diff options
Diffstat (limited to 'lldb/source/Symbol/ClangASTImporter.cpp')
-rw-r--r-- | lldb/source/Symbol/ClangASTImporter.cpp | 1952 |
1 files changed, 928 insertions, 1024 deletions
diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp index 6be10602d99..c0e8fea1f3b 100644 --- a/lldb/source/Symbol/ClangASTImporter.cpp +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -22,1192 +22,1096 @@ using namespace lldb_private; using namespace clang; -ClangASTMetrics::Counters ClangASTMetrics::global_counters = { 0, 0, 0, 0, 0, 0 }; -ClangASTMetrics::Counters ClangASTMetrics::local_counters = { 0, 0, 0, 0, 0, 0 }; - -void ClangASTMetrics::DumpCounters (Log *log, ClangASTMetrics::Counters &counters) -{ - log->Printf(" Number of visible Decl queries by name : %" PRIu64, counters.m_visible_query_count); - log->Printf(" Number of lexical Decl queries : %" PRIu64, counters.m_lexical_query_count); - log->Printf(" Number of imports initiated by LLDB : %" PRIu64, counters.m_lldb_import_count); - log->Printf(" Number of imports conducted by Clang : %" PRIu64, counters.m_clang_import_count); - log->Printf(" Number of Decls completed : %" PRIu64, counters.m_decls_completed_count); - log->Printf(" Number of records laid out : %" PRIu64, counters.m_record_layout_count); +ClangASTMetrics::Counters ClangASTMetrics::global_counters = {0, 0, 0, 0, 0, 0}; +ClangASTMetrics::Counters ClangASTMetrics::local_counters = {0, 0, 0, 0, 0, 0}; + +void ClangASTMetrics::DumpCounters(Log *log, + ClangASTMetrics::Counters &counters) { + log->Printf(" Number of visible Decl queries by name : %" PRIu64, + counters.m_visible_query_count); + log->Printf(" Number of lexical Decl queries : %" PRIu64, + counters.m_lexical_query_count); + log->Printf(" Number of imports initiated by LLDB : %" PRIu64, + counters.m_lldb_import_count); + log->Printf(" Number of imports conducted by Clang : %" PRIu64, + counters.m_clang_import_count); + log->Printf(" Number of Decls completed : %" PRIu64, + counters.m_decls_completed_count); + log->Printf(" Number of records laid out : %" PRIu64, + counters.m_record_layout_count); } -void ClangASTMetrics::DumpCounters (Log *log) -{ - if (!log) - return; - - log->Printf("== ClangASTMetrics output =="); - log->Printf("-- Global metrics --"); - DumpCounters (log, global_counters); - log->Printf("-- Local metrics --"); - DumpCounters (log, local_counters); +void ClangASTMetrics::DumpCounters(Log *log) { + if (!log) + return; + + log->Printf("== ClangASTMetrics output =="); + log->Printf("-- Global metrics --"); + DumpCounters(log, global_counters); + log->Printf("-- Local metrics --"); + DumpCounters(log, local_counters); } -clang::QualType -ClangASTImporter::CopyType (clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, - clang::QualType type) -{ - MinionSP minion_sp (GetMinion(dst_ast, src_ast)); - - if (minion_sp) - return minion_sp->Import(type); - - return QualType(); +clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast, + clang::ASTContext *src_ast, + clang::QualType type) { + MinionSP minion_sp(GetMinion(dst_ast, src_ast)); + + if (minion_sp) + return minion_sp->Import(type); + + return QualType(); } lldb::opaque_compiler_type_t -ClangASTImporter::CopyType (clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, - lldb::opaque_compiler_type_t type) -{ - return CopyType (dst_ast, src_ast, QualType::getFromOpaquePtr(type)).getAsOpaquePtr(); +ClangASTImporter::CopyType(clang::ASTContext *dst_ast, + clang::ASTContext *src_ast, + lldb::opaque_compiler_type_t type) { + return CopyType(dst_ast, src_ast, QualType::getFromOpaquePtr(type)) + .getAsOpaquePtr(); } -CompilerType -ClangASTImporter::CopyType (ClangASTContext &dst_ast, - const CompilerType &src_type) -{ - clang::ASTContext *dst_clang_ast = dst_ast.getASTContext(); - if (dst_clang_ast) - { - ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); - if (src_ast) - { - clang::ASTContext *src_clang_ast = src_ast->getASTContext(); - if (src_clang_ast) - { - lldb::opaque_compiler_type_t dst_clang_type = CopyType(dst_clang_ast, - src_clang_ast, - src_type.GetOpaqueQualType()); - - if (dst_clang_type) - return CompilerType(&dst_ast, dst_clang_type); - } - } +CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast, + const CompilerType &src_type) { + clang::ASTContext *dst_clang_ast = dst_ast.getASTContext(); + if (dst_clang_ast) { + ClangASTContext *src_ast = + llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); + if (src_ast) { + clang::ASTContext *src_clang_ast = src_ast->getASTContext(); + if (src_clang_ast) { + lldb::opaque_compiler_type_t dst_clang_type = CopyType( + dst_clang_ast, src_clang_ast, src_type.GetOpaqueQualType()); + + if (dst_clang_type) + return CompilerType(&dst_ast, dst_clang_type); + } } - return CompilerType(); + } + return CompilerType(); } -clang::Decl * -ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, - clang::Decl *decl) -{ - MinionSP minion_sp; - - minion_sp = GetMinion(dst_ast, src_ast); - - if (minion_sp) - { - clang::Decl *result = minion_sp->Import(decl); - - if (!result) - { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - if (log) - { - lldb::user_id_t user_id = LLDB_INVALID_UID; - ClangASTMetadata *metadata = GetDeclMetadata(decl); - if (metadata) - user_id = metadata->GetUserID(); - - if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) - log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%" PRIx64, - decl->getDeclKindName(), - named_decl->getNameAsString().c_str(), - user_id); - else - log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%" PRIx64, - decl->getDeclKindName(), - user_id); - } - } - - return result; +clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast, + clang::ASTContext *src_ast, + clang::Decl *decl) { + MinionSP minion_sp; + + minion_sp = GetMinion(dst_ast, src_ast); + + if (minion_sp) { + clang::Decl *result = minion_sp->Import(decl); + + if (!result) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + lldb::user_id_t user_id = LLDB_INVALID_UID; + ClangASTMetadata *metadata = GetDeclMetadata(decl); + if (metadata) + user_id = metadata->GetUserID(); + + if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) + log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s " + "'%s', metadata 0x%" PRIx64, + decl->getDeclKindName(), + named_decl->getNameAsString().c_str(), user_id); + else + log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, " + "metadata 0x%" PRIx64, + decl->getDeclKindName(), user_id); + } } - - return nullptr; + + return result; + } + + return nullptr; } -class DeclContextOverride -{ +class DeclContextOverride { private: - struct Backup - { - clang::DeclContext *decl_context; - clang::DeclContext *lexical_decl_context; - }; - - std::map<clang::Decl *, Backup> m_backups; - - void OverrideOne(clang::Decl *decl) - { - if (m_backups.find(decl) != m_backups.end()) - { - return; - } - - m_backups[decl] = { decl->getDeclContext(), decl->getLexicalDeclContext() }; - - decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl()); - decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl()); + struct Backup { + clang::DeclContext *decl_context; + clang::DeclContext *lexical_decl_context; + }; + + std::map<clang::Decl *, Backup> m_backups; + + void OverrideOne(clang::Decl *decl) { + if (m_backups.find(decl) != m_backups.end()) { + return; } - - bool ChainPassesThrough(clang::Decl *decl, - clang::DeclContext *base, - clang::DeclContext *(clang::Decl::*contextFromDecl)(), - clang::DeclContext *(clang::DeclContext::*contextFromContext)()) - { - for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); - decl_ctx; - decl_ctx = (decl_ctx->*contextFromContext)()) - { - if (decl_ctx == base) - { - return true; - } - } - - return false; + + m_backups[decl] = {decl->getDeclContext(), decl->getLexicalDeclContext()}; + + decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl()); + decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl()); + } + + bool ChainPassesThrough( + clang::Decl *decl, clang::DeclContext *base, + clang::DeclContext *(clang::Decl::*contextFromDecl)(), + clang::DeclContext *(clang::DeclContext::*contextFromContext)()) { + for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); decl_ctx; + decl_ctx = (decl_ctx->*contextFromContext)()) { + if (decl_ctx == base) { + return true; + } } - - clang::Decl *GetEscapedChild(clang::Decl *decl, clang::DeclContext *base = nullptr) - { - if (base) - { - // decl's DeclContext chains must pass through base. - - if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext, &clang::DeclContext::getParent) || - !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext, &clang::DeclContext::getLexicalParent)) - { - return decl; - } - } - else - { - base = clang::dyn_cast<clang::DeclContext>(decl); - - if (!base) - { - return nullptr; - } - } - - if (clang::DeclContext *context = clang::dyn_cast<clang::DeclContext>(decl)) - { - for (clang::Decl *decl : context->decls()) - { - if (clang::Decl *escaped_child = GetEscapedChild(decl)) - { - return escaped_child; - } - } - } - + + return false; + } + + clang::Decl *GetEscapedChild(clang::Decl *decl, + clang::DeclContext *base = nullptr) { + if (base) { + // decl's DeclContext chains must pass through base. + + if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext, + &clang::DeclContext::getParent) || + !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext, + &clang::DeclContext::getLexicalParent)) { + return decl; + } + } else { + base = clang::dyn_cast<clang::DeclContext>(decl); + + if (!base) { return nullptr; + } } - - void Override(clang::Decl *decl) - { - if (clang::Decl *escaped_child = GetEscapedChild(decl)) - { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - if (log) - log->Printf(" [ClangASTImporter] DeclContextOverride couldn't override (%sDecl*)%p - its child (%sDecl*)%p escapes", - decl->getDeclKindName(), static_cast<void*>(decl), - escaped_child->getDeclKindName(), static_cast<void*>(escaped_child)); - lldbassert(0 && "Couldn't override!"); + + if (clang::DeclContext *context = + clang::dyn_cast<clang::DeclContext>(decl)) { + for (clang::Decl *decl : context->decls()) { + if (clang::Decl *escaped_child = GetEscapedChild(decl)) { + return escaped_child; } - - OverrideOne(decl); + } } - -public: - DeclContextOverride() - { + + return nullptr; + } + + void Override(clang::Decl *decl) { + if (clang::Decl *escaped_child = GetEscapedChild(decl)) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) + log->Printf(" [ClangASTImporter] DeclContextOverride couldn't " + "override (%sDecl*)%p - its child (%sDecl*)%p escapes", + decl->getDeclKindName(), static_cast<void *>(decl), + escaped_child->getDeclKindName(), + static_cast<void *>(escaped_child)); + lldbassert(0 && "Couldn't override!"); } - - void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) - { - for (DeclContext *decl_context = decl->getLexicalDeclContext(); - decl_context; - decl_context = decl_context->getLexicalParent()) - { - DeclContext *redecl_context = decl_context->getRedeclContext(); - - if (llvm::isa<FunctionDecl>(redecl_context) && - llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) - { - for (clang::Decl *child_decl : decl_context->decls()) - { - Override(child_decl); - } - } + + OverrideOne(decl); + } + +public: + DeclContextOverride() {} + + void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) { + for (DeclContext *decl_context = decl->getLexicalDeclContext(); + decl_context; decl_context = decl_context->getLexicalParent()) { + DeclContext *redecl_context = decl_context->getRedeclContext(); + + if (llvm::isa<FunctionDecl>(redecl_context) && + llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) { + for (clang::Decl *child_decl : decl_context->decls()) { + Override(child_decl); } + } } - - ~DeclContextOverride() - { - for (const std::pair<clang::Decl *, Backup> &backup : m_backups) - { - backup.first->setDeclContext(backup.second.decl_context); - backup.first->setLexicalDeclContext(backup.second.lexical_decl_context); - } + } + + ~DeclContextOverride() { + for (const std::pair<clang::Decl *, Backup> &backup : m_backups) { + backup.first->setDeclContext(backup.second.decl_context); + backup.first->setLexicalDeclContext(backup.second.lexical_decl_context); } + } }; lldb::opaque_compiler_type_t -ClangASTImporter::DeportType (clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - lldb::opaque_compiler_type_t type) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - if (log) - log->Printf(" [ClangASTImporter] DeportType called on (%sType*)0x%llx from (ASTContext*)%p to (ASTContext*)%p", - QualType::getFromOpaquePtr(type)->getTypeClassName(), (unsigned long long)type, - static_cast<void*>(src_ctx), - static_cast<void*>(dst_ctx)); - - MinionSP minion_sp (GetMinion (dst_ctx, src_ctx)); - - if (!minion_sp) - return nullptr; - - std::set<NamedDecl *> decls_to_deport; - std::set<NamedDecl *> decls_already_deported; - - DeclContextOverride decl_context_override; - - if (const clang::TagType *tag_type = clang::QualType::getFromOpaquePtr(type)->getAs<TagType>()) - { - decl_context_override.OverrideAllDeclsFromContainingFunction(tag_type->getDecl()); - } - - minion_sp->InitDeportWorkQueues(&decls_to_deport, - &decls_already_deported); - - lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type); - - minion_sp->ExecuteDeportWorkQueues(); - - if (!result) - return nullptr; - - return result; +ClangASTImporter::DeportType(clang::ASTContext *dst_ctx, + clang::ASTContext *src_ctx, + lldb::opaque_compiler_type_t type) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); -} - -clang::Decl * -ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - clang::Decl *decl) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + if (log) + log->Printf(" [ClangASTImporter] DeportType called on (%sType*)0x%llx " + "from (ASTContext*)%p to (ASTContext*)%p", + QualType::getFromOpaquePtr(type)->getTypeClassName(), + (unsigned long long)type, static_cast<void *>(src_ctx), + static_cast<void *>(dst_ctx)); - if (log) - log->Printf(" [ClangASTImporter] DeportDecl called on (%sDecl*)%p from (ASTContext*)%p to (ASTContext*)%p", - decl->getDeclKindName(), static_cast<void*>(decl), - static_cast<void*>(src_ctx), - static_cast<void*>(dst_ctx)); + MinionSP minion_sp(GetMinion(dst_ctx, src_ctx)); - MinionSP minion_sp (GetMinion (dst_ctx, src_ctx)); + if (!minion_sp) + return nullptr; - if (!minion_sp) - return nullptr; + std::set<NamedDecl *> decls_to_deport; + std::set<NamedDecl *> decls_already_deported; - std::set<NamedDecl *> decls_to_deport; - std::set<NamedDecl *> decls_already_deported; - - DeclContextOverride decl_context_override; - - decl_context_override.OverrideAllDeclsFromContainingFunction(decl); + DeclContextOverride decl_context_override; - minion_sp->InitDeportWorkQueues(&decls_to_deport, - &decls_already_deported); + if (const clang::TagType *tag_type = + clang::QualType::getFromOpaquePtr(type)->getAs<TagType>()) { + decl_context_override.OverrideAllDeclsFromContainingFunction( + tag_type->getDecl()); + } - clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl); + minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); - minion_sp->ExecuteDeportWorkQueues(); + lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type); - if (!result) - return nullptr; + minion_sp->ExecuteDeportWorkQueues(); - if (log) - log->Printf(" [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p", - decl->getDeclKindName(), static_cast<void*>(decl), - result->getDeclKindName(), static_cast<void*>(result)); + if (!result) + return nullptr; - return result; + return result; } -bool -ClangASTImporter::CanImport(const CompilerType &type) -{ - if (!ClangUtil::IsClangType(type)) - return false; +clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, + clang::ASTContext *src_ctx, + clang::Decl *decl) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - // TODO: remove external completion BOOL - // CompleteAndFetchChildren should get the Decl out and check for the - - clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - { - const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL)) - return true; - } - } - break; + if (log) + log->Printf(" [ClangASTImporter] DeportDecl called on (%sDecl*)%p from " + "(ASTContext*)%p to (ASTContext*)%p", + decl->getDeclKindName(), static_cast<void *>(decl), + static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx)); - case clang::Type::Enum: - { - clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); - if (enum_decl) - { - if (ResolveDeclOrigin(enum_decl, NULL, NULL)) - return true; - } - } - break; + MinionSP minion_sp(GetMinion(dst_ctx, src_ctx)); - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - { - const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); - if (objc_class_type) - { - clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - // We currently can't complete objective C types through the newly added ASTContext - // because it only supports TagDecl objects right now... - if (class_interface_decl) - { - if (ResolveDeclOrigin(class_interface_decl, NULL, NULL)) - return true; - } - } - } - break; + if (!minion_sp) + return nullptr; - case clang::Type::Typedef: - return CanImport(CompilerType( - type.GetTypeSystem(), - llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr())); + std::set<NamedDecl *> decls_to_deport; + std::set<NamedDecl *> decls_already_deported; - case clang::Type::Auto: - return CanImport(CompilerType(type.GetTypeSystem(), - llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr())); + DeclContextOverride decl_context_override; - case clang::Type::Elaborated: - return CanImport(CompilerType( - type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr())); + decl_context_override.OverrideAllDeclsFromContainingFunction(decl); - case clang::Type::Paren: - return CanImport(CompilerType(type.GetTypeSystem(), - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); + minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); - default: - break; - } + clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl); - return false; -} + minion_sp->ExecuteDeportWorkQueues(); -bool -ClangASTImporter::Import(const CompilerType &type) -{ - if (!ClangUtil::IsClangType(type)) - return false; - // TODO: remove external completion BOOL - // CompleteAndFetchChildren should get the Decl out and check for the - - clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - { - const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL)) - return CompleteAndFetchChildren(qual_type); - } - } - break; + if (!result) + return nullptr; - case clang::Type::Enum: - { - clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); - if (enum_decl) - { - if (ResolveDeclOrigin(enum_decl, NULL, NULL)) - return CompleteAndFetchChildren(qual_type); - } - } - break; + if (log) + log->Printf( + " [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p", + decl->getDeclKindName(), static_cast<void *>(decl), + result->getDeclKindName(), static_cast<void *>(result)); - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - { - const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); - if (objc_class_type) - { - clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - // We currently can't complete objective C types through the newly added ASTContext - // because it only supports TagDecl objects right now... - if (class_interface_decl) - { - if (ResolveDeclOrigin(class_interface_decl, NULL, NULL)) - return CompleteAndFetchChildren(qual_type); - } - } - } - break; + return result; +} - case clang::Type::Typedef: - return Import(CompilerType( - type.GetTypeSystem(), - llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr())); +bool ClangASTImporter::CanImport(const CompilerType &type) { + if (!ClangUtil::IsClangType(type)) + return false; - case clang::Type::Auto: - return Import(CompilerType(type.GetTypeSystem(), - llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr())); + // TODO: remove external completion BOOL + // CompleteAndFetchChildren should get the Decl out and check for the - case clang::Type::Elaborated: - return Import(CompilerType(type.GetTypeSystem(), - llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr())); + clang::QualType qual_type( + ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); - case clang::Type::Paren: - return Import(CompilerType(type.GetTypeSystem(), - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL)) + return true; + } + } break; - default: - break; + case clang::Type::Enum: { + clang::EnumDecl *enum_decl = + llvm::cast<clang::EnumType>(qual_type)->getDecl(); + if (enum_decl) { + if (ResolveDeclOrigin(enum_decl, NULL, NULL)) + return true; } - return false; + } break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast<clang::ObjCObjectType>(qual_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added + // ASTContext + // because it only supports TagDecl objects right now... + if (class_interface_decl) { + if (ResolveDeclOrigin(class_interface_decl, NULL, NULL)) + return true; + } + } + } break; + + case clang::Type::Typedef: + return CanImport(CompilerType(type.GetTypeSystem(), + llvm::cast<clang::TypedefType>(qual_type) + ->getDecl() + ->getUnderlyingType() + .getAsOpaquePtr())); + + case clang::Type::Auto: + return CanImport(CompilerType(type.GetTypeSystem(), + llvm::cast<clang::AutoType>(qual_type) + ->getDeducedType() + .getAsOpaquePtr())); + + case clang::Type::Elaborated: + return CanImport(CompilerType(type.GetTypeSystem(), + llvm::cast<clang::ElaboratedType>(qual_type) + ->getNamedType() + .getAsOpaquePtr())); + + case clang::Type::Paren: + return CanImport(CompilerType( + type.GetTypeSystem(), + llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); + + default: + break; + } + + return false; } -bool -ClangASTImporter::CompleteType(const CompilerType &compiler_type) -{ - if (!CanImport(compiler_type)) - return false; - - if (Import(compiler_type)) - { - ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); - return true; +bool ClangASTImporter::Import(const CompilerType &type) { + if (!ClangUtil::IsClangType(type)) + return false; + // TODO: remove external completion BOOL + // CompleteAndFetchChildren should get the Decl out and check for the + + clang::QualType qual_type( + ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL)) + return CompleteAndFetchChildren(qual_type); } + } break; + + case clang::Type::Enum: { + clang::EnumDecl *enum_decl = + llvm::cast<clang::EnumType>(qual_type)->getDecl(); + if (enum_decl) { + if (ResolveDeclOrigin(enum_decl, NULL, NULL)) + return CompleteAndFetchChildren(qual_type); + } + } break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast<clang::ObjCObjectType>(qual_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added + // ASTContext + // because it only supports TagDecl objects right now... + if (class_interface_decl) { + if (ResolveDeclOrigin(class_interface_decl, NULL, NULL)) + return CompleteAndFetchChildren(qual_type); + } + } + } break; + + case clang::Type::Typedef: + return Import(CompilerType(type.GetTypeSystem(), + llvm::cast<clang::TypedefType>(qual_type) + ->getDecl() + ->getUnderlyingType() + .getAsOpaquePtr())); + + case clang::Type::Auto: + return Import(CompilerType(type.GetTypeSystem(), + llvm::cast<clang::AutoType>(qual_type) + ->getDeducedType() + .getAsOpaquePtr())); + + case clang::Type::Elaborated: + return Import(CompilerType(type.GetTypeSystem(), + llvm::cast<clang::ElaboratedType>(qual_type) + ->getNamedType() + .getAsOpaquePtr())); + + case clang::Type::Paren: + return Import(CompilerType( + type.GetTypeSystem(), + llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); + + default: + break; + } + return false; +} - ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false); +bool ClangASTImporter::CompleteType(const CompilerType &compiler_type) { + if (!CanImport(compiler_type)) return false; + + if (Import(compiler_type)) { + ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); + return true; + } + + ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), + false); + return false; } -bool -ClangASTImporter::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) -{ - RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find(record_decl); - bool success = false; - base_offsets.clear(); - vbase_offsets.clear(); - if (pos != m_record_decl_to_layout_map.end()) - { - bit_size = pos->second.bit_size; - alignment = pos->second.alignment; - field_offsets.swap(pos->second.field_offsets); - base_offsets.swap(pos->second.base_offsets); - vbase_offsets.swap(pos->second.vbase_offsets); - m_record_decl_to_layout_map.erase(pos); - success = true; - } - else - { - bit_size = 0; - alignment = 0; - field_offsets.clear(); - } - return success; +bool ClangASTImporter::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) { + RecordDeclToLayoutMap::iterator pos = + m_record_decl_to_layout_map.find(record_decl); + bool success = false; + base_offsets.clear(); + vbase_offsets.clear(); + if (pos != m_record_decl_to_layout_map.end()) { + bit_size = pos->second.bit_size; + alignment = pos->second.alignment; + field_offsets.swap(pos->second.field_offsets); + base_offsets.swap(pos->second.base_offsets); + vbase_offsets.swap(pos->second.vbase_offsets); + m_record_decl_to_layout_map.erase(pos); + success = true; + } else { + bit_size = 0; + alignment = 0; + field_offsets.clear(); + } + return success; } -void -ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout) -{ - m_record_decl_to_layout_map.insert(std::make_pair(decl, layout)); +void ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, + const LayoutInfo &layout) { + m_record_decl_to_layout_map.insert(std::make_pair(decl, layout)); } -void -ClangASTImporter::CompleteDecl (clang::Decl *decl) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); +void ClangASTImporter::CompleteDecl(clang::Decl *decl) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf(" [ClangASTImporter] CompleteDecl called on (%sDecl*)%p", - decl->getDeclKindName(), static_cast<void*>(decl)); - - if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) - { - if (!interface_decl->getDefinition()) - { - interface_decl->startDefinition(); - CompleteObjCInterfaceDecl(interface_decl); - } - } - else if (ObjCProtocolDecl *protocol_decl = dyn_cast<ObjCProtocolDecl>(decl)) - { - if (!protocol_decl->getDefinition()) - protocol_decl->startDefinition(); - } - else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) - { - if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined()) - { - tag_decl->startDefinition(); - CompleteTagDecl(tag_decl); - tag_decl->setCompleteDefinition(true); - } + if (log) + log->Printf(" [ClangASTImporter] CompleteDecl called on (%sDecl*)%p", + decl->getDeclKindName(), static_cast<void *>(decl)); + + if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) { + if (!interface_decl->getDefinition()) { + interface_decl->startDefinition(); + CompleteObjCInterfaceDecl(interface_decl); } - else - { - assert (0 && "CompleteDecl called on a Decl that can't be completed"); + } else if (ObjCProtocolDecl *protocol_decl = + dyn_cast<ObjCProtocolDecl>(decl)) { + if (!protocol_decl->getDefinition()) + protocol_decl->startDefinition(); + } else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) { + if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined()) { + tag_decl->startDefinition(); + CompleteTagDecl(tag_decl); + tag_decl->setCompleteDefinition(true); } + } else { + assert(0 && "CompleteDecl called on a Decl that can't be completed"); + } } -bool -ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl) -{ - ClangASTMetrics::RegisterDeclCompletion(); - - DeclOrigin decl_origin = GetDeclOrigin(decl); - - if (!decl_origin.Valid()) - return false; - - if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) - return false; - - MinionSP minion_sp (GetMinion(&decl->getASTContext(), decl_origin.ctx)); - - if (minion_sp) - minion_sp->ImportDefinitionTo(decl, decl_origin.decl); - - return true; -} +bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { + ClangASTMetrics::RegisterDeclCompletion(); -bool -ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl) -{ - ClangASTMetrics::RegisterDeclCompletion(); + DeclOrigin decl_origin = GetDeclOrigin(decl); - clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); - - if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) - return false; - - MinionSP minion_sp (GetMinion(&decl->getASTContext(), origin_ast_ctx)); - - if (minion_sp) - minion_sp->ImportDefinitionTo(decl, origin_decl); - - ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - - OriginMap &origins = context_md->m_origins; - - origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl); - - return true; + if (!decl_origin.Valid()) + return false; + + if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) + return false; + + MinionSP minion_sp(GetMinion(&decl->getASTContext(), decl_origin.ctx)); + + if (minion_sp) + minion_sp->ImportDefinitionTo(decl, decl_origin.decl); + + return true; } -bool -ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl) -{ - ClangASTMetrics::RegisterDeclCompletion(); - - DeclOrigin decl_origin = GetDeclOrigin(interface_decl); - - if (!decl_origin.Valid()) - return false; - - if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) - return false; - - MinionSP minion_sp (GetMinion(&interface_decl->getASTContext(), decl_origin.ctx)); - - if (minion_sp) - minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); +bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, + clang::TagDecl *origin_decl) { + ClangASTMetrics::RegisterDeclCompletion(); - if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass()) - RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0)); + clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); - return true; + if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) + return false; + + MinionSP minion_sp(GetMinion(&decl->getASTContext(), origin_ast_ctx)); + + if (minion_sp) + minion_sp->ImportDefinitionTo(decl, origin_decl); + + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + OriginMap &origins = context_md->m_origins; + + origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl); + + return true; } -bool -ClangASTImporter::CompleteAndFetchChildren (clang::QualType type) -{ - if (!RequireCompleteType(type)) - return false; +bool ClangASTImporter::CompleteObjCInterfaceDecl( + clang::ObjCInterfaceDecl *interface_decl) { + ClangASTMetrics::RegisterDeclCompletion(); - if (const TagType *tag_type = type->getAs<TagType>()) - { - TagDecl *tag_decl = tag_type->getDecl(); + DeclOrigin decl_origin = GetDeclOrigin(interface_decl); - DeclOrigin decl_origin = GetDeclOrigin(tag_decl); + if (!decl_origin.Valid()) + return false; - if (!decl_origin.Valid()) - return false; + if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) + return false; - MinionSP minion_sp (GetMinion(&tag_decl->getASTContext(), decl_origin.ctx)); + MinionSP minion_sp( + GetMinion(&interface_decl->getASTContext(), decl_origin.ctx)); - TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl); + if (minion_sp) + minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); - for (Decl *origin_child_decl : origin_tag_decl->decls()) - { - minion_sp->Import(origin_child_decl); - } + if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass()) + RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0)); - if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) - { - record_decl->setHasLoadedFieldsFromExternalStorage(true); - } + return true; +} - return true; - } +bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { + if (!RequireCompleteType(type)) + return false; - if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) - { - if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) - { - DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl); + if (const TagType *tag_type = type->getAs<TagType>()) { + TagDecl *tag_decl = tag_type->getDecl(); - if (!decl_origin.Valid()) - return false; + DeclOrigin decl_origin = GetDeclOrigin(tag_decl); - MinionSP minion_sp (GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx)); + if (!decl_origin.Valid()) + return false; - ObjCInterfaceDecl *origin_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl); + MinionSP minion_sp(GetMinion(&tag_decl->getASTContext(), decl_origin.ctx)); - for (Decl *origin_child_decl : origin_interface_decl->decls()) - { - minion_sp->Import(origin_child_decl); - } + TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl); - return true; - } - else - { - return false; - } + for (Decl *origin_child_decl : origin_tag_decl->decls()) { + minion_sp->Import(origin_child_decl); } - + + if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) { + record_decl->setHasLoadedFieldsFromExternalStorage(true); + } + return true; -} + } + if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) { + if (ObjCInterfaceDecl *objc_interface_decl = + objc_object_type->getInterface()) { + DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl); -bool -ClangASTImporter::RequireCompleteType (clang::QualType type) -{ - if (type.isNull()) + if (!decl_origin.Valid()) return false; - - if (const TagType *tag_type = type->getAs<TagType>()) - { - TagDecl *tag_decl = tag_type->getDecl(); - if (tag_decl->getDefinition() || tag_decl->isBeingDefined()) - return true; + MinionSP minion_sp( + GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx)); - return CompleteTagDecl(tag_decl); - } - if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) - { - if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) - return CompleteObjCInterfaceDecl(objc_interface_decl); - else - return false; - } - if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) - { - return RequireCompleteType(array_type->getElementType()); - } - if (const AtomicType *atomic_type = type->getAs<AtomicType>()) - { - return RequireCompleteType(atomic_type->getPointeeType()); + ObjCInterfaceDecl *origin_interface_decl = + llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl); + + for (Decl *origin_child_decl : origin_interface_decl->decls()) { + minion_sp->Import(origin_child_decl); + } + + return true; + } else { + return false; } - - return true; -} + } -ClangASTMetadata * -ClangASTImporter::GetDeclMetadata (const clang::Decl *decl) -{ - DeclOrigin decl_origin = GetDeclOrigin(decl); - - if (decl_origin.Valid()) - return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl); - else - return ClangASTContext::GetMetadata(&decl->getASTContext(), decl); + return true; } -ClangASTImporter::DeclOrigin -ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) -{ - ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - - OriginMap &origins = context_md->m_origins; - - OriginMap::iterator iter = origins.find(decl); - - if (iter != origins.end()) - return iter->second; +bool ClangASTImporter::RequireCompleteType(clang::QualType type) { + if (type.isNull()) + return false; + + if (const TagType *tag_type = type->getAs<TagType>()) { + TagDecl *tag_decl = tag_type->getDecl(); + + if (tag_decl->getDefinition() || tag_decl->isBeingDefined()) + return true; + + return CompleteTagDecl(tag_decl); + } + if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) { + if (ObjCInterfaceDecl *objc_interface_decl = + objc_object_type->getInterface()) + return CompleteObjCInterfaceDecl(objc_interface_decl); else - return DeclOrigin(); + return false; + } + if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) { + return RequireCompleteType(array_type->getElementType()); + } + if (const AtomicType *atomic_type = type->getAs<AtomicType>()) { + return RequireCompleteType(atomic_type->getPointeeType()); + } + + return true; } -void -ClangASTImporter::SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl) -{ - ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - - OriginMap &origins = context_md->m_origins; - - OriginMap::iterator iter = origins.find(decl); - - if (iter != origins.end()) - { - iter->second.decl = original_decl; - iter->second.ctx = &original_decl->getASTContext(); - } - else - { - origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); - } +ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) { + DeclOrigin decl_origin = GetDeclOrigin(decl); + + if (decl_origin.Valid()) + return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl); + else + return ClangASTContext::GetMetadata(&decl->getASTContext(), decl); } -void -ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, - NamespaceMapSP &namespace_map) -{ - ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - - context_md->m_namespace_maps[decl] = namespace_map; +ClangASTImporter::DeclOrigin +ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) { + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + OriginMap &origins = context_md->m_origins; + + OriginMap::iterator iter = origins.find(decl); + + if (iter != origins.end()) + return iter->second; + else + return DeclOrigin(); } -ClangASTImporter::NamespaceMapSP -ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) -{ - ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - - NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps; - - NamespaceMetaMap::iterator iter = namespace_maps.find(decl); - - if (iter != namespace_maps.end()) - return iter->second; - else - return NamespaceMapSP(); +void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl, + clang::Decl *original_decl) { + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + OriginMap &origins = context_md->m_origins; + + OriginMap::iterator iter = origins.find(decl); + + if (iter != origins.end()) { + iter->second.decl = original_decl; + iter->second.ctx = &original_decl->getASTContext(); + } else { + origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); + } } -void -ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) -{ - assert (decl); - ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - - const DeclContext *parent_context = decl->getDeclContext(); - const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context); - NamespaceMapSP parent_map; - - if (parent_namespace) - parent_map = GetNamespaceMap(parent_namespace); - - NamespaceMapSP new_map; - - new_map.reset(new NamespaceMap); - - if (context_md->m_map_completer) - { - std::string namespace_string = decl->getDeclName().getAsString(); - - context_md->m_map_completer->CompleteNamespaceMap (new_map, ConstString(namespace_string.c_str()), parent_map); - } - - context_md->m_namespace_maps[decl] = new_map; +void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, + NamespaceMapSP &namespace_map) { + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + context_md->m_namespace_maps[decl] = namespace_map; } -void -ClangASTImporter::ForgetDestination (clang::ASTContext *dst_ast) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); +ClangASTImporter::NamespaceMapSP +ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) { + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - if (log) - log->Printf(" [ClangASTImporter] Forgetting destination (ASTContext*)%p", - static_cast<void*>(dst_ast)); + NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps; + + NamespaceMetaMap::iterator iter = namespace_maps.find(decl); - m_metadata_map.erase(dst_ast); + if (iter != namespace_maps.end()) + return iter->second; + else + return NamespaceMapSP(); } -void -ClangASTImporter::ForgetSource (clang::ASTContext *dst_ast, clang::ASTContext *src_ast) -{ - ASTContextMetadataSP md = MaybeGetContextMetadata (dst_ast); +void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) { + assert(decl); + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const DeclContext *parent_context = decl->getDeclContext(); + const NamespaceDecl *parent_namespace = + dyn_cast<NamespaceDecl>(parent_context); + NamespaceMapSP parent_map; - if (log) - log->Printf(" [ClangASTImporter] Forgetting source->dest (ASTContext*)%p->(ASTContext*)%p", - static_cast<void*>(src_ast), static_cast<void*>(dst_ast)); + if (parent_namespace) + parent_map = GetNamespaceMap(parent_namespace); - if (!md) - return; + NamespaceMapSP new_map; - md->m_minions.erase(src_ast); + new_map.reset(new NamespaceMap); - for (OriginMap::iterator iter = md->m_origins.begin(); - iter != md->m_origins.end(); - ) - { - if (iter->second.ctx == src_ast) - md->m_origins.erase(iter++); - else - ++iter; - } + if (context_md->m_map_completer) { + std::string namespace_string = decl->getDeclName().getAsString(); + + context_md->m_map_completer->CompleteNamespaceMap( + new_map, ConstString(namespace_string.c_str()), parent_map); + } + + context_md->m_namespace_maps[decl] = new_map; } -ClangASTImporter::MapCompleter::~MapCompleter () -{ - return; +void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) + log->Printf(" [ClangASTImporter] Forgetting destination (ASTContext*)%p", + static_cast<void *>(dst_ast)); + + m_metadata_map.erase(dst_ast); } -void -ClangASTImporter::Minion::InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport, - std::set<clang::NamedDecl *> *decls_already_deported) -{ - assert(!m_decls_to_deport); - assert(!m_decls_already_deported); - - m_decls_to_deport = decls_to_deport; - m_decls_already_deported = decls_already_deported; +void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, + clang::ASTContext *src_ast) { + ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) + log->Printf(" [ClangASTImporter] Forgetting source->dest " + "(ASTContext*)%p->(ASTContext*)%p", + static_cast<void *>(src_ast), static_cast<void *>(dst_ast)); + + if (!md) + return; + + md->m_minions.erase(src_ast); + + for (OriginMap::iterator iter = md->m_origins.begin(); + iter != md->m_origins.end();) { + if (iter->second.ctx == src_ast) + md->m_origins.erase(iter++); + else + ++iter; + } } -void -ClangASTImporter::Minion::ExecuteDeportWorkQueues () -{ - assert(m_decls_to_deport); - assert(m_decls_already_deported); - - ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&getToContext()); - - while (!m_decls_to_deport->empty()) - { - NamedDecl *decl = *m_decls_to_deport->begin(); - - m_decls_already_deported->insert(decl); - m_decls_to_deport->erase(decl); - - DeclOrigin &origin = to_context_md->m_origins[decl]; - UNUSED_IF_ASSERT_DISABLED(origin); - - assert (origin.ctx == m_source_ctx); // otherwise we should never have added this - // because it doesn't need to be deported - - Decl *original_decl = to_context_md->m_origins[decl].decl; - - ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl); - - if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) - { - if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) - { - if (original_tag_decl->isCompleteDefinition()) - { - ImportDefinitionTo(tag_decl, original_tag_decl); - tag_decl->setCompleteDefinition(true); - } - } - - tag_decl->setHasExternalLexicalStorage(false); - tag_decl->setHasExternalVisibleStorage(false); - } - else if (ObjCContainerDecl *container_decl = dyn_cast<ObjCContainerDecl>(decl)) - { - container_decl->setHasExternalLexicalStorage(false); - container_decl->setHasExternalVisibleStorage(false); - } - - to_context_md->m_origins.erase(decl); - } - - m_decls_to_deport = nullptr; - m_decls_already_deported = nullptr; +ClangASTImporter::MapCompleter::~MapCompleter() { return; } + +void ClangASTImporter::Minion::InitDeportWorkQueues( + std::set<clang::NamedDecl *> *decls_to_deport, + std::set<clang::NamedDecl *> *decls_already_deported) { + assert(!m_decls_to_deport); + assert(!m_decls_already_deported); + + m_decls_to_deport = decls_to_deport; + m_decls_already_deported = decls_already_deported; } -void -ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from) -{ - ASTImporter::Imported(from, to); +void ClangASTImporter::Minion::ExecuteDeportWorkQueues() { + assert(m_decls_to_deport); + assert(m_decls_already_deported); - /* - if (to_objc_interface) - to_objc_interface->startDefinition(); - - CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to); - - if (to_cxx_record) - to_cxx_record->startDefinition(); - */ - - ImportDefinition(from); - - if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) - { - if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) - { - to_tag->setCompleteDefinition(from_tag->isCompleteDefinition()); - } - } - - // If we're dealing with an Objective-C class, ensure that the inheritance has - // been set up correctly. The ASTImporter may not do this correctly if the - // class was originally sourced from symbols. - - if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) - { - do - { - ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass(); - - if (to_superclass) - break; // we're not going to override it if it's set - - ObjCInterfaceDecl *from_objc_interface = dyn_cast<ObjCInterfaceDecl>(from); - - if (!from_objc_interface) - break; - - ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass(); - - if (!from_superclass) - break; - - Decl *imported_from_superclass_decl = Import(from_superclass); - - if (!imported_from_superclass_decl) - break; - - ObjCInterfaceDecl *imported_from_superclass = dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl); - - if (!imported_from_superclass) - break; - - if (!to_objc_interface->hasDefinition()) - to_objc_interface->startDefinition(); - - to_objc_interface->setSuperClass( - m_source_ctx->getTrivialTypeSourceInfo(m_source_ctx->getObjCInterfaceType(imported_from_superclass))); + ASTContextMetadataSP to_context_md = + m_master.GetContextMetadata(&getToContext()); + + while (!m_decls_to_deport->empty()) { + NamedDecl *decl = *m_decls_to_deport->begin(); + + m_decls_already_deported->insert(decl); + m_decls_to_deport->erase(decl); + + DeclOrigin &origin = to_context_md->m_origins[decl]; + UNUSED_IF_ASSERT_DISABLED(origin); + + assert(origin.ctx == + m_source_ctx); // otherwise we should never have added this + // because it doesn't need to be deported + + Decl *original_decl = to_context_md->m_origins[decl].decl; + + ClangASTContext::GetCompleteDecl(m_source_ctx, original_decl); + + if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) { + if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) { + if (original_tag_decl->isCompleteDefinition()) { + ImportDefinitionTo(tag_decl, original_tag_decl); + tag_decl->setCompleteDefinition(true); } - while (0); + } + + tag_decl->setHasExternalLexicalStorage(false); + tag_decl->setHasExternalVisibleStorage(false); + } else if (ObjCContainerDecl *container_decl = + dyn_cast<ObjCContainerDecl>(decl)) { + container_decl->setHasExternalLexicalStorage(false); + container_decl->setHasExternalVisibleStorage(false); } + + to_context_md->m_origins.erase(decl); + } + + m_decls_to_deport = nullptr; + m_decls_already_deported = nullptr; } -clang::Decl * -ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to) -{ - ClangASTMetrics::RegisterClangImport(); +void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, + clang::Decl *from) { + ASTImporter::Imported(from, to); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + /* + if (to_objc_interface) + to_objc_interface->startDefinition(); - lldb::user_id_t user_id = LLDB_INVALID_UID; - ClangASTMetadata *metadata = m_master.GetDeclMetadata(from); - if (metadata) - user_id = metadata->GetUserID(); - - if (log) - { - if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) - { - std::string name_string; - llvm::raw_string_ostream name_stream(name_string); - from_named_decl->printName(name_stream); - name_stream.flush(); - - log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64, - from->getDeclKindName(), static_cast<void*>(to), - name_string.c_str(), static_cast<void*>(from), - user_id); - } - else - { - log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64, - from->getDeclKindName(), static_cast<void*>(to), - static_cast<void*>(from), user_id); - } + CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to); + + if (to_cxx_record) + to_cxx_record->startDefinition(); + */ + + ImportDefinition(from); + + if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) { + if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) { + to_tag->setCompleteDefinition(from_tag->isCompleteDefinition()); } + } - ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&to->getASTContext()); - ASTContextMetadataSP from_context_md = m_master.MaybeGetContextMetadata(m_source_ctx); - - if (from_context_md) - { - OriginMap &origins = from_context_md->m_origins; - - OriginMap::iterator origin_iter = origins.find(from); - - if (origin_iter != origins.end()) - { - if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || - user_id != LLDB_INVALID_UID) - { - if (origin_iter->second.ctx != &to->getASTContext()) - to_context_md->m_origins[to] = origin_iter->second; - } - - MinionSP direct_completer = m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx); - - if (direct_completer.get() != this) - direct_completer->ASTImporter::Imported(origin_iter->second.decl, to); - - if (log) - log->Printf(" [ClangASTImporter] Propagated origin (Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to (ASTContext*)%p", - static_cast<void*>(origin_iter->second.decl), - static_cast<void*>(origin_iter->second.ctx), - static_cast<void*>(&from->getASTContext()), - static_cast<void*>(&to->getASTContext())); - } - else - { - if (m_decls_to_deport && m_decls_already_deported) - { - if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) - { - RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from); - if (from_record_decl == nullptr || from_record_decl->isInjectedClassName() == false) - { - NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to); - - if (!m_decls_already_deported->count(to_named_decl)) - m_decls_to_deport->insert(to_named_decl); - } - } - } - - if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || - user_id != LLDB_INVALID_UID) - { - to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from); - } - - if (log) - log->Printf(" [ClangASTImporter] Decl has no origin information in (ASTContext*)%p", - static_cast<void*>(&from->getASTContext())); - } + // If we're dealing with an Objective-C class, ensure that the inheritance has + // been set up correctly. The ASTImporter may not do this correctly if the + // class was originally sourced from symbols. - if (clang::NamespaceDecl *to_namespace = dyn_cast<clang::NamespaceDecl>(to)) - { - clang::NamespaceDecl *from_namespace = dyn_cast<clang::NamespaceDecl>(from); + if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) { + do { + ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass(); - NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps; + if (to_superclass) + break; // we're not going to override it if it's set - NamespaceMetaMap::iterator namespace_map_iter = namespace_maps.find(from_namespace); + ObjCInterfaceDecl *from_objc_interface = + dyn_cast<ObjCInterfaceDecl>(from); - if (namespace_map_iter != namespace_maps.end()) - to_context_md->m_namespace_maps[to_namespace] = namespace_map_iter->second; - } + if (!from_objc_interface) + break; + + ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass(); + + if (!from_superclass) + break; + + Decl *imported_from_superclass_decl = Import(from_superclass); + + if (!imported_from_superclass_decl) + break; + + ObjCInterfaceDecl *imported_from_superclass = + dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl); + + if (!imported_from_superclass) + break; + + if (!to_objc_interface->hasDefinition()) + to_objc_interface->startDefinition(); + + to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo( + m_source_ctx->getObjCInterfaceType(imported_from_superclass))); + } while (0); + } +} + +clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, + clang::Decl *to) { + ClangASTMetrics::RegisterClangImport(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + lldb::user_id_t user_id = LLDB_INVALID_UID; + ClangASTMetadata *metadata = m_master.GetDeclMetadata(from); + if (metadata) + user_id = metadata->GetUserID(); + + if (log) { + if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) { + std::string name_string; + llvm::raw_string_ostream name_stream(name_string); + from_named_decl->printName(name_stream); + name_stream.flush(); + + log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from " + "(Decl*)%p), metadata 0x%" PRIx64, + from->getDeclKindName(), static_cast<void *>(to), + name_string.c_str(), static_cast<void *>(from), user_id); + } else { + log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from " + "(Decl*)%p), metadata 0x%" PRIx64, + from->getDeclKindName(), static_cast<void *>(to), + static_cast<void *>(from), user_id); } - else - { - to_context_md->m_origins[to] = DeclOrigin (m_source_ctx, from); - - if (log) - log->Printf(" [ClangASTImporter] Sourced origin (Decl*)%p/(ASTContext*)%p into (ASTContext*)%p", - static_cast<void*>(from), - static_cast<void*>(m_source_ctx), - static_cast<void*>(&to->getASTContext())); + } + + ASTContextMetadataSP to_context_md = + m_master.GetContextMetadata(&to->getASTContext()); + ASTContextMetadataSP from_context_md = + m_master.MaybeGetContextMetadata(m_source_ctx); + + if (from_context_md) { + OriginMap &origins = from_context_md->m_origins; + + OriginMap::iterator origin_iter = origins.find(from); + + if (origin_iter != origins.end()) { + if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || + user_id != LLDB_INVALID_UID) { + if (origin_iter->second.ctx != &to->getASTContext()) + to_context_md->m_origins[to] = origin_iter->second; + } + + MinionSP direct_completer = + m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx); + + if (direct_completer.get() != this) + direct_completer->ASTImporter::Imported(origin_iter->second.decl, to); + + if (log) + log->Printf(" [ClangASTImporter] Propagated origin " + "(Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to " + "(ASTContext*)%p", + static_cast<void *>(origin_iter->second.decl), + static_cast<void *>(origin_iter->second.ctx), + static_cast<void *>(&from->getASTContext()), + static_cast<void *>(&to->getASTContext())); + } else { + if (m_decls_to_deport && m_decls_already_deported) { + if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) { + RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from); + if (from_record_decl == nullptr || + from_record_decl->isInjectedClassName() == false) { + NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to); + + if (!m_decls_already_deported->count(to_named_decl)) + m_decls_to_deport->insert(to_named_decl); + } + } + } + + if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || + user_id != LLDB_INVALID_UID) { + to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from); + } + + if (log) + log->Printf(" [ClangASTImporter] Decl has no origin information in " + "(ASTContext*)%p", + static_cast<void *>(&from->getASTContext())); } - if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) - { - TagDecl *to_tag_decl = dyn_cast<TagDecl>(to); + if (clang::NamespaceDecl *to_namespace = + dyn_cast<clang::NamespaceDecl>(to)) { + clang::NamespaceDecl *from_namespace = + dyn_cast<clang::NamespaceDecl>(from); - to_tag_decl->setHasExternalLexicalStorage(); - to_tag_decl->setMustBuildLookupTable(); + NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps; - if (log) - log->Printf(" [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]", - (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""), - (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""), - (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"), - (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete")); + NamespaceMetaMap::iterator namespace_map_iter = + namespace_maps.find(from_namespace); + + if (namespace_map_iter != namespace_maps.end()) + to_context_md->m_namespace_maps[to_namespace] = + namespace_map_iter->second; } + } else { + to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from); - if (isa<NamespaceDecl>(from)) - { - NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to); + if (log) + log->Printf(" [ClangASTImporter] Sourced origin " + "(Decl*)%p/(ASTContext*)%p into (ASTContext*)%p", + static_cast<void *>(from), static_cast<void *>(m_source_ctx), + static_cast<void *>(&to->getASTContext())); + } - m_master.BuildNamespaceMap(to_namespace_decl); + if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) { + TagDecl *to_tag_decl = dyn_cast<TagDecl>(to); - to_namespace_decl->setHasExternalVisibleStorage(); - } + to_tag_decl->setHasExternalLexicalStorage(); + to_tag_decl->setMustBuildLookupTable(); - if (isa<ObjCContainerDecl>(from)) - { - ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to); - - to_container_decl->setHasExternalLexicalStorage(); - to_container_decl->setHasExternalVisibleStorage(); - - /*to_interface_decl->setExternallyCompleted();*/ - - if (log) - { - if (ObjCInterfaceDecl *to_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) - { - log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s", - (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""), - (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""), - (to_interface_decl->hasDefinition() ? " HasDefinition" : "")); - } - else - { - log->Printf(" [ClangASTImporter] To is an %sDecl - attributes %s%s", - ((Decl*)to_container_decl)->getDeclKindName(), - (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""), - (to_container_decl->hasExternalVisibleStorage() ? " Visible" : "")); - } - } + if (log) + log->Printf( + " [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]", + (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""), + (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""), + (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"), + (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete")); + } + + if (isa<NamespaceDecl>(from)) { + NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to); + + m_master.BuildNamespaceMap(to_namespace_decl); + + to_namespace_decl->setHasExternalVisibleStorage(); + } + + if (isa<ObjCContainerDecl>(from)) { + ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to); + + to_container_decl->setHasExternalLexicalStorage(); + to_container_decl->setHasExternalVisibleStorage(); + + /*to_interface_decl->setExternallyCompleted();*/ + + if (log) { + if (ObjCInterfaceDecl *to_interface_decl = + llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) { + log->Printf( + " [ClangASTImporter] To is an ObjCInterfaceDecl - attributes " + "%s%s%s", + (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""), + (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""), + (to_interface_decl->hasDefinition() ? " HasDefinition" : "")); + } else { + log->Printf( + " [ClangASTImporter] To is an %sDecl - attributes %s%s", + ((Decl *)to_container_decl)->getDeclKindName(), + (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""), + (to_container_decl->hasExternalVisibleStorage() ? " Visible" : "")); + } } + } - return clang::ASTImporter::Imported(from, to); + return clang::ASTImporter::Imported(from, to); } -clang::Decl *ClangASTImporter::Minion::GetOriginalDecl (clang::Decl *To) -{ - ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&To->getASTContext()); - - if (!to_context_md) - return nullptr; - - OriginMap::iterator iter = to_context_md->m_origins.find(To); - - if (iter == to_context_md->m_origins.end()) - return nullptr; - - return const_cast<clang::Decl*>(iter->second.decl); +clang::Decl *ClangASTImporter::Minion::GetOriginalDecl(clang::Decl *To) { + ASTContextMetadataSP to_context_md = + m_master.GetContextMetadata(&To->getASTContext()); + + if (!to_context_md) + return nullptr; + + OriginMap::iterator iter = to_context_md->m_origins.find(To); + + if (iter == to_context_md->m_origins.end()) + return nullptr; + + return const_cast<clang::Decl *>(iter->second.decl); } |