/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
Line | Count | Source (jump to first uncovered line) |
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 LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H |
10 | | #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H |
11 | | |
12 | | #include <set> |
13 | | |
14 | | #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" |
15 | | #include "Plugins/ExpressionParser/Clang/NameSearchContext.h" |
16 | | #include "lldb/Symbol/CompilerType.h" |
17 | | #include "lldb/Target/Target.h" |
18 | | #include "clang/AST/ExternalASTSource.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 clang::ExternalASTSource, |
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 | | /// |
43 | | /// \param[in] importer |
44 | | /// The ClangASTImporter to use. |
45 | | ClangASTSource(const lldb::TargetSP &target, |
46 | | const std::shared_ptr<ClangASTImporter> &importer); |
47 | | |
48 | | /// Destructor |
49 | | ~ClangASTSource() override; |
50 | | |
51 | | /// Interface stubs. |
52 | 0 | clang::Decl *GetExternalDecl(uint32_t) override { return nullptr; } |
53 | 0 | clang::Stmt *GetExternalDeclStmt(uint64_t) override { return nullptr; } |
54 | 0 | clang::Selector GetExternalSelector(uint32_t) override { |
55 | 0 | return clang::Selector(); |
56 | 0 | } |
57 | 0 | uint32_t GetNumExternalSelectors() override { return 0; } |
58 | | clang::CXXBaseSpecifier * |
59 | 0 | GetExternalCXXBaseSpecifiers(uint64_t Offset) override { |
60 | 0 | return nullptr; |
61 | 0 | } |
62 | 0 | void MaterializeVisibleDecls(const clang::DeclContext *DC) {} |
63 | | |
64 | | void InstallASTContext(TypeSystemClang &ast_context); |
65 | | |
66 | | // |
67 | | // APIs for ExternalASTSource |
68 | | // |
69 | | |
70 | | /// Look up all Decls that match a particular name. Only handles |
71 | | /// Identifiers and DeclContexts that are either NamespaceDecls or |
72 | | /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with the |
73 | | /// result. |
74 | | /// |
75 | | /// The work for this function is done by |
76 | | /// void FindExternalVisibleDecls (NameSearchContext &); |
77 | | /// |
78 | | /// \param[in] DC |
79 | | /// The DeclContext to register the found Decls in. |
80 | | /// |
81 | | /// \param[in] Name |
82 | | /// The name to find entries for. |
83 | | /// |
84 | | /// \return |
85 | | /// Whatever SetExternalVisibleDeclsForName returns. |
86 | | bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, |
87 | | clang::DeclarationName Name) override; |
88 | | |
89 | | /// Enumerate all Decls in a given lexical context. |
90 | | /// |
91 | | /// \param[in] DC |
92 | | /// The DeclContext being searched. |
93 | | /// |
94 | | /// \param[in] IsKindWeWant |
95 | | /// A callback function that returns true given the |
96 | | /// DeclKinds of desired Decls, and false otherwise. |
97 | | /// |
98 | | /// \param[in] Decls |
99 | | /// A vector that is filled in with matching Decls. |
100 | | void FindExternalLexicalDecls( |
101 | | const clang::DeclContext *DC, |
102 | | llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, |
103 | | llvm::SmallVectorImpl<clang::Decl *> &Decls) override; |
104 | | |
105 | | /// Specify the layout of the contents of a RecordDecl. |
106 | | /// |
107 | | /// \param[in] Record |
108 | | /// The record (in the parser's AST context) that needs to be |
109 | | /// laid out. |
110 | | /// |
111 | | /// \param[out] Size |
112 | | /// The total size of the record in bits. |
113 | | /// |
114 | | /// \param[out] Alignment |
115 | | /// The alignment of the record in bits. |
116 | | /// |
117 | | /// \param[in] FieldOffsets |
118 | | /// A map that must be populated with pairs of the record's |
119 | | /// fields (in the parser's AST context) and their offsets |
120 | | /// (measured in bits). |
121 | | /// |
122 | | /// \param[in] BaseOffsets |
123 | | /// A map that must be populated with pairs of the record's |
124 | | /// C++ concrete base classes (in the parser's AST context, |
125 | | /// and only if the record is a CXXRecordDecl and has base |
126 | | /// classes) and their offsets (measured in bytes). |
127 | | /// |
128 | | /// \param[in] VirtualBaseOffsets |
129 | | /// A map that must be populated with pairs of the record's |
130 | | /// C++ virtual base classes (in the parser's AST context, |
131 | | /// and only if the record is a CXXRecordDecl and has base |
132 | | /// classes) and their offsets (measured in bytes). |
133 | | /// |
134 | | /// \return |
135 | | /// True <=> the layout is valid. |
136 | | bool layoutRecordType( |
137 | | const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, |
138 | | llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, |
139 | | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
140 | | &BaseOffsets, |
141 | | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
142 | | &VirtualBaseOffsets) override; |
143 | | |
144 | | /// Complete a TagDecl. |
145 | | /// |
146 | | /// \param[in] Tag |
147 | | /// The Decl to be completed in place. |
148 | | void CompleteType(clang::TagDecl *Tag) override; |
149 | | |
150 | | /// Complete an ObjCInterfaceDecl. |
151 | | /// |
152 | | /// \param[in] Class |
153 | | /// The Decl to be completed in place. |
154 | | void CompleteType(clang::ObjCInterfaceDecl *Class) override; |
155 | | |
156 | | /// Called on entering a translation unit. Tells Clang by calling |
157 | | /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that |
158 | | /// this object has something to say about undefined names. |
159 | | /// |
160 | | /// \param[in] Consumer |
161 | | /// Unused. |
162 | | void StartTranslationUnit(clang::ASTConsumer *Consumer) override; |
163 | | |
164 | | // |
165 | | // APIs for NamespaceMapCompleter |
166 | | // |
167 | | |
168 | | /// Look up the modules containing a given namespace and put the appropriate |
169 | | /// entries in the namespace map. |
170 | | /// |
171 | | /// \param[in] namespace_map |
172 | | /// The map to be completed. |
173 | | /// |
174 | | /// \param[in] name |
175 | | /// The name of the namespace to be found. |
176 | | /// |
177 | | /// \param[in] parent_map |
178 | | /// The map for the namespace's parent namespace, if there is |
179 | | /// one. |
180 | | void CompleteNamespaceMap( |
181 | | ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name, |
182 | | ClangASTImporter::NamespaceMapSP &parent_map) const override; |
183 | | |
184 | | // |
185 | | // Helper APIs |
186 | | // |
187 | | |
188 | | clang::NamespaceDecl * |
189 | | AddNamespace(NameSearchContext &context, |
190 | | ClangASTImporter::NamespaceMapSP &namespace_decls); |
191 | | |
192 | | /// The worker function for FindExternalVisibleDeclsByName. |
193 | | /// |
194 | | /// \param[in] context |
195 | | /// The NameSearchContext to use when filing results. |
196 | | virtual void FindExternalVisibleDecls(NameSearchContext &context); |
197 | | |
198 | | clang::Sema *getSema(); |
199 | | |
200 | 8.01k | void SetLookupsEnabled(bool lookups_enabled) { |
201 | 8.01k | m_lookups_enabled = lookups_enabled; |
202 | 8.01k | } |
203 | 345k | bool GetLookupsEnabled() { return m_lookups_enabled; } |
204 | | |
205 | | /// \class ClangASTSourceProxy ClangASTSource.h |
206 | | /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource |
207 | | /// |
208 | | /// Clang AST contexts like to own their AST sources, so this is a state- |
209 | | /// free proxy object. |
210 | | class ClangASTSourceProxy : public clang::ExternalASTSource { |
211 | | public: |
212 | 12.0k | ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {} |
213 | | |
214 | | bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, |
215 | 356k | clang::DeclarationName Name) override { |
216 | 356k | return m_original.FindExternalVisibleDeclsByName(DC, Name); |
217 | 356k | } |
218 | | |
219 | | void FindExternalLexicalDecls( |
220 | | const clang::DeclContext *DC, |
221 | | llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, |
222 | 41.5k | llvm::SmallVectorImpl<clang::Decl *> &Decls) override { |
223 | 41.5k | return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls); |
224 | 41.5k | } |
225 | | |
226 | 876 | void CompleteType(clang::TagDecl *Tag) override { |
227 | 876 | return m_original.CompleteType(Tag); |
228 | 876 | } |
229 | | |
230 | 38 | void CompleteType(clang::ObjCInterfaceDecl *Class) override { |
231 | 38 | return m_original.CompleteType(Class); |
232 | 38 | } |
233 | | |
234 | | bool layoutRecordType( |
235 | | const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, |
236 | | llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, |
237 | | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
238 | | &BaseOffsets, |
239 | | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
240 | 30.1k | &VirtualBaseOffsets) override { |
241 | 30.1k | return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets, |
242 | 30.1k | BaseOffsets, VirtualBaseOffsets); |
243 | 30.1k | } |
244 | | |
245 | 9.94k | void StartTranslationUnit(clang::ASTConsumer *Consumer) override { |
246 | 9.94k | return m_original.StartTranslationUnit(Consumer); |
247 | 9.94k | } |
248 | | |
249 | | private: |
250 | | ClangASTSource &m_original; |
251 | | }; |
252 | | |
253 | 12.0k | clang::ExternalASTSource *CreateProxy() { |
254 | 12.0k | return new ClangASTSourceProxy(*this); |
255 | 12.0k | } |
256 | | |
257 | | protected: |
258 | | /// Look for the complete version of an Objective-C interface, and return it |
259 | | /// if found. |
260 | | /// |
261 | | /// \param[in] interface_decl |
262 | | /// An ObjCInterfaceDecl that may not be the complete one. |
263 | | /// |
264 | | /// \return |
265 | | /// NULL if the complete interface couldn't be found; |
266 | | /// the complete interface otherwise. |
267 | | clang::ObjCInterfaceDecl * |
268 | | GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl); |
269 | | |
270 | | /// Find all entities matching a given name in a given module, using a |
271 | | /// NameSearchContext to make Decls for them. |
272 | | /// |
273 | | /// \param[in] context |
274 | | /// The NameSearchContext that can construct Decls for this name. |
275 | | /// |
276 | | /// \param[in] module |
277 | | /// If non-NULL, the module to query. |
278 | | /// |
279 | | /// \param[in] namespace_decl |
280 | | /// If valid and module is non-NULL, the parent namespace. |
281 | | void FindExternalVisibleDecls(NameSearchContext &context, |
282 | | lldb::ModuleSP module, |
283 | | CompilerDeclContext &namespace_decl); |
284 | | |
285 | | /// Find all Objective-C methods matching a given selector. |
286 | | /// |
287 | | /// \param[in] context |
288 | | /// The NameSearchContext that can construct Decls for this name. |
289 | | /// Its m_decl_name contains the selector and its m_decl_context |
290 | | /// is the containing object. |
291 | | void FindObjCMethodDecls(NameSearchContext &context); |
292 | | |
293 | | /// Find all Objective-C properties and ivars with a given name. |
294 | | /// |
295 | | /// \param[in] context |
296 | | /// The NameSearchContext that can construct Decls for this name. |
297 | | /// Its m_decl_name contains the name and its m_decl_context |
298 | | /// is the containing object. |
299 | | void FindObjCPropertyAndIvarDecls(NameSearchContext &context); |
300 | | |
301 | | /// Performs lookup into a namespace. |
302 | | /// |
303 | | /// \param context |
304 | | /// The NameSearchContext for a lookup inside a namespace. |
305 | | void LookupInNamespace(NameSearchContext &context); |
306 | | |
307 | | /// A wrapper for TypeSystemClang::CopyType that sets a flag that |
308 | | /// indicates that we should not respond to queries during import. |
309 | | /// |
310 | | /// \param[in] src_type |
311 | | /// The source type. |
312 | | /// |
313 | | /// \return |
314 | | /// The imported type. |
315 | | CompilerType GuardedCopyType(const CompilerType &src_type); |
316 | | |
317 | | std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor(); |
318 | | |
319 | | public: |
320 | | /// Returns true if a name should be ignored by name lookup. |
321 | | /// |
322 | | /// \param[in] name |
323 | | /// The name to be considered. |
324 | | /// |
325 | | /// \param[in] ignore_all_dollar_names |
326 | | /// True if $-names of all sorts should be ignored. |
327 | | /// |
328 | | /// \return |
329 | | /// True if the name is one of a class of names that are ignored by |
330 | | /// global lookup for performance reasons. |
331 | | bool IgnoreName(const ConstString name, bool ignore_all_dollar_names); |
332 | | |
333 | | /// Copies a single Decl into the parser's AST context. |
334 | | /// |
335 | | /// \param[in] src_decl |
336 | | /// The Decl to copy. |
337 | | /// |
338 | | /// \return |
339 | | /// A copy of the Decl in m_ast_context, or NULL if the copy failed. |
340 | | clang::Decl *CopyDecl(clang::Decl *src_decl); |
341 | | |
342 | | /// Determined the origin of a single Decl, if it can be found. |
343 | | /// |
344 | | /// \param[in] decl |
345 | | /// The Decl whose origin is to be found. |
346 | | /// |
347 | | /// \return |
348 | | /// True if lookup succeeded; false otherwise. |
349 | | ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl); |
350 | | |
351 | | /// Returns the TypeSystem that uses this ClangASTSource instance as it's |
352 | | /// ExternalASTSource. |
353 | 20.7k | TypeSystemClang *GetTypeSystem() const { return m_clang_ast_context; } |
354 | | |
355 | | protected: |
356 | | bool FindObjCMethodDeclsWithOrigin( |
357 | | NameSearchContext &context, |
358 | | clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info); |
359 | | |
360 | | void FindDeclInModules(NameSearchContext &context, ConstString name); |
361 | | void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name); |
362 | | |
363 | | /// Fills the namespace map of the given NameSearchContext. |
364 | | /// |
365 | | /// \param context The NameSearchContext with the namespace map to fill. |
366 | | /// \param module_sp The module to search for namespaces or a nullptr if |
367 | | /// the current target should be searched. |
368 | | /// \param namespace_decl The DeclContext in which to search for namespaces. |
369 | | void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp, |
370 | | const CompilerDeclContext &namespace_decl); |
371 | | |
372 | | clang::TagDecl *FindCompleteType(const clang::TagDecl *decl); |
373 | | |
374 | | friend struct NameSearchContext; |
375 | | |
376 | | bool m_lookups_enabled; |
377 | | |
378 | | /// The target to use in finding variables and types. |
379 | | const lldb::TargetSP m_target; |
380 | | /// The AST context requests are coming in for. |
381 | | clang::ASTContext *m_ast_context; |
382 | | /// The TypeSystemClang for m_ast_context. |
383 | | TypeSystemClang *m_clang_ast_context; |
384 | | /// The file manager paired with the AST context. |
385 | | clang::FileManager *m_file_manager; |
386 | | /// The target's AST importer. |
387 | | std::shared_ptr<ClangASTImporter> m_ast_importer_sp; |
388 | | std::set<const clang::Decl *> m_active_lexical_decls; |
389 | | std::set<const char *> m_active_lookups; |
390 | | }; |
391 | | |
392 | | } // namespace lldb_private |
393 | | |
394 | | #endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H |