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