xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
1 //===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef liblldb_ClangASTSource_h_
10 #define liblldb_ClangASTSource_h_
11 
12 #include <set>
13 
14 #include "lldb/Symbol/ClangASTImporter.h"
15 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
16 #include "lldb/Symbol/CompilerType.h"
17 #include "lldb/Target/Target.h"
18 #include "clang/AST/ExternalASTMerger.h"
19 #include "clang/Basic/IdentifierTable.h"
20 
21 #include "llvm/ADT/SmallSet.h"
22 
23 namespace lldb_private {
24 
25 /// \class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
26 /// Provider for named objects defined in the debug info for Clang
27 ///
28 /// As Clang parses an expression, it may encounter names that are not defined
29 /// inside the expression, including variables, functions, and types.  Clang
30 /// knows the name it is looking for, but nothing else. The ExternalSemaSource
31 /// class provides Decls (VarDecl, FunDecl, TypeDecl) to Clang for these
32 /// names, consulting the ClangExpressionDeclMap to do the actual lookups.
33 class ClangASTSource : public ClangExternalASTSourceCommon,
34                        public ClangASTImporter::MapCompleter {
35 public:
36   /// Constructor
37   ///
38   /// Initializes class variables.
39   ///
40   /// \param[in] target
41   ///     A reference to the target containing debug information to use.
42   ClangASTSource(const lldb::TargetSP &target);
43 
44   /// Destructor
45   ~ClangASTSource() override;
46 
47   /// Interface stubs.
48   clang::Decl *GetExternalDecl(uint32_t) override { return nullptr; }
49   clang::Stmt *GetExternalDeclStmt(uint64_t) override { return nullptr; }
50   clang::Selector GetExternalSelector(uint32_t) override {
51     return clang::Selector();
52   }
53   uint32_t GetNumExternalSelectors() override { return 0; }
54   clang::CXXBaseSpecifier *
55   GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
56     return nullptr;
57   }
58   void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
59 
60   void InstallASTContext(clang::ASTContext &ast_context,
61                          clang::FileManager &file_manager,
62                          bool is_shared_context = false);
63 
64   //
65   // APIs for ExternalASTSource
66   //
67 
68   /// Look up all Decls that match a particular name.  Only handles
69   /// Identifiers and DeclContexts that are either NamespaceDecls or
70   /// TranslationUnitDecls.  Calls SetExternalVisibleDeclsForName with the
71   /// result.
72   ///
73   /// The work for this function is done by
74   /// void FindExternalVisibleDecls (NameSearchContext &);
75   ///
76   /// \param[in] DC
77   ///     The DeclContext to register the found Decls in.
78   ///
79   /// \param[in] Name
80   ///     The name to find entries for.
81   ///
82   /// \return
83   ///     Whatever SetExternalVisibleDeclsForName returns.
84   bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
85                                       clang::DeclarationName Name) override;
86 
87   /// Enumerate all Decls in a given lexical context.
88   ///
89   /// \param[in] DC
90   ///     The DeclContext being searched.
91   ///
92   /// \param[in] isKindWeWant
93   ///     A callback function that returns true given the
94   ///     DeclKinds of desired Decls, and false otherwise.
95   ///
96   /// \param[in] Decls
97   ///     A vector that is filled in with matching Decls.
98   void FindExternalLexicalDecls(
99       const clang::DeclContext *DC,
100       llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
101       llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
102 
103   /// Specify the layout of the contents of a RecordDecl.
104   ///
105   /// \param[in] Record
106   ///     The record (in the parser's AST context) that needs to be
107   ///     laid out.
108   ///
109   /// \param[out] Size
110   ///     The total size of the record in bits.
111   ///
112   /// \param[out] Alignment
113   ///     The alignment of the record in bits.
114   ///
115   /// \param[in] FieldOffsets
116   ///     A map that must be populated with pairs of the record's
117   ///     fields (in the parser's AST context) and their offsets
118   ///     (measured in bits).
119   ///
120   /// \param[in] BaseOffsets
121   ///     A map that must be populated with pairs of the record's
122   ///     C++ concrete base classes (in the parser's AST context,
123   ///     and only if the record is a CXXRecordDecl and has base
124   ///     classes) and their offsets (measured in bytes).
125   ///
126   /// \param[in] VirtualBaseOffsets
127   ///     A map that must be populated with pairs of the record's
128   ///     C++ virtual base classes (in the parser's AST context,
129   ///     and only if the record is a CXXRecordDecl and has base
130   ///     classes) and their offsets (measured in bytes).
131   ///
132   /// \return
133   ///     True <=> the layout is valid.
134   bool layoutRecordType(
135       const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
136       llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
137       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
138           &BaseOffsets,
139       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
140           &VirtualBaseOffsets) override;
141 
142   /// Complete a TagDecl.
143   ///
144   /// \param[in] Tag
145   ///     The Decl to be completed in place.
146   void CompleteType(clang::TagDecl *Tag) override;
147 
148   /// Complete an ObjCInterfaceDecl.
149   ///
150   /// \param[in] Class
151   ///     The Decl to be completed in place.
152   void CompleteType(clang::ObjCInterfaceDecl *Class) override;
153 
154   /// Called on entering a translation unit.  Tells Clang by calling
155   /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that
156   /// this object has something to say about undefined names.
157   ///
158   /// \param[in] ASTConsumer
159   ///     Unused.
160   void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
161 
162   //
163   // APIs for NamespaceMapCompleter
164   //
165 
166   /// Look up the modules containing a given namespace and put the appropriate
167   /// entries in the namespace map.
168   ///
169   /// \param[in] namespace_map
170   ///     The map to be completed.
171   ///
172   /// \param[in] name
173   ///     The name of the namespace to be found.
174   ///
175   /// \param[in] parent_map
176   ///     The map for the namespace's parent namespace, if there is
177   ///     one.
178   void CompleteNamespaceMap(
179       ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
180       ClangASTImporter::NamespaceMapSP &parent_map) const override;
181 
182   //
183   // Helper APIs
184   //
185 
186   clang::NamespaceDecl *
187   AddNamespace(NameSearchContext &context,
188                ClangASTImporter::NamespaceMapSP &namespace_decls);
189 
190   /// The worker function for FindExternalVisibleDeclsByName.
191   ///
192   /// \param[in] context
193   ///     The NameSearchContext to use when filing results.
194   virtual void FindExternalVisibleDecls(NameSearchContext &context);
195 
196   clang::Sema *getSema();
197 
198   void SetImportInProgress(bool import_in_progress) {
199     m_import_in_progress = import_in_progress;
200   }
201   bool GetImportInProgress() { return m_import_in_progress; }
202 
203   void SetLookupsEnabled(bool lookups_enabled) {
204     m_lookups_enabled = lookups_enabled;
205   }
206   bool GetLookupsEnabled() { return m_lookups_enabled; }
207 
208   /// \class ClangASTSourceProxy ClangASTSource.h
209   /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
210   ///
211   /// Clang AST contexts like to own their AST sources, so this is a state-
212   /// free proxy object.
213   class ClangASTSourceProxy : public ClangExternalASTSourceCommon {
214   public:
215     ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}
216 
217     bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
218                                         clang::DeclarationName Name) override {
219       return m_original.FindExternalVisibleDeclsByName(DC, Name);
220     }
221 
222     void FindExternalLexicalDecls(
223         const clang::DeclContext *DC,
224         llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
225         llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
226       return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
227     }
228 
229     void CompleteType(clang::TagDecl *Tag) override {
230       return m_original.CompleteType(Tag);
231     }
232 
233     void CompleteType(clang::ObjCInterfaceDecl *Class) override {
234       return m_original.CompleteType(Class);
235     }
236 
237     bool layoutRecordType(
238         const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
239         llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
240         llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
241             &BaseOffsets,
242         llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
243             &VirtualBaseOffsets) override {
244       return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
245                                          BaseOffsets, VirtualBaseOffsets);
246     }
247 
248     void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
249       return m_original.StartTranslationUnit(Consumer);
250     }
251 
252     ClangASTMetadata *GetMetadata(const void *object) {
253       return m_original.GetMetadata(object);
254     }
255 
256     void SetMetadata(const void *object, ClangASTMetadata &metadata) {
257       return m_original.SetMetadata(object, metadata);
258     }
259 
260     bool HasMetadata(const void *object) {
261       return m_original.HasMetadata(object);
262     }
263 
264   private:
265     ClangASTSource &m_original;
266   };
267 
268   clang::ExternalASTSource *CreateProxy() {
269     return new ClangASTSourceProxy(*this);
270   }
271 
272 protected:
273   /// Look for the complete version of an Objective-C interface, and return it
274   /// if found.
275   ///
276   /// \param[in] interface_decl
277   ///     An ObjCInterfaceDecl that may not be the complete one.
278   ///
279   /// \return
280   ///     NULL if the complete interface couldn't be found;
281   ///     the complete interface otherwise.
282   clang::ObjCInterfaceDecl *
283   GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
284 
285   /// Find all entities matching a given name in a given module, using a
286   /// NameSearchContext to make Decls for them.
287   ///
288   /// \param[in] context
289   ///     The NameSearchContext that can construct Decls for this name.
290   ///
291   /// \param[in] module
292   ///     If non-NULL, the module to query.
293   ///
294   /// \param[in] namespace_decl
295   ///     If valid and module is non-NULL, the parent namespace.
296   ///
297   /// \param[in] current_id
298   ///     The ID for the current FindExternalVisibleDecls invocation,
299   ///     for logging purposes.
300   void FindExternalVisibleDecls(NameSearchContext &context,
301                                 lldb::ModuleSP module,
302                                 CompilerDeclContext &namespace_decl,
303                                 unsigned int current_id);
304 
305   /// Find all Objective-C methods matching a given selector.
306   ///
307   /// \param[in] context
308   ///     The NameSearchContext that can construct Decls for this name.
309   ///     Its m_decl_name contains the selector and its m_decl_context
310   ///     is the containing object.
311   void FindObjCMethodDecls(NameSearchContext &context);
312 
313   /// Find all Objective-C properties and ivars with a given name.
314   ///
315   /// \param[in] context
316   ///     The NameSearchContext that can construct Decls for this name.
317   ///     Its m_decl_name contains the name and its m_decl_context
318   ///     is the containing object.
319   void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
320 
321   /// A wrapper for ClangASTContext::CopyType that sets a flag that
322   /// indicates that we should not respond to queries during import.
323   ///
324   /// \param[in] dest_context
325   ///     The target AST context, typically the parser's AST context.
326   ///
327   /// \param[in] source_context
328   ///     The source AST context, typically the AST context of whatever
329   ///     symbol file the type was found in.
330   ///
331   /// \param[in] src_type
332   ///     The source type.
333   ///
334   /// \return
335   ///     The imported type.
336   CompilerType GuardedCopyType(const CompilerType &src_type);
337 
338 public:
339   /// Returns true if a name should be ignored by name lookup.
340   ///
341   /// \param[in] name
342   ///     The name to be considered.
343   ///
344   /// \param[in] ignore_all_dollar_nmmes
345   ///     True if $-names of all sorts should be ignored.
346   ///
347   /// \return
348   ///     True if the name is one of a class of names that are ignored by
349   ///     global lookup for performance reasons.
350   bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
351 
352 public:
353   /// Copies a single Decl into the parser's AST context.
354   ///
355   /// \param[in] src_decl
356   ///     The Decl to copy.
357   ///
358   /// \return
359   ///     A copy of the Decl in m_ast_context, or NULL if the copy failed.
360   clang::Decl *CopyDecl(clang::Decl *src_decl);
361 
362   /// Copies a single Type to the target of the given ExternalASTMerger.
363   ///
364   /// \param[in] src_context
365   ///     The ASTContext containing the type.
366   ///
367   /// \param[in] merger
368   ///     The merger to use.  This isn't just *m_merger_up because it might be
369   ///     the persistent AST context's merger.
370   ///
371   /// \param[in] type
372   ///     The type to copy.
373   ///
374   /// \return
375   ///     A copy of the Type in the merger's target context.
376 	clang::QualType CopyTypeWithMerger(clang::ASTContext &src_context,
377                                      clang::ExternalASTMerger &merger,
378                                      clang::QualType type);
379 
380   /// Determined the origin of a single Decl, if it can be found.
381   ///
382   /// \param[in] decl
383   ///     The Decl whose origin is to be found.
384   ///
385   /// \param[out] original_decl
386   ///     A pointer whose target is filled in with the original Decl.
387   ///
388   /// \param[in] original_ctx
389   ///     A pointer whose target is filled in with the original's ASTContext.
390   ///
391   /// \return
392   ///     True if lookup succeeded; false otherwise.
393   bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl,
394                          clang::ASTContext **original_ctx);
395 
396   /// Returns m_merger_up.  Only call this if the target is configured to use
397   /// modern lookup,
398 	clang::ExternalASTMerger &GetMergerUnchecked();
399 
400   /// Returns true if there is a merger.  This only occurs if the target is
401   /// using modern lookup.
402   bool HasMerger() { return (bool)m_merger_up; }
403 
404 protected:
405   bool FindObjCMethodDeclsWithOrigin(
406       unsigned int current_id, NameSearchContext &context,
407       clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
408 
409   friend struct NameSearchContext;
410 
411   bool m_import_in_progress;
412   bool m_lookups_enabled;
413 
414   const lldb::TargetSP
415       m_target; ///< The target to use in finding variables and types.
416   clang::ASTContext
417       *m_ast_context; ///< The AST context requests are coming in for.
418   clang::FileManager
419       *m_file_manager; ///< The file manager paired with the AST context.
420   lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
421   std::unique_ptr<clang::ExternalASTMerger> m_merger_up;
422       ///< The ExternalASTMerger for this parse.
423   std::set<const clang::Decl *> m_active_lexical_decls;
424   std::set<const char *> m_active_lookups;
425 };
426 
427 /// \class NameSearchContext ClangASTSource.h
428 /// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
429 /// single name lookup
430 ///
431 /// LLDB needs to create Decls for entities it finds.  This class communicates
432 /// what name is being searched for and provides helper functions to construct
433 /// Decls given appropriate type information.
434 struct NameSearchContext {
435   ClangASTSource &m_ast_source; ///< The AST source making the request
436   llvm::SmallVectorImpl<clang::NamedDecl *>
437       &m_decls; ///< The list of declarations already constructed
438   ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all
439                                                     ///namespaces found for this
440                                                     ///request back to their
441                                                     ///modules
442   const clang::DeclarationName &m_decl_name; ///< The name being looked for
443   const clang::DeclContext
444       *m_decl_context; ///< The DeclContext to put declarations into
445   llvm::SmallSet<CompilerType, 5> m_function_types; ///< All the types of
446                                                     ///functions that have been
447                                                     ///reported, so we don't
448                                                     ///report conflicts
449 
450   struct {
451     bool variable : 1;
452     bool function_with_type_info : 1;
453     bool function : 1;
454     bool local_vars_nsp : 1;
455     bool type : 1;
456   } m_found;
457 
458   /// Constructor
459   ///
460   /// Initializes class variables.
461   ///
462   /// \param[in] astSource
463   ///     A reference to the AST source making a request.
464   ///
465   /// \param[in] decls
466   ///     A reference to a list into which new Decls will be placed.  This
467   ///     list is typically empty when the function is called.
468   ///
469   /// \param[in] name
470   ///     The name being searched for (always an Identifier).
471   ///
472   /// \param[in] dc
473   ///     The DeclContext to register Decls in.
474   NameSearchContext(ClangASTSource &astSource,
475                     llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
476                     clang::DeclarationName &name, const clang::DeclContext *dc)
477       : m_ast_source(astSource), m_decls(decls), m_decl_name(name),
478         m_decl_context(dc) {
479     memset(&m_found, 0, sizeof(m_found));
480   }
481 
482   /// Create a VarDecl with the name being searched for and the provided type
483   /// and register it in the right places.
484   ///
485   /// \param[in] type
486   ///     The opaque QualType for the VarDecl being registered.
487   clang::NamedDecl *AddVarDecl(const CompilerType &type);
488 
489   /// Create a FunDecl with the name being searched for and the provided type
490   /// and register it in the right places.
491   ///
492   /// \param[in] type
493   ///     The opaque QualType for the FunDecl being registered.
494   ///
495   /// \param[in] extern_c
496   ///     If true, build an extern "C" linkage specification for this.
497   clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
498 
499   /// Create a FunDecl with the name being searched for and generic type (i.e.
500   /// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
501   clang::NamedDecl *AddGenericFunDecl();
502 
503   /// Create a TypeDecl with the name being searched for and the provided type
504   /// and register it in the right places.
505   ///
506   /// \param[in] compiler_type
507   ///     The opaque QualType for the TypeDecl being registered.
508   clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
509 
510   /// Add Decls from the provided DeclContextLookupResult to the list of
511   /// results.
512   ///
513   /// \param[in] result
514   ///     The DeclContextLookupResult, usually returned as the result
515   ///     of querying a DeclContext.
516   void AddLookupResult(clang::DeclContextLookupResult result);
517 
518   /// Add a NamedDecl to the list of results.
519   ///
520   /// \param[in] decl
521   ///     The NamedDecl, usually returned as the result
522   ///     of querying a DeclContext.
523   void AddNamedDecl(clang::NamedDecl *decl);
524 };
525 
526 } // namespace lldb_private
527 
528 #endif // liblldb_ClangASTSource_h_
529