summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp120
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp35
-rw-r--r--lldb/source/Symbol/ClangASTImporter.cpp42
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
OpenPOWER on IntegriCloud