1 //===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_ClangASTSource_h_
11 #define liblldb_ClangASTSource_h_
15 #include "clang/Basic/IdentifierTable.h"
16 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
17 #include "lldb/Symbol/ClangASTImporter.h"
18 #include "lldb/Symbol/CompilerType.h"
19 #include "lldb/Target/Target.h"
21 #include "llvm/ADT/SmallSet.h"
23 namespace lldb_private {
25 //----------------------------------------------------------------------
26 /// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
27 /// @brief Provider for named objects defined in the debug info for Clang
29 /// As Clang parses an expression, it may encounter names that are not
30 /// defined inside the expression, including variables, functions, and
31 /// types. Clang knows the name it is looking for, but nothing else.
32 /// The ExternalSemaSource class provides Decls (VarDecl, FunDecl, TypeDecl)
33 /// to Clang for these names, consulting the ClangExpressionDeclMap to do
34 /// the actual lookups.
35 //----------------------------------------------------------------------
36 class ClangASTSource :
37 public ClangExternalASTSourceCommon,
38 public ClangASTImporter::MapCompleter
41 //------------------------------------------------------------------
44 /// Initializes class variables.
46 /// @param[in] declMap
47 /// A reference to the LLDB object that handles entity lookup.
48 //------------------------------------------------------------------
49 ClangASTSource (const lldb::TargetSP &target) :
50 m_import_in_progress (false),
51 m_lookups_enabled (false),
54 m_active_lexical_decls (),
57 m_ast_importer_sp = m_target->GetClangASTImporter();
60 //------------------------------------------------------------------
62 //------------------------------------------------------------------
63 ~ClangASTSource() override;
65 //------------------------------------------------------------------
67 //------------------------------------------------------------------
68 clang::Decl *GetExternalDecl (uint32_t) override { return NULL; }
69 clang::Stmt *GetExternalDeclStmt (uint64_t) override { return NULL; }
70 clang::Selector GetExternalSelector (uint32_t) override { return clang::Selector(); }
71 uint32_t GetNumExternalSelectors () override { return 0; }
72 clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset) override
74 void MaterializeVisibleDecls (const clang::DeclContext *DC)
77 void InstallASTContext (clang::ASTContext *ast_context)
79 m_ast_context = ast_context;
80 m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
84 // APIs for ExternalASTSource
87 //------------------------------------------------------------------
88 /// Look up all Decls that match a particular name. Only handles
89 /// Identifiers and DeclContexts that are either NamespaceDecls or
90 /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
93 /// The work for this function is done by
94 /// void FindExternalVisibleDecls (NameSearchContext &);
97 /// The DeclContext to register the found Decls in.
100 /// The name to find entries for.
103 /// Whatever SetExternalVisibleDeclsForName returns.
104 //------------------------------------------------------------------
105 bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override;
107 //------------------------------------------------------------------
108 /// Enumerate all Decls in a given lexical context.
111 /// The DeclContext being searched.
113 /// @param[in] isKindWeWant
114 /// A callback function that returns true given the
115 /// DeclKinds of desired Decls, and false otherwise.
118 /// A vector that is filled in with matching Decls.
119 //------------------------------------------------------------------
120 void FindExternalLexicalDecls(
121 const clang::DeclContext *DC, llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
122 llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
124 //------------------------------------------------------------------
125 /// Specify the layout of the contents of a RecordDecl.
127 /// @param[in] Record
128 /// The record (in the parser's AST context) that needs to be
132 /// The total size of the record in bits.
134 /// @param[out] Alignment
135 /// The alignment of the record in bits.
137 /// @param[in] FieldOffsets
138 /// A map that must be populated with pairs of the record's
139 /// fields (in the parser's AST context) and their offsets
140 /// (measured in bits).
142 /// @param[in] BaseOffsets
143 /// A map that must be populated with pairs of the record's
144 /// C++ concrete base classes (in the parser's AST context,
145 /// and only if the record is a CXXRecordDecl and has base
146 /// classes) and their offsets (measured in bytes).
148 /// @param[in] VirtualBaseOffsets
149 /// A map that must be populated with pairs of the record's
150 /// C++ virtual base classes (in the parser's AST context,
151 /// and only if the record is a CXXRecordDecl and has base
152 /// classes) and their offsets (measured in bytes).
155 /// True <=> the layout is valid.
156 //-----------------------------------------------------------------
157 bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
158 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
159 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
160 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override;
162 //------------------------------------------------------------------
163 /// Complete a TagDecl.
166 /// The Decl to be completed in place.
167 //------------------------------------------------------------------
168 void CompleteType(clang::TagDecl *Tag) override;
170 //------------------------------------------------------------------
171 /// Complete an ObjCInterfaceDecl.
174 /// The Decl to be completed in place.
175 //------------------------------------------------------------------
176 void CompleteType(clang::ObjCInterfaceDecl *Class) override;
178 //------------------------------------------------------------------
179 /// Called on entering a translation unit. Tells Clang by calling
180 /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
181 /// that this object has something to say about undefined names.
183 /// @param[in] ASTConsumer
185 //------------------------------------------------------------------
186 void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
189 // APIs for NamespaceMapCompleter
192 //------------------------------------------------------------------
193 /// Look up the modules containing a given namespace and put the
194 /// appropriate entries in the namespace map.
196 /// @param[in] namespace_map
197 /// The map to be completed.
200 /// The name of the namespace to be found.
202 /// @param[in] parent_map
203 /// The map for the namespace's parent namespace, if there is
205 //------------------------------------------------------------------
206 void CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
207 ClangASTImporter::NamespaceMapSP &parent_map) const override;
213 clang::NamespaceDecl *
214 AddNamespace (NameSearchContext &context,
215 ClangASTImporter::NamespaceMapSP &namespace_decls);
217 //------------------------------------------------------------------
218 /// The worker function for FindExternalVisibleDeclsByName.
220 /// @param[in] context
221 /// The NameSearchContext to use when filing results.
222 //------------------------------------------------------------------
223 virtual void FindExternalVisibleDecls (NameSearchContext &context);
225 void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
226 bool GetImportInProgress () { return m_import_in_progress; }
228 void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
229 bool GetLookupsEnabled () { return m_lookups_enabled; }
231 //----------------------------------------------------------------------
232 /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
233 /// @brief Proxy for ClangASTSource
235 /// Clang AST contexts like to own their AST sources, so this is a
236 /// state-free proxy object.
237 //----------------------------------------------------------------------
238 class ClangASTSourceProxy : public ClangExternalASTSourceCommon
241 ClangASTSourceProxy (ClangASTSource &original) :
247 FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override
249 return m_original.FindExternalVisibleDeclsByName(DC, Name);
253 FindExternalLexicalDecls(const clang::DeclContext *DC,
254 llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
255 llvm::SmallVectorImpl<clang::Decl *> &Decls) override
257 return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
261 CompleteType(clang::TagDecl *Tag) override
263 return m_original.CompleteType(Tag);
267 CompleteType(clang::ObjCInterfaceDecl *Class) override
269 return m_original.CompleteType(Class);
273 layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
274 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
275 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
276 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override
278 return m_original.layoutRecordType(Record,
287 StartTranslationUnit(clang::ASTConsumer *Consumer) override
289 return m_original.StartTranslationUnit(Consumer);
293 GetMetadata(const void * object)
295 return m_original.GetMetadata(object);
299 SetMetadata(const void * object, ClangASTMetadata &metadata)
301 return m_original.SetMetadata(object, metadata);
305 HasMetadata(const void * object)
307 return m_original.HasMetadata(object);
310 ClangASTSource &m_original;
313 clang::ExternalASTSource *CreateProxy()
315 return new ClangASTSourceProxy(*this);
319 //------------------------------------------------------------------
320 /// Look for the complete version of an Objective-C interface, and
321 /// return it if found.
323 /// @param[in] interface_decl
324 /// An ObjCInterfaceDecl that may not be the complete one.
327 /// NULL if the complete interface couldn't be found;
328 /// the complete interface otherwise.
329 //------------------------------------------------------------------
330 clang::ObjCInterfaceDecl *
331 GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
333 //------------------------------------------------------------------
334 /// Find all entities matching a given name in a given module,
335 /// using a NameSearchContext to make Decls for them.
337 /// @param[in] context
338 /// The NameSearchContext that can construct Decls for this name.
340 /// @param[in] module
341 /// If non-NULL, the module to query.
343 /// @param[in] namespace_decl
344 /// If valid and module is non-NULL, the parent namespace.
346 /// @param[in] current_id
347 /// The ID for the current FindExternalVisibleDecls invocation,
348 /// for logging purposes.
351 /// True on success; false otherwise.
352 //------------------------------------------------------------------
354 FindExternalVisibleDecls (NameSearchContext &context,
355 lldb::ModuleSP module,
356 CompilerDeclContext &namespace_decl,
357 unsigned int current_id);
359 //------------------------------------------------------------------
360 /// Find all Objective-C methods matching a given selector.
362 /// @param[in] context
363 /// The NameSearchContext that can construct Decls for this name.
364 /// Its m_decl_name contains the selector and its m_decl_context
365 /// is the containing object.
366 //------------------------------------------------------------------
368 FindObjCMethodDecls (NameSearchContext &context);
370 //------------------------------------------------------------------
371 /// Find all Objective-C properties and ivars with a given name.
373 /// @param[in] context
374 /// The NameSearchContext that can construct Decls for this name.
375 /// Its m_decl_name contains the name and its m_decl_context
376 /// is the containing object.
377 //------------------------------------------------------------------
379 FindObjCPropertyAndIvarDecls (NameSearchContext &context);
381 //------------------------------------------------------------------
382 /// A wrapper for ClangASTContext::CopyType that sets a flag that
383 /// indicates that we should not respond to queries during import.
385 /// @param[in] dest_context
386 /// The target AST context, typically the parser's AST context.
388 /// @param[in] source_context
389 /// The source AST context, typically the AST context of whatever
390 /// symbol file the type was found in.
392 /// @param[in] src_type
396 /// The imported type.
397 //------------------------------------------------------------------
399 GuardedCopyType (const CompilerType &src_type);
401 friend struct NameSearchContext;
403 bool m_import_in_progress;
404 bool m_lookups_enabled;
406 const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
407 clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
408 lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
409 std::set<const clang::Decl *> m_active_lexical_decls;
410 std::set<const char *> m_active_lookups;
413 //----------------------------------------------------------------------
414 /// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
415 /// @brief Container for all objects relevant to a single name lookup
417 /// LLDB needs to create Decls for entities it finds. This class communicates
418 /// what name is being searched for and provides helper functions to construct
419 /// Decls given appropriate type information.
420 //----------------------------------------------------------------------
421 struct NameSearchContext {
422 ClangASTSource &m_ast_source; ///< The AST source making the request
423 llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed
424 ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules
425 const clang::DeclarationName &m_decl_name; ///< The name being looked for
426 const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into
427 llvm::SmallSet <CompilerType, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts
431 bool function_with_type_info : 1;
433 bool local_vars_nsp : 1;
437 //------------------------------------------------------------------
440 /// Initializes class variables.
442 /// @param[in] astSource
443 /// A reference to the AST source making a request.
446 /// A reference to a list into which new Decls will be placed. This
447 /// list is typically empty when the function is called.
450 /// The name being searched for (always an Identifier).
453 /// The DeclContext to register Decls in.
454 //------------------------------------------------------------------
455 NameSearchContext (ClangASTSource &astSource,
456 llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
457 clang::DeclarationName &name,
458 const clang::DeclContext *dc) :
459 m_ast_source(astSource),
464 memset(&m_found, 0, sizeof(m_found));
467 //------------------------------------------------------------------
468 /// Create a VarDecl with the name being searched for and the provided
469 /// type and register it in the right places.
472 /// The opaque QualType for the VarDecl being registered.
473 //------------------------------------------------------------------
474 clang::NamedDecl *AddVarDecl(const CompilerType &type);
476 //------------------------------------------------------------------
477 /// Create a FunDecl with the name being searched for and the provided
478 /// type and register it in the right places.
481 /// The opaque QualType for the FunDecl being registered.
483 /// @param[in] extern_c
484 /// If true, build an extern "C" linkage specification for this.
485 //------------------------------------------------------------------
486 clang::NamedDecl *AddFunDecl(const CompilerType &type,
487 bool extern_c = false);
489 //------------------------------------------------------------------
490 /// Create a FunDecl with the name being searched for and generic
491 /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
493 //------------------------------------------------------------------
494 clang::NamedDecl *AddGenericFunDecl();
496 //------------------------------------------------------------------
497 /// Create a TypeDecl with the name being searched for and the provided
498 /// type and register it in the right places.
500 /// @param[in] compiler_type
501 /// The opaque QualType for the TypeDecl being registered.
502 //------------------------------------------------------------------
503 clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
506 //------------------------------------------------------------------
507 /// Add Decls from the provided DeclContextLookupResult to the list
510 /// @param[in] result
511 /// The DeclContextLookupResult, usually returned as the result
512 /// of querying a DeclContext.
513 //------------------------------------------------------------------
514 void AddLookupResult (clang::DeclContextLookupResult result);
516 //------------------------------------------------------------------
517 /// Add a NamedDecl to the list of results.
520 /// The NamedDecl, usually returned as the result
521 /// of querying a DeclContext.
522 //------------------------------------------------------------------
523 void AddNamedDecl (clang::NamedDecl *decl);
526 } // namespace lldb_private
528 #endif // liblldb_ClangASTSource_h_