Make sure we create only unique one namespace per AST when parsing the DWARF.

llvm-svn: 142005
This commit is contained in:
Greg Clayton 2011-10-14 21:34:45 +00:00
parent 1ac5da1017
commit 030a204664
4 changed files with 57 additions and 30 deletions

View File

@ -540,7 +540,6 @@ public:
clang::NamespaceDecl *
GetUniqueNamespaceDeclaration (const char *name,
const Declaration &decl,
clang::DeclContext *decl_ctx);
//------------------------------------------------------------------

View File

@ -1145,11 +1145,12 @@ DWARFDebugInfoEntry::DumpLocation
if (obj_file)
obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString();
const char *die_name = GetName (dwarf2Data, cu);
s.Printf ("CU: %s OBJFILE: %s DIE: %s (0x%x).",
cu_name ? cu_name : "<UNKNOWN>",
obj_file_name ? obj_file_name : "<UNKNOWN>",
die_name ? die_name : "<NO NAME>",
GetOffset());
s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)",
cu->GetOffset(),
GetOffset(),
die_name ? die_name : "",
cu_name ? cu_name : "<NULL>",
obj_file_name ? obj_file_name : "<NULL>");
}
//----------------------------------------------------------------------

View File

@ -3313,16 +3313,41 @@ SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_of
clang::NamespaceDecl *
SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
{
if (die->Tag() == DW_TAG_namespace)
if (die && die->Tag() == DW_TAG_namespace)
{
const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
if (namespace_name)
{
Declaration decl; // TODO: fill in the decl object
clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent(), NULL));
if (namespace_decl)
LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
// See if we already parsed this namespace DIE and associated it with a
// uniqued namespace declaration
clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
if (namespace_decl)
return namespace_decl;
else
{
const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
if (namespace_name)
{
clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (curr_cu, die, NULL);
namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log)
{
const char *object_name = m_obj_file->GetModule()->GetObjectName().GetCString();
log->Printf ("ASTContext => %p: 0x%8.8x: DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl * %p in %s/%s%s%s%s (original = %p)",
GetClangASTContext().getASTContext(),
die->GetOffset(),
namespace_name,
namespace_decl,
m_obj_file->GetFileSpec().GetDirectory().GetCString(),
m_obj_file->GetFileSpec().GetFilename().GetCString(),
object_name ? "(" : "",
object_name ? object_name : "",
object_name ? "(" : "",
namespace_decl->getOriginalNamespace());
}
if (namespace_decl)
LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
return namespace_decl;
}
}
}
return NULL;
@ -3377,17 +3402,7 @@ SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const D
return m_clang_tu_decl;
case DW_TAG_namespace:
{
const char *namespace_name = decl_ctx_die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
if (namespace_name)
{
Declaration decl; // TODO: fill in the decl object
clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (cu, decl_ctx_die, NULL));
if (namespace_decl)
LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, decl_ctx_die);
return namespace_decl;
}
}
return ResolveNamespaceDIE (cu, decl_ctx_die);
break;
case DW_TAG_structure_type:

View File

@ -4115,18 +4115,30 @@ ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
#pragma mark Namespace Declarations
NamespaceDecl *
ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *decl_ctx)
{
// TODO: Do something intelligent with the Declaration object passed in
// like maybe filling in the SourceLocation with it...
NamespaceDecl *namespace_decl = NULL;
if (name)
{
ASTContext *ast = getASTContext();
if (decl_ctx == NULL)
decl_ctx = ast->getTranslationUnitDecl();
return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name));
IdentifierInfo &identifier_info = ast->Idents.get(name);
DeclarationName decl_name (&identifier_info);
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
{
namespace_decl = dyn_cast<clang::NamespaceDecl>(*pos);
if (namespace_decl)
return namespace_decl;
}
namespace_decl = NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &identifier_info);
decl_ctx->addDecl (namespace_decl);
}
return NULL;
return namespace_decl;
}