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 "lldb/Symbol/ClangASTImporter.h"
16 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
17 #include "lldb/Symbol/CompilerType.h"
18 #include "lldb/Target/Target.h"
19 #include "clang/Basic/IdentifierTable.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 : public ClangExternalASTSourceCommon,
37 public ClangASTImporter::MapCompleter {
39 //------------------------------------------------------------------
42 /// Initializes class variables.
44 /// @param[in] declMap
45 /// A reference to the LLDB object that handles entity lookup.
46 //------------------------------------------------------------------
47 ClangASTSource(const lldb::TargetSP &target)
48 : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
49 m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
50 m_ast_importer_sp = m_target->GetClangASTImporter();
53 //------------------------------------------------------------------
55 //------------------------------------------------------------------
56 ~ClangASTSource() override;
58 //------------------------------------------------------------------
60 //------------------------------------------------------------------
61 clang::Decl *GetExternalDecl(uint32_t) override { return NULL; }
62 clang::Stmt *GetExternalDeclStmt(uint64_t) override { return NULL; }
63 clang::Selector GetExternalSelector(uint32_t) override {
64 return clang::Selector();
66 uint32_t GetNumExternalSelectors() override { return 0; }
67 clang::CXXBaseSpecifier *
68 GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
71 void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
73 void InstallASTContext(clang::ASTContext *ast_context) {
74 m_ast_context = ast_context;
75 m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
79 // APIs for ExternalASTSource
82 //------------------------------------------------------------------
83 /// Look up all Decls that match a particular name. Only handles
84 /// Identifiers and DeclContexts that are either NamespaceDecls or
85 /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
88 /// The work for this function is done by
89 /// void FindExternalVisibleDecls (NameSearchContext &);
92 /// The DeclContext to register the found Decls in.
95 /// The name to find entries for.
98 /// Whatever SetExternalVisibleDeclsForName returns.
99 //------------------------------------------------------------------
100 bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
101 clang::DeclarationName Name) override;
103 //------------------------------------------------------------------
104 /// Enumerate all Decls in a given lexical context.
107 /// The DeclContext being searched.
109 /// @param[in] isKindWeWant
110 /// A callback function that returns true given the
111 /// DeclKinds of desired Decls, and false otherwise.
114 /// A vector that is filled in with matching Decls.
115 //------------------------------------------------------------------
116 void FindExternalLexicalDecls(
117 const clang::DeclContext *DC,
118 llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
119 llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
121 //------------------------------------------------------------------
122 /// Specify the layout of the contents of a RecordDecl.
124 /// @param[in] Record
125 /// The record (in the parser's AST context) that needs to be
129 /// The total size of the record in bits.
131 /// @param[out] Alignment
132 /// The alignment of the record in bits.
134 /// @param[in] FieldOffsets
135 /// A map that must be populated with pairs of the record's
136 /// fields (in the parser's AST context) and their offsets
137 /// (measured in bits).
139 /// @param[in] BaseOffsets
140 /// A map that must be populated with pairs of the record's
141 /// C++ concrete base classes (in the parser's AST context,
142 /// and only if the record is a CXXRecordDecl and has base
143 /// classes) and their offsets (measured in bytes).
145 /// @param[in] VirtualBaseOffsets
146 /// A map that must be populated with pairs of the record's
147 /// C++ virtual base classes (in the parser's AST context,
148 /// and only if the record is a CXXRecordDecl and has base
149 /// classes) and their offsets (measured in bytes).
152 /// True <=> the layout is valid.
153 //-----------------------------------------------------------------
154 bool layoutRecordType(
155 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
156 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
157 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
159 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
160 &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(
207 ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
208 ClangASTImporter::NamespaceMapSP &parent_map) const override;
214 clang::NamespaceDecl *
215 AddNamespace(NameSearchContext &context,
216 ClangASTImporter::NamespaceMapSP &namespace_decls);
218 //------------------------------------------------------------------
219 /// The worker function for FindExternalVisibleDeclsByName.
221 /// @param[in] context
222 /// The NameSearchContext to use when filing results.
223 //------------------------------------------------------------------
224 virtual void FindExternalVisibleDecls(NameSearchContext &context);
226 void SetImportInProgress(bool import_in_progress) {
227 m_import_in_progress = import_in_progress;
229 bool GetImportInProgress() { return m_import_in_progress; }
231 void SetLookupsEnabled(bool lookups_enabled) {
232 m_lookups_enabled = lookups_enabled;
234 bool GetLookupsEnabled() { return m_lookups_enabled; }
236 //----------------------------------------------------------------------
237 /// @class ClangASTSourceProxy ClangASTSource.h
238 /// "lldb/Expression/ClangASTSource.h"
239 /// @brief Proxy for ClangASTSource
241 /// Clang AST contexts like to own their AST sources, so this is a
242 /// state-free proxy object.
243 //----------------------------------------------------------------------
244 class ClangASTSourceProxy : public ClangExternalASTSourceCommon {
246 ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}
248 bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
249 clang::DeclarationName Name) override {
250 return m_original.FindExternalVisibleDeclsByName(DC, Name);
253 void FindExternalLexicalDecls(
254 const clang::DeclContext *DC,
255 llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
256 llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
257 return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
260 void CompleteType(clang::TagDecl *Tag) override {
261 return m_original.CompleteType(Tag);
264 void CompleteType(clang::ObjCInterfaceDecl *Class) override {
265 return m_original.CompleteType(Class);
268 bool layoutRecordType(
269 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
270 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
271 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
273 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
274 &VirtualBaseOffsets) override {
275 return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
276 BaseOffsets, VirtualBaseOffsets);
279 void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
280 return m_original.StartTranslationUnit(Consumer);
283 ClangASTMetadata *GetMetadata(const void *object) {
284 return m_original.GetMetadata(object);
287 void SetMetadata(const void *object, ClangASTMetadata &metadata) {
288 return m_original.SetMetadata(object, metadata);
291 bool HasMetadata(const void *object) {
292 return m_original.HasMetadata(object);
296 ClangASTSource &m_original;
299 clang::ExternalASTSource *CreateProxy() {
300 return new ClangASTSourceProxy(*this);
304 //------------------------------------------------------------------
305 /// Look for the complete version of an Objective-C interface, and
306 /// return it if found.
308 /// @param[in] interface_decl
309 /// An ObjCInterfaceDecl that may not be the complete one.
312 /// NULL if the complete interface couldn't be found;
313 /// the complete interface otherwise.
314 //------------------------------------------------------------------
315 clang::ObjCInterfaceDecl *
316 GetCompleteObjCInterface(clang::ObjCInterfaceDecl *interface_decl);
318 //------------------------------------------------------------------
319 /// Find all entities matching a given name in a given module,
320 /// using a NameSearchContext to make Decls for them.
322 /// @param[in] context
323 /// The NameSearchContext that can construct Decls for this name.
325 /// @param[in] module
326 /// If non-NULL, the module to query.
328 /// @param[in] namespace_decl
329 /// If valid and module is non-NULL, the parent namespace.
331 /// @param[in] current_id
332 /// The ID for the current FindExternalVisibleDecls invocation,
333 /// for logging purposes.
334 //------------------------------------------------------------------
335 void FindExternalVisibleDecls(NameSearchContext &context,
336 lldb::ModuleSP module,
337 CompilerDeclContext &namespace_decl,
338 unsigned int current_id);
340 //------------------------------------------------------------------
341 /// Find all Objective-C methods matching a given selector.
343 /// @param[in] context
344 /// The NameSearchContext that can construct Decls for this name.
345 /// Its m_decl_name contains the selector and its m_decl_context
346 /// is the containing object.
347 //------------------------------------------------------------------
348 void FindObjCMethodDecls(NameSearchContext &context);
350 //------------------------------------------------------------------
351 /// Find all Objective-C properties and ivars with a given name.
353 /// @param[in] context
354 /// The NameSearchContext that can construct Decls for this name.
355 /// Its m_decl_name contains the name and its m_decl_context
356 /// is the containing object.
357 //------------------------------------------------------------------
358 void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
360 //------------------------------------------------------------------
361 /// A wrapper for ClangASTContext::CopyType that sets a flag that
362 /// indicates that we should not respond to queries during import.
364 /// @param[in] dest_context
365 /// The target AST context, typically the parser's AST context.
367 /// @param[in] source_context
368 /// The source AST context, typically the AST context of whatever
369 /// symbol file the type was found in.
371 /// @param[in] src_type
375 /// The imported type.
376 //------------------------------------------------------------------
377 CompilerType GuardedCopyType(const CompilerType &src_type);
379 friend struct NameSearchContext;
381 bool m_import_in_progress;
382 bool m_lookups_enabled;
385 m_target; ///< The target to use in finding variables and types.
387 *m_ast_context; ///< The AST context requests are coming in for.
388 lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
389 std::set<const clang::Decl *> m_active_lexical_decls;
390 std::set<const char *> m_active_lookups;
393 //----------------------------------------------------------------------
394 /// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
395 /// @brief Container for all objects relevant to a single name lookup
397 /// LLDB needs to create Decls for entities it finds. This class communicates
398 /// what name is being searched for and provides helper functions to construct
399 /// Decls given appropriate type information.
400 //----------------------------------------------------------------------
401 struct NameSearchContext {
402 ClangASTSource &m_ast_source; ///< The AST source making the request
403 llvm::SmallVectorImpl<clang::NamedDecl *>
404 &m_decls; ///< The list of declarations already constructed
405 ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all
406 ///namespaces found for this
407 ///request back to their
409 const clang::DeclarationName &m_decl_name; ///< The name being looked for
410 const clang::DeclContext
411 *m_decl_context; ///< The DeclContext to put declarations into
412 llvm::SmallSet<CompilerType, 5> m_function_types; ///< All the types of
413 ///functions that have been
414 ///reported, so we don't
419 bool function_with_type_info : 1;
421 bool local_vars_nsp : 1;
425 //------------------------------------------------------------------
428 /// Initializes class variables.
430 /// @param[in] astSource
431 /// A reference to the AST source making a request.
434 /// A reference to a list into which new Decls will be placed. This
435 /// list is typically empty when the function is called.
438 /// The name being searched for (always an Identifier).
441 /// The DeclContext to register Decls in.
442 //------------------------------------------------------------------
443 NameSearchContext(ClangASTSource &astSource,
444 llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
445 clang::DeclarationName &name, const clang::DeclContext *dc)
446 : m_ast_source(astSource), m_decls(decls), m_decl_name(name),
448 memset(&m_found, 0, sizeof(m_found));
451 //------------------------------------------------------------------
452 /// Create a VarDecl with the name being searched for and the provided
453 /// type and register it in the right places.
456 /// The opaque QualType for the VarDecl being registered.
457 //------------------------------------------------------------------
458 clang::NamedDecl *AddVarDecl(const CompilerType &type);
460 //------------------------------------------------------------------
461 /// Create a FunDecl with the name being searched for and the provided
462 /// type and register it in the right places.
465 /// The opaque QualType for the FunDecl being registered.
467 /// @param[in] extern_c
468 /// If true, build an extern "C" linkage specification for this.
469 //------------------------------------------------------------------
470 clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
472 //------------------------------------------------------------------
473 /// Create a FunDecl with the name being searched for and generic
474 /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
476 //------------------------------------------------------------------
477 clang::NamedDecl *AddGenericFunDecl();
479 //------------------------------------------------------------------
480 /// Create a TypeDecl with the name being searched for and the provided
481 /// type and register it in the right places.
483 /// @param[in] compiler_type
484 /// The opaque QualType for the TypeDecl being registered.
485 //------------------------------------------------------------------
486 clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
488 //------------------------------------------------------------------
489 /// Add Decls from the provided DeclContextLookupResult to the list
492 /// @param[in] result
493 /// The DeclContextLookupResult, usually returned as the result
494 /// of querying a DeclContext.
495 //------------------------------------------------------------------
496 void AddLookupResult(clang::DeclContextLookupResult result);
498 //------------------------------------------------------------------
499 /// Add a NamedDecl to the list of results.
502 /// The NamedDecl, usually returned as the result
503 /// of querying a DeclContext.
504 //------------------------------------------------------------------
505 void AddNamedDecl(clang::NamedDecl *decl);
508 } // namespace lldb_private
510 #endif // liblldb_ClangASTSource_h_