/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- ClangASTImporter.cpp ----------------------------------------------===// |
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 | | #include "lldb/Core/Module.h" |
10 | | #include "lldb/Utility/LLDBAssert.h" |
11 | | #include "lldb/Utility/LLDBLog.h" |
12 | | #include "lldb/Utility/Log.h" |
13 | | #include "clang/AST/Decl.h" |
14 | | #include "clang/AST/DeclCXX.h" |
15 | | #include "clang/AST/DeclObjC.h" |
16 | | #include "clang/Sema/Lookup.h" |
17 | | #include "clang/Sema/Sema.h" |
18 | | #include "llvm/Support/raw_ostream.h" |
19 | | |
20 | | #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" |
21 | | #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" |
22 | | #include "Plugins/ExpressionParser/Clang/ClangASTSource.h" |
23 | | #include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h" |
24 | | #include "Plugins/ExpressionParser/Clang/ClangUtil.h" |
25 | | #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" |
26 | | |
27 | | #include <memory> |
28 | | #include <optional> |
29 | | |
30 | | using namespace lldb_private; |
31 | | using namespace clang; |
32 | | |
33 | | CompilerType ClangASTImporter::CopyType(TypeSystemClang &dst_ast, |
34 | 22.0k | const CompilerType &src_type) { |
35 | 22.0k | clang::ASTContext &dst_clang_ast = dst_ast.getASTContext(); |
36 | | |
37 | 22.0k | auto src_ast = src_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>(); |
38 | 22.0k | if (!src_ast) |
39 | 0 | return CompilerType(); |
40 | | |
41 | 22.0k | clang::ASTContext &src_clang_ast = src_ast->getASTContext(); |
42 | | |
43 | 22.0k | clang::QualType src_qual_type = ClangUtil::GetQualType(src_type); |
44 | | |
45 | 22.0k | ImporterDelegateSP delegate_sp(GetDelegate(&dst_clang_ast, &src_clang_ast)); |
46 | 22.0k | if (!delegate_sp) |
47 | 0 | return CompilerType(); |
48 | | |
49 | 22.0k | ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, &dst_clang_ast); |
50 | | |
51 | 22.0k | llvm::Expected<QualType> ret_or_error = delegate_sp->Import(src_qual_type); |
52 | 22.0k | if (!ret_or_error) { |
53 | 0 | Log *log = GetLog(LLDBLog::Expressions); |
54 | 0 | LLDB_LOG_ERROR(log, ret_or_error.takeError(), |
55 | 0 | "Couldn't import type: {0}"); |
56 | 0 | return CompilerType(); |
57 | 0 | } |
58 | | |
59 | 22.0k | lldb::opaque_compiler_type_t dst_clang_type = ret_or_error->getAsOpaquePtr(); |
60 | | |
61 | 22.0k | if (dst_clang_type) |
62 | 22.0k | return CompilerType(dst_ast.weak_from_this(), dst_clang_type); |
63 | 0 | return CompilerType(); |
64 | 22.0k | } |
65 | | |
66 | | clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast, |
67 | 347k | clang::Decl *decl) { |
68 | 347k | ImporterDelegateSP delegate_sp; |
69 | | |
70 | 347k | clang::ASTContext *src_ast = &decl->getASTContext(); |
71 | 347k | delegate_sp = GetDelegate(dst_ast, src_ast); |
72 | | |
73 | 347k | ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); |
74 | | |
75 | 347k | if (!delegate_sp) |
76 | 0 | return nullptr; |
77 | | |
78 | 347k | llvm::Expected<clang::Decl *> result = delegate_sp->Import(decl); |
79 | 347k | if (!result) { |
80 | 4 | Log *log = GetLog(LLDBLog::Expressions); |
81 | 4 | LLDB_LOG_ERROR(log, result.takeError(), "Couldn't import decl: {0}"); |
82 | 4 | if (log) { |
83 | 0 | lldb::user_id_t user_id = LLDB_INVALID_UID; |
84 | 0 | ClangASTMetadata *metadata = GetDeclMetadata(decl); |
85 | 0 | if (metadata) |
86 | 0 | user_id = metadata->GetUserID(); |
87 | |
|
88 | 0 | if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) |
89 | 0 | LLDB_LOG(log, |
90 | 0 | " [ClangASTImporter] WARNING: Failed to import a {0} " |
91 | 0 | "'{1}', metadata {2}", |
92 | 0 | decl->getDeclKindName(), named_decl->getNameAsString(), |
93 | 0 | user_id); |
94 | 0 | else |
95 | 0 | LLDB_LOG(log, |
96 | 0 | " [ClangASTImporter] WARNING: Failed to import a {0}, " |
97 | 0 | "metadata {1}", |
98 | 0 | decl->getDeclKindName(), user_id); |
99 | 0 | } |
100 | 4 | return nullptr; |
101 | 4 | } |
102 | | |
103 | 347k | return *result; |
104 | 347k | } |
105 | | |
106 | | class DeclContextOverride { |
107 | | private: |
108 | | struct Backup { |
109 | | clang::DeclContext *decl_context; |
110 | | clang::DeclContext *lexical_decl_context; |
111 | | }; |
112 | | |
113 | | llvm::DenseMap<clang::Decl *, Backup> m_backups; |
114 | | |
115 | 99 | void OverrideOne(clang::Decl *decl) { |
116 | 99 | if (m_backups.contains(decl)) { |
117 | 0 | return; |
118 | 0 | } |
119 | | |
120 | 99 | m_backups[decl] = {decl->getDeclContext(), decl->getLexicalDeclContext()}; |
121 | | |
122 | 99 | decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl()); |
123 | 99 | decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl()); |
124 | 99 | } |
125 | | |
126 | | bool ChainPassesThrough( |
127 | | clang::Decl *decl, clang::DeclContext *base, |
128 | | clang::DeclContext *(clang::Decl::*contextFromDecl)(), |
129 | 0 | clang::DeclContext *(clang::DeclContext::*contextFromContext)()) { |
130 | 0 | for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); decl_ctx; |
131 | 0 | decl_ctx = (decl_ctx->*contextFromContext)()) { |
132 | 0 | if (decl_ctx == base) { |
133 | 0 | return true; |
134 | 0 | } |
135 | 0 | } |
136 | | |
137 | 0 | return false; |
138 | 0 | } |
139 | | |
140 | | clang::Decl *GetEscapedChild(clang::Decl *decl, |
141 | 239 | clang::DeclContext *base = nullptr) { |
142 | 239 | if (base) { |
143 | | // decl's DeclContext chains must pass through base. |
144 | |
|
145 | 0 | if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext, |
146 | 0 | &clang::DeclContext::getParent) || |
147 | 0 | !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext, |
148 | 0 | &clang::DeclContext::getLexicalParent)) { |
149 | 0 | return decl; |
150 | 0 | } |
151 | 239 | } else { |
152 | 239 | base = clang::dyn_cast<clang::DeclContext>(decl); |
153 | | |
154 | 239 | if (!base) { |
155 | 133 | return nullptr; |
156 | 133 | } |
157 | 239 | } |
158 | | |
159 | 106 | if (clang::DeclContext *context = |
160 | 106 | clang::dyn_cast<clang::DeclContext>(decl)) { |
161 | 140 | for (clang::Decl *decl : context->decls()) { |
162 | 140 | if (clang::Decl *escaped_child = GetEscapedChild(decl)) { |
163 | 0 | return escaped_child; |
164 | 0 | } |
165 | 140 | } |
166 | 106 | } |
167 | | |
168 | 106 | return nullptr; |
169 | 106 | } |
170 | | |
171 | 99 | void Override(clang::Decl *decl) { |
172 | 99 | if (clang::Decl *escaped_child = GetEscapedChild(decl)) { |
173 | 0 | Log *log = GetLog(LLDBLog::Expressions); |
174 | |
|
175 | 0 | LLDB_LOG(log, |
176 | 0 | " [ClangASTImporter] DeclContextOverride couldn't " |
177 | 0 | "override ({0}Decl*){1} - its child ({2}Decl*){3} escapes", |
178 | 0 | decl->getDeclKindName(), decl, escaped_child->getDeclKindName(), |
179 | 0 | escaped_child); |
180 | 0 | lldbassert(0 && "Couldn't override!"); |
181 | 0 | } |
182 | | |
183 | 99 | OverrideOne(decl); |
184 | 99 | } |
185 | | |
186 | | public: |
187 | 6.90k | DeclContextOverride() = default; |
188 | | |
189 | 1.57k | void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) { |
190 | 1.57k | for (DeclContext *decl_context = decl->getLexicalDeclContext(); |
191 | 3.61k | decl_context; decl_context = decl_context->getLexicalParent()2.03k ) { |
192 | 2.03k | DeclContext *redecl_context = decl_context->getRedeclContext(); |
193 | | |
194 | 2.03k | if (llvm::isa<FunctionDecl>(redecl_context) && |
195 | 2.03k | llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())37 ) { |
196 | 99 | for (clang::Decl *child_decl : decl_context->decls()) { |
197 | 99 | Override(child_decl); |
198 | 99 | } |
199 | 37 | } |
200 | 2.03k | } |
201 | 1.57k | } |
202 | | |
203 | 6.90k | ~DeclContextOverride() { |
204 | 6.90k | for (const std::pair<clang::Decl *, Backup> &backup : m_backups) { |
205 | 99 | backup.first->setDeclContext(backup.second.decl_context); |
206 | 99 | backup.first->setLexicalDeclContext(backup.second.lexical_decl_context); |
207 | 99 | } |
208 | 6.90k | } |
209 | | }; |
210 | | |
211 | | namespace { |
212 | | /// Completes all imported TagDecls at the end of the scope. |
213 | | /// |
214 | | /// While in a CompleteTagDeclsScope, every decl that could be completed will |
215 | | /// be completed at the end of the scope (including all Decls that are |
216 | | /// imported while completing the original Decls). |
217 | | class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener { |
218 | | ClangASTImporter::ImporterDelegateSP m_delegate; |
219 | | /// List of declarations in the target context that need to be completed. |
220 | | /// Every declaration should only be completed once and therefore should only |
221 | | /// be once in this list. |
222 | | llvm::SetVector<NamedDecl *> m_decls_to_complete; |
223 | | /// Set of declarations that already were successfully completed (not just |
224 | | /// added to m_decls_to_complete). |
225 | | llvm::SmallPtrSet<NamedDecl *, 32> m_decls_already_completed; |
226 | | clang::ASTContext *m_dst_ctx; |
227 | | clang::ASTContext *m_src_ctx; |
228 | | ClangASTImporter &importer; |
229 | | |
230 | | public: |
231 | | /// Constructs a CompleteTagDeclsScope. |
232 | | /// \param importer The ClangASTImporter that we should observe. |
233 | | /// \param dst_ctx The ASTContext to which Decls are imported. |
234 | | /// \param src_ctx The ASTContext from which Decls are imported. |
235 | | explicit CompleteTagDeclsScope(ClangASTImporter &importer, |
236 | | clang::ASTContext *dst_ctx, |
237 | | clang::ASTContext *src_ctx) |
238 | 6.90k | : m_delegate(importer.GetDelegate(dst_ctx, src_ctx)), m_dst_ctx(dst_ctx), |
239 | 6.90k | m_src_ctx(src_ctx), importer(importer) { |
240 | 6.90k | m_delegate->SetImportListener(this); |
241 | 6.90k | } |
242 | | |
243 | 6.90k | ~CompleteTagDeclsScope() override { |
244 | 6.90k | ClangASTImporter::ASTContextMetadataSP to_context_md = |
245 | 6.90k | importer.GetContextMetadata(m_dst_ctx); |
246 | | |
247 | | // Complete all decls we collected until now. |
248 | 20.8k | while (!m_decls_to_complete.empty()) { |
249 | 13.9k | NamedDecl *decl = m_decls_to_complete.pop_back_val(); |
250 | 13.9k | m_decls_already_completed.insert(decl); |
251 | | |
252 | | // The decl that should be completed has to be imported into the target |
253 | | // context from some other context. |
254 | 13.9k | assert(to_context_md->hasOrigin(decl)); |
255 | | // We should only complete decls coming from the source context. |
256 | 13.9k | assert(to_context_md->getOrigin(decl).ctx == m_src_ctx); |
257 | | |
258 | 13.9k | Decl *original_decl = to_context_md->getOrigin(decl).decl; |
259 | | |
260 | | // Complete the decl now. |
261 | 13.9k | TypeSystemClang::GetCompleteDecl(m_src_ctx, original_decl); |
262 | 13.9k | if (auto *tag_decl = dyn_cast<TagDecl>(decl)) { |
263 | 13.9k | if (auto *original_tag_decl = dyn_cast<TagDecl>(original_decl)) { |
264 | 13.9k | if (original_tag_decl->isCompleteDefinition()) { |
265 | 10.9k | m_delegate->ImportDefinitionTo(tag_decl, original_tag_decl); |
266 | 10.9k | tag_decl->setCompleteDefinition(true); |
267 | 10.9k | } |
268 | 13.9k | } |
269 | | |
270 | 13.9k | tag_decl->setHasExternalLexicalStorage(false); |
271 | 13.9k | tag_decl->setHasExternalVisibleStorage(false); |
272 | 13.9k | } else if (auto *0 container_decl0 = dyn_cast<ObjCContainerDecl>(decl)) { |
273 | 0 | container_decl->setHasExternalLexicalStorage(false); |
274 | 0 | container_decl->setHasExternalVisibleStorage(false); |
275 | 0 | } |
276 | | |
277 | 13.9k | to_context_md->removeOrigin(decl); |
278 | 13.9k | } |
279 | | |
280 | | // Stop listening to imported decls. We do this after clearing the |
281 | | // Decls we needed to import to catch all Decls they might have pulled in. |
282 | 6.90k | m_delegate->RemoveImportListener(); |
283 | 6.90k | } |
284 | | |
285 | 369k | void NewDeclImported(clang::Decl *from, clang::Decl *to) override { |
286 | | // Filter out decls that we can't complete later. |
287 | 369k | if (!isa<TagDecl>(to) && !isa<ObjCInterfaceDecl>(to)345k ) |
288 | 345k | return; |
289 | 24.6k | RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from); |
290 | | // We don't need to complete injected class name decls. |
291 | 24.6k | if (from_record_decl && from_record_decl->isInjectedClassName()24.4k ) |
292 | 10.6k | return; |
293 | | |
294 | 13.9k | NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to); |
295 | | // Check if we already completed this type. |
296 | 13.9k | if (m_decls_already_completed.contains(to_named_decl)) |
297 | 0 | return; |
298 | | // Queue this type to be completed. |
299 | 13.9k | m_decls_to_complete.insert(to_named_decl); |
300 | 13.9k | } |
301 | | }; |
302 | | } // namespace |
303 | | |
304 | | CompilerType ClangASTImporter::DeportType(TypeSystemClang &dst, |
305 | 6.83k | const CompilerType &src_type) { |
306 | 6.83k | Log *log = GetLog(LLDBLog::Expressions); |
307 | | |
308 | 6.83k | auto src_ctxt = src_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>(); |
309 | 6.83k | if (!src_ctxt) |
310 | 0 | return {}; |
311 | | |
312 | 6.83k | LLDB_LOG(log, |
313 | 6.83k | " [ClangASTImporter] DeportType called on ({0}Type*){1} " |
314 | 6.83k | "from (ASTContext*){2} to (ASTContext*){3}", |
315 | 6.83k | src_type.GetTypeName(), src_type.GetOpaqueQualType(), |
316 | 6.83k | &src_ctxt->getASTContext(), &dst.getASTContext()); |
317 | | |
318 | 6.83k | DeclContextOverride decl_context_override; |
319 | | |
320 | 6.83k | if (auto *t = ClangUtil::GetQualType(src_type)->getAs<TagType>()) |
321 | 1.50k | decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl()); |
322 | | |
323 | 6.83k | CompleteTagDeclsScope complete_scope(*this, &dst.getASTContext(), |
324 | 6.83k | &src_ctxt->getASTContext()); |
325 | 6.83k | return CopyType(dst, src_type); |
326 | 6.83k | } |
327 | | |
328 | | clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, |
329 | 78 | clang::Decl *decl) { |
330 | 78 | Log *log = GetLog(LLDBLog::Expressions); |
331 | | |
332 | 78 | clang::ASTContext *src_ctx = &decl->getASTContext(); |
333 | 78 | LLDB_LOG(log, |
334 | 78 | " [ClangASTImporter] DeportDecl called on ({0}Decl*){1} from " |
335 | 78 | "(ASTContext*){2} to (ASTContext*){3}", |
336 | 78 | decl->getDeclKindName(), decl, src_ctx, dst_ctx); |
337 | | |
338 | 78 | DeclContextOverride decl_context_override; |
339 | | |
340 | 78 | decl_context_override.OverrideAllDeclsFromContainingFunction(decl); |
341 | | |
342 | 78 | clang::Decl *result; |
343 | 78 | { |
344 | 78 | CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx); |
345 | 78 | result = CopyDecl(dst_ctx, decl); |
346 | 78 | } |
347 | | |
348 | 78 | if (!result) |
349 | 0 | return nullptr; |
350 | | |
351 | 78 | LLDB_LOG(log, |
352 | 78 | " [ClangASTImporter] DeportDecl deported ({0}Decl*){1} to " |
353 | 78 | "({2}Decl*){3}", |
354 | 78 | decl->getDeclKindName(), decl, result->getDeclKindName(), result); |
355 | | |
356 | 78 | return result; |
357 | 78 | } |
358 | | |
359 | 37.2k | bool ClangASTImporter::CanImport(const CompilerType &type) { |
360 | 37.2k | if (!ClangUtil::IsClangType(type)) |
361 | 1 | return false; |
362 | | |
363 | 37.2k | clang::QualType qual_type( |
364 | 37.2k | ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); |
365 | | |
366 | 37.2k | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); |
367 | 37.2k | switch (type_class) { |
368 | 36.5k | case clang::Type::Record: { |
369 | 36.5k | const clang::CXXRecordDecl *cxx_record_decl = |
370 | 36.5k | qual_type->getAsCXXRecordDecl(); |
371 | 36.5k | if (cxx_record_decl) { |
372 | 36.5k | if (GetDeclOrigin(cxx_record_decl).Valid()) |
373 | 127 | return true; |
374 | 36.5k | } |
375 | 36.5k | } break36.4k ; |
376 | | |
377 | 36.4k | case clang::Type::Enum: { |
378 | 138 | clang::EnumDecl *enum_decl = |
379 | 138 | llvm::cast<clang::EnumType>(qual_type)->getDecl(); |
380 | 138 | if (enum_decl) { |
381 | 138 | if (GetDeclOrigin(enum_decl).Valid()) |
382 | 0 | return true; |
383 | 138 | } |
384 | 138 | } break; |
385 | | |
386 | 138 | case clang::Type::ObjCObject: |
387 | 505 | case clang::Type::ObjCInterface: { |
388 | 505 | const clang::ObjCObjectType *objc_class_type = |
389 | 505 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type); |
390 | 505 | if (objc_class_type) { |
391 | 505 | clang::ObjCInterfaceDecl *class_interface_decl = |
392 | 505 | objc_class_type->getInterface(); |
393 | | // We currently can't complete objective C types through the newly added |
394 | | // ASTContext because it only supports TagDecl objects right now... |
395 | 505 | if (class_interface_decl) { |
396 | 505 | if (GetDeclOrigin(class_interface_decl).Valid()) |
397 | 10 | return true; |
398 | 505 | } |
399 | 505 | } |
400 | 505 | } break495 ; |
401 | | |
402 | 495 | case clang::Type::Typedef: |
403 | 0 | return CanImport(CompilerType(type.GetTypeSystem(), |
404 | 0 | llvm::cast<clang::TypedefType>(qual_type) |
405 | 0 | ->getDecl() |
406 | 0 | ->getUnderlyingType() |
407 | 0 | .getAsOpaquePtr())); |
408 | | |
409 | 0 | case clang::Type::Auto: |
410 | 0 | return CanImport(CompilerType(type.GetTypeSystem(), |
411 | 0 | llvm::cast<clang::AutoType>(qual_type) |
412 | 0 | ->getDeducedType() |
413 | 0 | .getAsOpaquePtr())); |
414 | | |
415 | 0 | case clang::Type::Elaborated: |
416 | 0 | return CanImport(CompilerType(type.GetTypeSystem(), |
417 | 0 | llvm::cast<clang::ElaboratedType>(qual_type) |
418 | 0 | ->getNamedType() |
419 | 0 | .getAsOpaquePtr())); |
420 | | |
421 | 0 | case clang::Type::Paren: |
422 | 0 | return CanImport(CompilerType( |
423 | 0 | type.GetTypeSystem(), |
424 | 0 | llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); |
425 | | |
426 | 0 | default: |
427 | 0 | break; |
428 | 37.2k | } |
429 | | |
430 | 37.0k | return false; |
431 | 37.2k | } |
432 | | |
433 | 57 | bool ClangASTImporter::Import(const CompilerType &type) { |
434 | 57 | if (!ClangUtil::IsClangType(type)) |
435 | 1 | return false; |
436 | | |
437 | 56 | clang::QualType qual_type( |
438 | 56 | ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); |
439 | | |
440 | 56 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); |
441 | 56 | switch (type_class) { |
442 | 51 | case clang::Type::Record: { |
443 | 51 | const clang::CXXRecordDecl *cxx_record_decl = |
444 | 51 | qual_type->getAsCXXRecordDecl(); |
445 | 51 | if (cxx_record_decl) { |
446 | 51 | if (GetDeclOrigin(cxx_record_decl).Valid()) |
447 | 51 | return CompleteAndFetchChildren(qual_type); |
448 | 51 | } |
449 | 51 | } break0 ; |
450 | | |
451 | 0 | case clang::Type::Enum: { |
452 | 0 | clang::EnumDecl *enum_decl = |
453 | 0 | llvm::cast<clang::EnumType>(qual_type)->getDecl(); |
454 | 0 | if (enum_decl) { |
455 | 0 | if (GetDeclOrigin(enum_decl).Valid()) |
456 | 0 | return CompleteAndFetchChildren(qual_type); |
457 | 0 | } |
458 | 0 | } break; |
459 | | |
460 | 0 | case clang::Type::ObjCObject: |
461 | 5 | case clang::Type::ObjCInterface: { |
462 | 5 | const clang::ObjCObjectType *objc_class_type = |
463 | 5 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type); |
464 | 5 | if (objc_class_type) { |
465 | 5 | clang::ObjCInterfaceDecl *class_interface_decl = |
466 | 5 | objc_class_type->getInterface(); |
467 | | // We currently can't complete objective C types through the newly added |
468 | | // ASTContext because it only supports TagDecl objects right now... |
469 | 5 | if (class_interface_decl) { |
470 | 5 | if (GetDeclOrigin(class_interface_decl).Valid()) |
471 | 5 | return CompleteAndFetchChildren(qual_type); |
472 | 5 | } |
473 | 5 | } |
474 | 5 | } break0 ; |
475 | | |
476 | 0 | case clang::Type::Typedef: |
477 | 0 | return Import(CompilerType(type.GetTypeSystem(), |
478 | 0 | llvm::cast<clang::TypedefType>(qual_type) |
479 | 0 | ->getDecl() |
480 | 0 | ->getUnderlyingType() |
481 | 0 | .getAsOpaquePtr())); |
482 | | |
483 | 0 | case clang::Type::Auto: |
484 | 0 | return Import(CompilerType(type.GetTypeSystem(), |
485 | 0 | llvm::cast<clang::AutoType>(qual_type) |
486 | 0 | ->getDeducedType() |
487 | 0 | .getAsOpaquePtr())); |
488 | | |
489 | 0 | case clang::Type::Elaborated: |
490 | 0 | return Import(CompilerType(type.GetTypeSystem(), |
491 | 0 | llvm::cast<clang::ElaboratedType>(qual_type) |
492 | 0 | ->getNamedType() |
493 | 0 | .getAsOpaquePtr())); |
494 | | |
495 | 0 | case clang::Type::Paren: |
496 | 0 | return Import(CompilerType( |
497 | 0 | type.GetTypeSystem(), |
498 | 0 | llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); |
499 | | |
500 | 0 | default: |
501 | 0 | break; |
502 | 56 | } |
503 | 0 | return false; |
504 | 56 | } |
505 | | |
506 | 56 | bool ClangASTImporter::CompleteType(const CompilerType &compiler_type) { |
507 | 56 | if (!CanImport(compiler_type)) |
508 | 0 | return false; |
509 | | |
510 | 56 | if (Import(compiler_type)) { |
511 | 56 | TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); |
512 | 56 | return true; |
513 | 56 | } |
514 | | |
515 | 0 | TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), |
516 | 0 | false); |
517 | 0 | return false; |
518 | 56 | } |
519 | | |
520 | | bool ClangASTImporter::LayoutRecordType( |
521 | | const clang::RecordDecl *record_decl, uint64_t &bit_size, |
522 | | uint64_t &alignment, |
523 | | llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, |
524 | | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
525 | | &base_offsets, |
526 | | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
527 | 5.89k | &vbase_offsets) { |
528 | 5.89k | RecordDeclToLayoutMap::iterator pos = |
529 | 5.89k | m_record_decl_to_layout_map.find(record_decl); |
530 | 5.89k | bool success = false; |
531 | 5.89k | base_offsets.clear(); |
532 | 5.89k | vbase_offsets.clear(); |
533 | 5.89k | if (pos != m_record_decl_to_layout_map.end()) { |
534 | 5.06k | bit_size = pos->second.bit_size; |
535 | 5.06k | alignment = pos->second.alignment; |
536 | 5.06k | field_offsets.swap(pos->second.field_offsets); |
537 | 5.06k | base_offsets.swap(pos->second.base_offsets); |
538 | 5.06k | vbase_offsets.swap(pos->second.vbase_offsets); |
539 | 5.06k | m_record_decl_to_layout_map.erase(pos); |
540 | 5.06k | success = true; |
541 | 5.06k | } else { |
542 | 831 | bit_size = 0; |
543 | 831 | alignment = 0; |
544 | 831 | field_offsets.clear(); |
545 | 831 | } |
546 | 5.89k | return success; |
547 | 5.89k | } |
548 | | |
549 | | void ClangASTImporter::SetRecordLayout(clang::RecordDecl *decl, |
550 | 5.88k | const LayoutInfo &layout) { |
551 | 5.88k | m_record_decl_to_layout_map.insert(std::make_pair(decl, layout)); |
552 | 5.88k | } |
553 | | |
554 | 5.26k | bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { |
555 | 5.26k | DeclOrigin decl_origin = GetDeclOrigin(decl); |
556 | | |
557 | 5.26k | if (!decl_origin.Valid()) |
558 | 802 | return false; |
559 | | |
560 | 4.46k | if (!TypeSystemClang::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) |
561 | 47 | return false; |
562 | | |
563 | 4.41k | ImporterDelegateSP delegate_sp( |
564 | 4.41k | GetDelegate(&decl->getASTContext(), decl_origin.ctx)); |
565 | | |
566 | 4.41k | ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, |
567 | 4.41k | &decl->getASTContext()); |
568 | 4.41k | if (delegate_sp) |
569 | 4.41k | delegate_sp->ImportDefinitionTo(decl, decl_origin.decl); |
570 | | |
571 | 4.41k | return true; |
572 | 4.46k | } |
573 | | |
574 | | bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, |
575 | 21 | clang::TagDecl *origin_decl) { |
576 | 21 | clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); |
577 | | |
578 | 21 | if (!TypeSystemClang::GetCompleteDecl(origin_ast_ctx, origin_decl)) |
579 | 0 | return false; |
580 | | |
581 | 21 | ImporterDelegateSP delegate_sp( |
582 | 21 | GetDelegate(&decl->getASTContext(), origin_ast_ctx)); |
583 | | |
584 | 21 | if (delegate_sp) |
585 | 21 | delegate_sp->ImportDefinitionTo(decl, origin_decl); |
586 | | |
587 | 21 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); |
588 | | |
589 | 21 | context_md->setOrigin(decl, DeclOrigin(origin_ast_ctx, origin_decl)); |
590 | 21 | return true; |
591 | 21 | } |
592 | | |
593 | | bool ClangASTImporter::CompleteObjCInterfaceDecl( |
594 | 1.50k | clang::ObjCInterfaceDecl *interface_decl) { |
595 | 1.50k | DeclOrigin decl_origin = GetDeclOrigin(interface_decl); |
596 | | |
597 | 1.50k | if (!decl_origin.Valid()) |
598 | 0 | return false; |
599 | | |
600 | 1.50k | if (!TypeSystemClang::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) |
601 | 5 | return false; |
602 | | |
603 | 1.50k | ImporterDelegateSP delegate_sp( |
604 | 1.50k | GetDelegate(&interface_decl->getASTContext(), decl_origin.ctx)); |
605 | | |
606 | 1.50k | if (delegate_sp) |
607 | 1.50k | delegate_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); |
608 | | |
609 | 1.50k | if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass()) |
610 | 563 | RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0)); |
611 | | |
612 | 1.50k | return true; |
613 | 1.50k | } |
614 | | |
615 | 56 | bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { |
616 | 56 | if (!RequireCompleteType(type)) |
617 | 0 | return false; |
618 | | |
619 | 56 | Log *log = GetLog(LLDBLog::Expressions); |
620 | | |
621 | 56 | if (const TagType *tag_type = type->getAs<TagType>()) { |
622 | 51 | TagDecl *tag_decl = tag_type->getDecl(); |
623 | | |
624 | 51 | DeclOrigin decl_origin = GetDeclOrigin(tag_decl); |
625 | | |
626 | 51 | if (!decl_origin.Valid()) |
627 | 0 | return false; |
628 | | |
629 | 51 | ImporterDelegateSP delegate_sp( |
630 | 51 | GetDelegate(&tag_decl->getASTContext(), decl_origin.ctx)); |
631 | | |
632 | 51 | ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, |
633 | 51 | &tag_decl->getASTContext()); |
634 | | |
635 | 51 | TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl); |
636 | | |
637 | 56 | for (Decl *origin_child_decl : origin_tag_decl->decls()) { |
638 | 56 | llvm::Expected<Decl *> imported_or_err = |
639 | 56 | delegate_sp->Import(origin_child_decl); |
640 | 56 | if (!imported_or_err) { |
641 | 0 | LLDB_LOG_ERROR(log, imported_or_err.takeError(), |
642 | 0 | "Couldn't import decl: {0}"); |
643 | 0 | return false; |
644 | 0 | } |
645 | 56 | } |
646 | | |
647 | 51 | if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) |
648 | 51 | record_decl->setHasLoadedFieldsFromExternalStorage(true); |
649 | | |
650 | 51 | return true; |
651 | 51 | } |
652 | | |
653 | 5 | if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) { |
654 | 5 | if (ObjCInterfaceDecl *objc_interface_decl = |
655 | 5 | objc_object_type->getInterface()) { |
656 | 5 | DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl); |
657 | | |
658 | 5 | if (!decl_origin.Valid()) |
659 | 0 | return false; |
660 | | |
661 | 5 | ImporterDelegateSP delegate_sp( |
662 | 5 | GetDelegate(&objc_interface_decl->getASTContext(), decl_origin.ctx)); |
663 | | |
664 | 5 | ObjCInterfaceDecl *origin_interface_decl = |
665 | 5 | llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl); |
666 | | |
667 | 26 | for (Decl *origin_child_decl : origin_interface_decl->decls()) { |
668 | 26 | llvm::Expected<Decl *> imported_or_err = |
669 | 26 | delegate_sp->Import(origin_child_decl); |
670 | 26 | if (!imported_or_err) { |
671 | 0 | LLDB_LOG_ERROR(log, imported_or_err.takeError(), |
672 | 0 | "Couldn't import decl: {0}"); |
673 | 0 | return false; |
674 | 0 | } |
675 | 26 | } |
676 | | |
677 | 5 | return true; |
678 | 5 | } |
679 | 0 | return false; |
680 | 5 | } |
681 | | |
682 | 0 | return true; |
683 | 5 | } |
684 | | |
685 | 25.9k | bool ClangASTImporter::RequireCompleteType(clang::QualType type) { |
686 | 25.9k | if (type.isNull()) |
687 | 2 | return false; |
688 | | |
689 | 25.9k | if (const TagType *tag_type = type->getAs<TagType>()) { |
690 | 2.72k | TagDecl *tag_decl = tag_type->getDecl(); |
691 | | |
692 | 2.72k | if (tag_decl->getDefinition() || tag_decl->isBeingDefined()32 ) |
693 | 2.69k | return true; |
694 | | |
695 | 32 | return CompleteTagDecl(tag_decl); |
696 | 2.72k | } |
697 | 23.2k | if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) { |
698 | 571 | if (ObjCInterfaceDecl *objc_interface_decl = |
699 | 571 | objc_object_type->getInterface()) |
700 | 571 | return CompleteObjCInterfaceDecl(objc_interface_decl); |
701 | 0 | return false; |
702 | 571 | } |
703 | 22.6k | if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) |
704 | 1.06k | return RequireCompleteType(array_type->getElementType()); |
705 | 21.5k | if (const AtomicType *atomic_type = type->getAs<AtomicType>()) |
706 | 2 | return RequireCompleteType(atomic_type->getPointeeType()); |
707 | | |
708 | 21.5k | return true; |
709 | 21.5k | } |
710 | | |
711 | 2.05M | ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) { |
712 | 2.05M | DeclOrigin decl_origin = GetDeclOrigin(decl); |
713 | | |
714 | 2.05M | if (decl_origin.Valid()) { |
715 | 2.15k | TypeSystemClang *ast = TypeSystemClang::GetASTContext(decl_origin.ctx); |
716 | 2.15k | return ast->GetMetadata(decl_origin.decl); |
717 | 2.15k | } |
718 | 2.05M | TypeSystemClang *ast = TypeSystemClang::GetASTContext(&decl->getASTContext()); |
719 | 2.05M | return ast->GetMetadata(decl); |
720 | 2.05M | } |
721 | | |
722 | | ClangASTImporter::DeclOrigin |
723 | 3.58M | ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) { |
724 | 3.58M | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); |
725 | | |
726 | 3.58M | return context_md->getOrigin(decl); |
727 | 3.58M | } |
728 | | |
729 | | void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl, |
730 | 38 | clang::Decl *original_decl) { |
731 | 38 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); |
732 | 38 | context_md->setOrigin( |
733 | 38 | decl, DeclOrigin(&original_decl->getASTContext(), original_decl)); |
734 | 38 | } |
735 | | |
736 | | void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, |
737 | 232 | NamespaceMapSP &namespace_map) { |
738 | 232 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); |
739 | | |
740 | 232 | context_md->m_namespace_maps[decl] = namespace_map; |
741 | 232 | } |
742 | | |
743 | | ClangASTImporter::NamespaceMapSP |
744 | 10.2k | ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) { |
745 | 10.2k | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); |
746 | | |
747 | 10.2k | NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps; |
748 | | |
749 | 10.2k | NamespaceMetaMap::iterator iter = namespace_maps.find(decl); |
750 | | |
751 | 10.2k | if (iter != namespace_maps.end()) |
752 | 8.94k | return iter->second; |
753 | 1.28k | return NamespaceMapSP(); |
754 | 10.2k | } |
755 | | |
756 | 16.7k | void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) { |
757 | 16.7k | assert(decl); |
758 | 16.7k | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); |
759 | | |
760 | 16.7k | const DeclContext *parent_context = decl->getDeclContext(); |
761 | 16.7k | const NamespaceDecl *parent_namespace = |
762 | 16.7k | dyn_cast<NamespaceDecl>(parent_context); |
763 | 16.7k | NamespaceMapSP parent_map; |
764 | | |
765 | 16.7k | if (parent_namespace) |
766 | 8.15k | parent_map = GetNamespaceMap(parent_namespace); |
767 | | |
768 | 16.7k | NamespaceMapSP new_map; |
769 | | |
770 | 16.7k | new_map = std::make_shared<NamespaceMap>(); |
771 | | |
772 | 16.7k | if (context_md->m_map_completer) { |
773 | 16.7k | std::string namespace_string = decl->getDeclName().getAsString(); |
774 | | |
775 | 16.7k | context_md->m_map_completer->CompleteNamespaceMap( |
776 | 16.7k | new_map, ConstString(namespace_string.c_str()), parent_map); |
777 | 16.7k | } |
778 | | |
779 | 16.7k | context_md->m_namespace_maps[decl] = new_map; |
780 | 16.7k | } |
781 | | |
782 | 12.0k | void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) { |
783 | 12.0k | Log *log = GetLog(LLDBLog::Expressions); |
784 | | |
785 | 12.0k | LLDB_LOG(log, |
786 | 12.0k | " [ClangASTImporter] Forgetting destination (ASTContext*){0}", |
787 | 12.0k | dst_ast); |
788 | | |
789 | 12.0k | m_metadata_map.erase(dst_ast); |
790 | 12.0k | } |
791 | | |
792 | | void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, |
793 | 10.3k | clang::ASTContext *src_ast) { |
794 | 10.3k | ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast); |
795 | | |
796 | 10.3k | Log *log = GetLog(LLDBLog::Expressions); |
797 | | |
798 | 10.3k | LLDB_LOG(log, |
799 | 10.3k | " [ClangASTImporter] Forgetting source->dest " |
800 | 10.3k | "(ASTContext*){0}->(ASTContext*){1}", |
801 | 10.3k | src_ast, dst_ast); |
802 | | |
803 | 10.3k | if (!md) |
804 | 0 | return; |
805 | | |
806 | 10.3k | md->m_delegates.erase(src_ast); |
807 | 10.3k | md->removeOriginsWithContext(src_ast); |
808 | 10.3k | } |
809 | | |
810 | 12.0k | ClangASTImporter::MapCompleter::~MapCompleter() = default; |
811 | | |
812 | | llvm::Expected<Decl *> |
813 | 1.02M | ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { |
814 | 1.02M | if (m_std_handler) { |
815 | 1.00M | std::optional<Decl *> D = m_std_handler->Import(From); |
816 | 1.00M | if (D) { |
817 | | // Make sure we don't use this decl later to map it back to it's original |
818 | | // decl. The decl the CxxModuleHandler created has nothing to do with |
819 | | // the one from debug info, and linking those two would just cause the |
820 | | // ASTImporter to try 'updating' the module decl with the minimal one from |
821 | | // the debug info. |
822 | 588 | m_decls_to_ignore.insert(*D); |
823 | 588 | return *D; |
824 | 588 | } |
825 | 1.00M | } |
826 | | |
827 | | // Check which ASTContext this declaration originally came from. |
828 | 1.02M | DeclOrigin origin = m_main.GetDeclOrigin(From); |
829 | | |
830 | | // Prevent infinite recursion when the origin tracking contains a cycle. |
831 | 1.02M | assert(origin.decl != From && "Origin points to itself?"); |
832 | | |
833 | | // If it originally came from the target ASTContext then we can just |
834 | | // pretend that the original is the one we imported. This can happen for |
835 | | // example when inspecting a persistent declaration from the scratch |
836 | | // ASTContext (which will provide the declaration when parsing the |
837 | | // expression and then we later try to copy the declaration back to the |
838 | | // scratch ASTContext to store the result). |
839 | | // Without this check we would ask the ASTImporter to import a declaration |
840 | | // into the same ASTContext where it came from (which doesn't make a lot of |
841 | | // sense). |
842 | 1.02M | if (origin.Valid() && origin.ctx == &getToContext()2.14k ) { |
843 | 69 | RegisterImportedDecl(From, origin.decl); |
844 | 69 | return origin.decl; |
845 | 69 | } |
846 | | |
847 | | // This declaration came originally from another ASTContext. Instead of |
848 | | // copying our potentially incomplete 'From' Decl we instead go to the |
849 | | // original ASTContext and copy the original to the target. This is not |
850 | | // only faster than first completing our current decl and then copying it |
851 | | // to the target, but it also prevents that indirectly copying the same |
852 | | // declaration to the same target requires the ASTImporter to merge all |
853 | | // the different decls that appear to come from different ASTContexts (even |
854 | | // though all these different source ASTContexts just got a copy from |
855 | | // one source AST). |
856 | 1.02M | if (origin.Valid()) { |
857 | 2.07k | auto R = m_main.CopyDecl(&getToContext(), origin.decl); |
858 | 2.07k | if (R) { |
859 | 2.07k | RegisterImportedDecl(From, R); |
860 | 2.07k | return R; |
861 | 2.07k | } |
862 | 2.07k | } |
863 | | |
864 | | // If we have a forcefully completed type, try to find an actual definition |
865 | | // for it in other modules. |
866 | 1.02M | const ClangASTMetadata *md = m_main.GetDeclMetadata(From); |
867 | 1.02M | auto *td = dyn_cast<TagDecl>(From); |
868 | 1.02M | if (td && md74.7k && md->IsForcefullyCompleted()34.3k ) { |
869 | 124 | Log *log = GetLog(LLDBLog::Expressions); |
870 | 124 | LLDB_LOG(log, |
871 | 124 | "[ClangASTImporter] Searching for a complete definition of {0} in " |
872 | 124 | "other modules", |
873 | 124 | td->getName()); |
874 | 124 | Expected<DeclContext *> dc_or_err = ImportContext(td->getDeclContext()); |
875 | 124 | if (!dc_or_err) |
876 | 0 | return dc_or_err.takeError(); |
877 | 124 | Expected<DeclarationName> dn_or_err = Import(td->getDeclName()); |
878 | 124 | if (!dn_or_err) |
879 | 0 | return dn_or_err.takeError(); |
880 | 124 | DeclContext *dc = *dc_or_err; |
881 | 124 | DeclContext::lookup_result lr = dc->lookup(*dn_or_err); |
882 | 124 | for (clang::Decl *candidate : lr) { |
883 | 118 | if (candidate->getKind() == From->getKind()) { |
884 | 72 | RegisterImportedDecl(From, candidate); |
885 | 72 | m_decls_to_ignore.insert(candidate); |
886 | 72 | return candidate; |
887 | 72 | } |
888 | 118 | } |
889 | 52 | LLDB_LOG(log, "[ClangASTImporter] Complete definition not found"); |
890 | 52 | } |
891 | | |
892 | 1.02M | return ASTImporter::ImportImpl(From); |
893 | 1.02M | } |
894 | | |
895 | | void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( |
896 | 16.9k | clang::Decl *to, clang::Decl *from) { |
897 | | // We might have a forward declaration from a shared library that we |
898 | | // gave external lexical storage so that Clang asks us about the full |
899 | | // definition when it needs it. In this case the ASTImporter isn't aware |
900 | | // that the forward decl from the shared library is the actual import |
901 | | // target but would create a second declaration that would then be defined. |
902 | | // We want that 'to' is actually complete after this function so let's |
903 | | // tell the ASTImporter that 'to' was imported from 'from'. |
904 | 16.9k | MapImported(from, to); |
905 | | |
906 | 16.9k | Log *log = GetLog(LLDBLog::Expressions); |
907 | | |
908 | 16.9k | if (llvm::Error err = ImportDefinition(from)) { |
909 | 2 | LLDB_LOG_ERROR(log, std::move(err), |
910 | 2 | "[ClangASTImporter] Error during importing definition: {0}"); |
911 | 2 | return; |
912 | 2 | } |
913 | | |
914 | 16.9k | if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) { |
915 | 15.4k | if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) { |
916 | 15.4k | to_tag->setCompleteDefinition(from_tag->isCompleteDefinition()); |
917 | | |
918 | 15.4k | if (Log *log_ast = GetLog(LLDBLog::AST)) { |
919 | 4 | std::string name_string; |
920 | 4 | if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) { |
921 | 4 | llvm::raw_string_ostream name_stream(name_string); |
922 | 4 | from_named_decl->printName(name_stream); |
923 | 4 | name_stream.flush(); |
924 | 4 | } |
925 | 4 | LLDB_LOG(log_ast, "==== [ClangASTImporter][TUDecl: {0}] Imported " |
926 | 4 | "({1}Decl*){2}, named {3} (from " |
927 | 4 | "(Decl*){4})", |
928 | 4 | static_cast<void *>(to->getTranslationUnitDecl()), |
929 | 4 | from->getDeclKindName(), static_cast<void *>(to), name_string, |
930 | 4 | static_cast<void *>(from)); |
931 | | |
932 | | // Log the AST of the TU. |
933 | 4 | std::string ast_string; |
934 | 4 | llvm::raw_string_ostream ast_stream(ast_string); |
935 | 4 | to->getTranslationUnitDecl()->dump(ast_stream); |
936 | 4 | LLDB_LOG(log_ast, "{0}", ast_string); |
937 | 4 | } |
938 | 15.4k | } |
939 | 15.4k | } |
940 | | |
941 | | // If we're dealing with an Objective-C class, ensure that the inheritance |
942 | | // has been set up correctly. The ASTImporter may not do this correctly if |
943 | | // the class was originally sourced from symbols. |
944 | | |
945 | 16.9k | if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) { |
946 | 1.50k | do { |
947 | 1.50k | ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass(); |
948 | | |
949 | 1.50k | if (to_superclass) |
950 | 563 | break; // we're not going to override it if it's set |
951 | | |
952 | 941 | ObjCInterfaceDecl *from_objc_interface = |
953 | 941 | dyn_cast<ObjCInterfaceDecl>(from); |
954 | | |
955 | 941 | if (!from_objc_interface) |
956 | 0 | break; |
957 | | |
958 | 941 | ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass(); |
959 | | |
960 | 941 | if (!from_superclass) |
961 | 941 | break; |
962 | | |
963 | 0 | llvm::Expected<Decl *> imported_from_superclass_decl = |
964 | 0 | Import(from_superclass); |
965 | |
|
966 | 0 | if (!imported_from_superclass_decl) { |
967 | 0 | LLDB_LOG_ERROR(log, imported_from_superclass_decl.takeError(), |
968 | 0 | "Couldn't import decl: {0}"); |
969 | 0 | break; |
970 | 0 | } |
971 | | |
972 | 0 | ObjCInterfaceDecl *imported_from_superclass = |
973 | 0 | dyn_cast<ObjCInterfaceDecl>(*imported_from_superclass_decl); |
974 | |
|
975 | 0 | if (!imported_from_superclass) |
976 | 0 | break; |
977 | | |
978 | 0 | if (!to_objc_interface->hasDefinition()) |
979 | 0 | to_objc_interface->startDefinition(); |
980 | |
|
981 | 0 | to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo( |
982 | 0 | m_source_ctx->getObjCInterfaceType(imported_from_superclass))); |
983 | 0 | } while (false); |
984 | 1.50k | } |
985 | 16.9k | } |
986 | | |
987 | | /// Takes a CXXMethodDecl and completes the return type if necessary. This |
988 | | /// is currently only necessary for virtual functions with covariant return |
989 | | /// types where Clang's CodeGen expects that the underlying records are already |
990 | | /// completed. |
991 | | static void MaybeCompleteReturnType(ClangASTImporter &importer, |
992 | 288k | CXXMethodDecl *to_method) { |
993 | 288k | if (!to_method->isVirtual()) |
994 | 287k | return; |
995 | 1.49k | QualType return_type = to_method->getReturnType(); |
996 | 1.49k | if (!return_type->isPointerType() && !return_type->isReferenceType()1.36k ) |
997 | 1.30k | return; |
998 | | |
999 | 196 | clang::RecordDecl *rd = return_type->getPointeeType()->getAsRecordDecl(); |
1000 | 196 | if (!rd) |
1001 | 86 | return; |
1002 | 110 | if (rd->getDefinition()) |
1003 | 106 | return; |
1004 | | |
1005 | 4 | importer.CompleteTagDecl(rd); |
1006 | 4 | } |
1007 | | |
1008 | | /// Recreate a module with its parents in \p to_source and return its id. |
1009 | | static OptionalClangModuleID |
1010 | | RemapModule(OptionalClangModuleID from_id, |
1011 | | ClangExternalASTSourceCallbacks &from_source, |
1012 | 511 | ClangExternalASTSourceCallbacks &to_source) { |
1013 | 511 | if (!from_id.HasValue()) |
1014 | 232 | return {}; |
1015 | 279 | clang::Module *module = from_source.getModule(from_id.GetValue()); |
1016 | 279 | OptionalClangModuleID parent = RemapModule( |
1017 | 279 | from_source.GetIDForModule(module->Parent), from_source, to_source); |
1018 | 279 | TypeSystemClang &to_ts = to_source.GetTypeSystem(); |
1019 | 279 | return to_ts.GetOrCreateClangModule(module->Name, parent, module->IsFramework, |
1020 | 279 | module->IsExplicit); |
1021 | 511 | } |
1022 | | |
1023 | | void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, |
1024 | 1.02M | clang::Decl *to) { |
1025 | 1.02M | Log *log = GetLog(LLDBLog::Expressions); |
1026 | | |
1027 | | // Some decls shouldn't be tracked here because they were not created by |
1028 | | // copying 'from' to 'to'. Just exit early for those. |
1029 | 1.02M | if (m_decls_to_ignore.count(to)) |
1030 | 660 | return; |
1031 | | |
1032 | | // Transfer module ownership information. |
1033 | 1.02M | auto *from_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>( |
1034 | 1.02M | getFromContext().getExternalSource()); |
1035 | | // Can also be a ClangASTSourceProxy. |
1036 | 1.02M | auto *to_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>( |
1037 | 1.02M | getToContext().getExternalSource()); |
1038 | 1.02M | if (from_source && to_source649k ) { |
1039 | 232 | OptionalClangModuleID from_id(from->getOwningModuleID()); |
1040 | 232 | OptionalClangModuleID to_id = |
1041 | 232 | RemapModule(from_id, *from_source, *to_source); |
1042 | 232 | TypeSystemClang &to_ts = to_source->GetTypeSystem(); |
1043 | 232 | to_ts.SetOwningModule(to, to_id); |
1044 | 232 | } |
1045 | | |
1046 | 1.02M | lldb::user_id_t user_id = LLDB_INVALID_UID; |
1047 | 1.02M | ClangASTMetadata *metadata = m_main.GetDeclMetadata(from); |
1048 | 1.02M | if (metadata) |
1049 | 313k | user_id = metadata->GetUserID(); |
1050 | | |
1051 | 1.02M | if (log) { |
1052 | 0 | if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) { |
1053 | 0 | std::string name_string; |
1054 | 0 | llvm::raw_string_ostream name_stream(name_string); |
1055 | 0 | from_named_decl->printName(name_stream); |
1056 | 0 | name_stream.flush(); |
1057 | |
|
1058 | 0 | LLDB_LOG(log, |
1059 | 0 | " [ClangASTImporter] Imported ({0}Decl*){1}, named {2} (from " |
1060 | 0 | "(Decl*){3}), metadata {4}", |
1061 | 0 | from->getDeclKindName(), to, name_string, from, user_id); |
1062 | 0 | } else { |
1063 | 0 | LLDB_LOG(log, |
1064 | 0 | " [ClangASTImporter] Imported ({0}Decl*){1} (from " |
1065 | 0 | "(Decl*){2}), metadata {3}", |
1066 | 0 | from->getDeclKindName(), to, from, user_id); |
1067 | 0 | } |
1068 | 0 | } |
1069 | | |
1070 | 1.02M | ASTContextMetadataSP to_context_md = |
1071 | 1.02M | m_main.GetContextMetadata(&to->getASTContext()); |
1072 | 1.02M | ASTContextMetadataSP from_context_md = |
1073 | 1.02M | m_main.MaybeGetContextMetadata(m_source_ctx); |
1074 | | |
1075 | 1.02M | if (from_context_md) { |
1076 | 1.02M | DeclOrigin origin = from_context_md->getOrigin(from); |
1077 | | |
1078 | 1.02M | if (origin.Valid()) { |
1079 | 2.14k | if (origin.ctx != &to->getASTContext()) { |
1080 | 2.07k | if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID) |
1081 | 1.54k | to_context_md->setOrigin(to, origin); |
1082 | | |
1083 | 2.07k | LLDB_LOG(log, |
1084 | 2.07k | " [ClangASTImporter] Propagated origin " |
1085 | 2.07k | "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to " |
1086 | 2.07k | "(ASTContext*){3}", |
1087 | 2.07k | origin.decl, origin.ctx, &from->getASTContext(), |
1088 | 2.07k | &to->getASTContext()); |
1089 | 2.07k | } |
1090 | 1.02M | } else { |
1091 | 1.02M | if (m_new_decl_listener) |
1092 | 369k | m_new_decl_listener->NewDeclImported(from, to); |
1093 | | |
1094 | 1.02M | if (!to_context_md->hasOrigin(to) || user_id != 55.7k LLDB_INVALID_UID55.7k ) |
1095 | 984k | to_context_md->setOrigin(to, DeclOrigin(m_source_ctx, from)); |
1096 | | |
1097 | 1.02M | LLDB_LOG(log, |
1098 | 1.02M | " [ClangASTImporter] Decl has no origin information in " |
1099 | 1.02M | "(ASTContext*){0}", |
1100 | 1.02M | &from->getASTContext()); |
1101 | 1.02M | } |
1102 | | |
1103 | 1.02M | if (auto *to_namespace = dyn_cast<clang::NamespaceDecl>(to)) { |
1104 | 16.7k | auto *from_namespace = cast<clang::NamespaceDecl>(from); |
1105 | | |
1106 | 16.7k | NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps; |
1107 | | |
1108 | 16.7k | NamespaceMetaMap::iterator namespace_map_iter = |
1109 | 16.7k | namespace_maps.find(from_namespace); |
1110 | | |
1111 | 16.7k | if (namespace_map_iter != namespace_maps.end()) |
1112 | 16 | to_context_md->m_namespace_maps[to_namespace] = |
1113 | 16 | namespace_map_iter->second; |
1114 | 16.7k | } |
1115 | 1.02M | } else { |
1116 | 0 | to_context_md->setOrigin(to, DeclOrigin(m_source_ctx, from)); |
1117 | |
|
1118 | 0 | LLDB_LOG(log, |
1119 | 0 | " [ClangASTImporter] Sourced origin " |
1120 | 0 | "(Decl*){0}/(ASTContext*){1} into (ASTContext*){2}", |
1121 | 0 | from, m_source_ctx, &to->getASTContext()); |
1122 | 0 | } |
1123 | | |
1124 | 1.02M | if (auto *to_tag_decl = dyn_cast<TagDecl>(to)) { |
1125 | 76.2k | to_tag_decl->setHasExternalLexicalStorage(); |
1126 | 76.2k | to_tag_decl->getPrimaryContext()->setMustBuildLookupTable(); |
1127 | 76.2k | auto from_tag_decl = cast<TagDecl>(from); |
1128 | | |
1129 | 76.2k | LLDB_LOG( |
1130 | 76.2k | log, |
1131 | 76.2k | " [ClangASTImporter] To is a TagDecl - attributes {0}{1} [{2}->{3}]", |
1132 | 76.2k | (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""), |
1133 | 76.2k | (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""), |
1134 | 76.2k | (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"), |
1135 | 76.2k | (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete")); |
1136 | 76.2k | } |
1137 | | |
1138 | 1.02M | if (auto *to_namespace_decl = dyn_cast<NamespaceDecl>(to)) { |
1139 | 16.7k | m_main.BuildNamespaceMap(to_namespace_decl); |
1140 | 16.7k | to_namespace_decl->setHasExternalVisibleStorage(); |
1141 | 16.7k | } |
1142 | | |
1143 | 1.02M | if (auto *to_container_decl = dyn_cast<ObjCContainerDecl>(to)) { |
1144 | 2.47k | to_container_decl->setHasExternalLexicalStorage(); |
1145 | 2.47k | to_container_decl->setHasExternalVisibleStorage(); |
1146 | | |
1147 | 2.47k | if (log) { |
1148 | 0 | if (ObjCInterfaceDecl *to_interface_decl = |
1149 | 0 | llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) { |
1150 | 0 | LLDB_LOG( |
1151 | 0 | log, |
1152 | 0 | " [ClangASTImporter] To is an ObjCInterfaceDecl - attributes " |
1153 | 0 | "{0}{1}{2}", |
1154 | 0 | (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""), |
1155 | 0 | (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""), |
1156 | 0 | (to_interface_decl->hasDefinition() ? " HasDefinition" : "")); |
1157 | 0 | } else { |
1158 | 0 | LLDB_LOG( |
1159 | 0 | log, " [ClangASTImporter] To is an {0}Decl - attributes {1}{2}", |
1160 | 0 | ((Decl *)to_container_decl)->getDeclKindName(), |
1161 | 0 | (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""), |
1162 | 0 | (to_container_decl->hasExternalVisibleStorage() ? " Visible" : "")); |
1163 | 0 | } |
1164 | 0 | } |
1165 | 2.47k | } |
1166 | | |
1167 | 1.02M | if (clang::CXXMethodDecl *to_method = dyn_cast<CXXMethodDecl>(to)) |
1168 | 288k | MaybeCompleteReturnType(m_main, to_method); |
1169 | 1.02M | } |
1170 | | |
1171 | | clang::Decl * |
1172 | 379k | ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) { |
1173 | 379k | return m_main.GetDeclOrigin(To).decl; |
1174 | 379k | } |