diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 120 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 35 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTImporter.cpp | 42 |
3 files changed, 166 insertions, 31 deletions
diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 552c54575a7..9831070c9be 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -149,15 +149,127 @@ ClangASTSource::CompleteType (TagDecl *tag_decl) { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + static unsigned int invocation_id = 0; + unsigned int current_id = invocation_id++; + if (log) { - log->Printf(" [CompleteTagDecl] on (ASTContext*)%p Completing a TagDecl named %s", m_ast_context, tag_decl->getName().str().c_str()); - log->Printf(" [CTD] Before:"); + log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing a TagDecl named %s", + invocation_id, + m_ast_context, + tag_decl->getName().str().c_str()); + + log->Printf(" CTD[%u] Before:", current_id); ASTDumper dumper((Decl*)tag_decl); dumper.ToLog(log, " [CTD] "); } - m_ast_importer->CompleteTagDecl (tag_decl); + if (!m_ast_importer->CompleteTagDecl (tag_decl)) + { + // We couldn't complete the type. Maybe there's a definition + // somewhere else that can be completed. + + if (log) + log->Printf(" CTD[%u] Type could not be completed in the module in which it was first found.", current_id); + + bool found = false; + + DeclContext *decl_ctx = tag_decl->getDeclContext(); + + if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx)) + { + ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context); + + if (log && log->GetVerbose()) + log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)", + current_id, + namespace_map.get(), + (int)namespace_map->size()); + + if (!namespace_map) + return; + + for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); + i != e && !found; + ++i) + { + if (log) + log->Printf(" CTD[%u] Searching namespace %s in module %s", + current_id, + i->second.GetNamespaceDecl()->getNameAsString().c_str(), + i->first->GetFileSpec().GetFilename().GetCString()); + + TypeList types; + + SymbolContext null_sc; + ConstString name(tag_decl->getName().str().c_str()); + + i->first->FindTypes(null_sc, name, &i->second, true, UINT32_MAX, types); + + for (uint32_t ti = 0, te = types.GetSize(); + ti != te && !found; + ++ti) + { + lldb::TypeSP type = types.GetTypeAtIndex(ti); + + if (!type) + continue; + + lldb::clang_type_t opaque_type = type->GetClangFullType(); + + if (!opaque_type) + continue; + + const TagType *tag_type = dyn_cast<TagType>(QualType::getFromOpaquePtr(opaque_type).getTypePtr()); + + if (!tag_type) + continue; + + TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl()); + + if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl)) + found = true; + } + } + } + else + { + TypeList types; + + SymbolContext null_sc; + ConstString name(tag_decl->getName().str().c_str()); + ClangNamespaceDecl namespace_decl; + + ModuleList &module_list = m_target->GetImages(); + + module_list.FindTypes(null_sc, name, true, UINT32_MAX, types); + + for (uint32_t ti = 0, te = types.GetSize(); + ti != te && !found; + ++ti) + { + lldb::TypeSP type = types.GetTypeAtIndex(ti); + + if (!type) + continue; + + lldb::clang_type_t opaque_type = type->GetClangFullType(); + + if (!opaque_type) + continue; + + const TagType *tag_type = dyn_cast<TagType>(QualType::getFromOpaquePtr(opaque_type).getTypePtr()); + + if (!tag_type) + continue; + + TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl()); + + if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl)) + found = true; + } + } + } if (log) { @@ -249,7 +361,7 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context, external_source->CompleteType (original_tag_decl); } - DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl); + const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl); if (!original_decl_context) return ELR_Failure; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 196bec836aa..e0abf9a0f44 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -4548,22 +4548,25 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, unique_ast_entry); - if (die->HasChildren() == false && is_forward_declaration == false) - { - // No children for this struct/union/class, lets finish it - ast.StartTagDeclarationDefinition (clang_type); - ast.CompleteTagDeclarationDefinition (clang_type); - } - else if (clang_type_was_created) - { - // Leave this as a forward declaration until we need - // to know the details of the type. lldb_private::Type - // will automatically call the SymbolFile virtual function - // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" - // When the definition needs to be defined. - m_forward_decl_die_to_clang_type[die] = clang_type; - m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; - ClangASTContext::SetHasExternalStorage (clang_type, true); + if (!is_forward_declaration) + { + if (die->HasChildren() == false) + { + // No children for this struct/union/class, lets finish it + ast.StartTagDeclarationDefinition (clang_type); + ast.CompleteTagDeclarationDefinition (clang_type); + } + else if (clang_type_was_created) + { + // Leave this as a forward declaration until we need + // to know the details of the type. lldb_private::Type + // will automatically call the SymbolFile virtual function + // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" + // When the definition needs to be defined. + m_forward_decl_die_to_clang_type[die] = clang_type; + m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; + ClangASTContext::SetHasExternalStorage (clang_type, true); + } } } diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp index eb65c9d03ee..3bbd9c6af35 100644 --- a/lldb/source/Symbol/ClangASTImporter.cpp +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -95,28 +95,48 @@ ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx, return result; } -void +bool ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl) -{ - lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - +{ DeclOrigin decl_origin = GetDeclOrigin(decl); if (!decl_origin.Valid()) - return; + return false; if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) - return; + return false; MinionSP minion_sp (GetMinion(&decl->getASTContext(), decl_origin.ctx)); if (minion_sp) minion_sp->ImportDefinition(decl_origin.decl); - return; + return true; } -void +bool +ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_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->ImportDefinition(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::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl) { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -124,17 +144,17 @@ ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface DeclOrigin decl_origin = GetDeclOrigin(interface_decl); if (!decl_origin.Valid()) - return; + return false; if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) - return; + return false; MinionSP minion_sp (GetMinion(&interface_decl->getASTContext(), decl_origin.ctx)); if (minion_sp) minion_sp->ImportDefinition(decl_origin.decl); - return; + return true; } ClangASTImporter::DeclOrigin |