Skip to content

Commit

Permalink
[NativePDB] Add anonymous namespaces support
Browse files Browse the repository at this point in the history
Summary:
This patch adds anonymous namespaces support to the native PDB plugin.

I had to reference from the main function variables of the types that are inside
of the anonymous namespace to include them in debug info. Without the references
they are not included. I think it's because they are static, then are visible
only in the current translation unit, so they are not needed without any
references to them.

There is also the problem case with variables of types that are nested in
template structs. For now I've left FIXME in the test because this case is not
related to the change.

Reviewers: zturner, asmith, labath, stella.stamenova, amccarth

Reviewed By: amccarth

Subscribers: zloyrobot, aprantl, teemperor, lldb-commits, leonid.mashinskiy

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D60817

llvm-svn: 358873
  • Loading branch information
Aleksandr Urakov committed Apr 22, 2019
1 parent 5c43ab3 commit ee12a75
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 11 deletions.
5 changes: 5 additions & 0 deletions lldb/lit/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
Expand Up @@ -10,11 +10,16 @@ target variable ABCVoid
target variable AC0
target variable ACNeg1

target variable AC1D
target variable AC0D
target variable ACNeg1D
target variable AD
target variable ADE

target variable AnonInt
target variable AnonABCVoid
target variable AnonABCVoidD

target modules dump ast

quit
26 changes: 24 additions & 2 deletions lldb/lit/SymbolFile/NativePDB/ast-types.cpp
Expand Up @@ -72,15 +72,18 @@ A::B::C<void> ABCVoid;
A::C<0> AC0;
A::C<-1> ACNeg1;

// FIXME: The type `D` is located now at the level of the translation unit.
// FIXME: Should be located in the namespace `A`, in the struct `C<1>`.
A::C<1>::D AC1D;

A::C<0>::D AC0D;
A::C<-1>::D ACNeg1D;
A::D AD;
A::D::E ADE;

// FIXME: Anonymous namespaces aren't working correctly.
Anonymous<int> AnonInt;
Anonymous<A::B::C<void>> AnonABCVoid;
Anonymous<A::B::C<int>>::D AnonABCVoidD;
Anonymous<A::B::C<void>>::D AnonABCVoidD;

// FIXME: Enum size isn't being correctly determined.
// FIXME: Can't read memory for variable values.
Expand All @@ -94,10 +97,14 @@ Anonymous<A::B::C<int>>::D AnonABCVoidD;
// CHECK: (A::B::C<void>) ABCVoid = (ABCSpecializationMember = 0x{{0+}})
// CHECK: (A::C<0>) AC0 = {}
// CHECK: (A::C<-1>) ACNeg1 = {}
// CHECK: (A::C<1>::D) AC1D = (ACDMember = 0, CPtr = 0x{{0+}})
// CHECK: (A::C<0>::D) AC0D = (ACDMember = 0, CPtr = 0x{{0+}})
// CHECK: (A::C<-1>::D) ACNeg1D = (ACDMember = 0, CPtr = 0x{{0+}})
// CHECK: (A::D) AD = {}
// CHECK: (A::D::E) ADE = (ADDMember = 0)
// CHECK: ((anonymous namespace)::Anonymous<int>) AnonInt = (AnonymousMember = 0)
// CHECK: ((anonymous namespace)::Anonymous<A::B::C<void>>) AnonABCVoid = (AnonymousMember = 0)
// CHECK: ((anonymous namespace)::Anonymous<A::B::C<void>>::D) AnonABCVoidD = (AnonymousDMember = 0)
// CHECK: Dumping clang ast for 1 modules.
// CHECK: TranslationUnitDecl {{.*}}
// CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition
Expand All @@ -113,6 +120,10 @@ Anonymous<A::B::C<int>>::D AnonABCVoidD;
// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'float'
// CHECK: | | `-CXXRecordDecl {{.*}} struct C<void> definition
// CHECK: | | `-FieldDecl {{.*}} ABCSpecializationMember 'void *'
// FIXME: | |-CXXRecordDecl {{.*}} struct C<1> definition
// FIXME: | | `-CXXRecordDecl {{.*}} class D definition
// FIXME: | | |-FieldDecl {{.*}} ACDMember 'int'
// FIXME: | | `-FieldDecl {{.*}} CPtr 'A::C<1> *'
// CHECK: | |-CXXRecordDecl {{.*}} struct C<0> definition
// CHECK: | | `-CXXRecordDecl {{.*}} class D definition
// CHECK: | | |-FieldDecl {{.*}} ACDMember 'int'
Expand All @@ -125,7 +136,18 @@ Anonymous<A::B::C<int>>::D AnonABCVoidD;
// CHECK: | `-CXXRecordDecl {{.*}} struct D definition
// CHECK: | `-CXXRecordDecl {{.*}} struct E definition
// CHECK: | `-FieldDecl {{.*}} ADDMember 'int'
// CHECK: |-NamespaceDecl
// CHECK: | |-CXXRecordDecl {{.*}} struct Anonymous<int> definition
// CHECK: | | `-FieldDecl {{.*}} AnonymousMember 'int'
// CHECK: | `-CXXRecordDecl {{.*}} struct Anonymous<A::B::C<void>> definition
// CHECK: | |-FieldDecl {{.*}} AnonymousMember 'int'
// CHECK: | `-CXXRecordDecl {{.*}} struct D definition
// CHECK: | `-FieldDecl {{.*}} AnonymousDMember 'int'

int main(int argc, char **argv) {
AnonInt.AnonymousMember = 1;
AnonABCVoid.AnonymousMember = 2;
AnonABCVoidD.AnonymousDMember = 3;

return 0;
}
2 changes: 1 addition & 1 deletion lldb/lit/SymbolFile/NativePDB/typedefs.cpp
Expand Up @@ -54,7 +54,7 @@ int main(int argc, char **argv) {
}


// CHECK: namespace `anonymous namespace' {
// CHECK: namespace {
// CHECK-NEXT: typedef bool AnonNamespaceTypedef;
// CHECK-NEXT: }
// CHECK-NEXT: typedef unsigned long ULongArrayTypedef[10];
Expand Down
3 changes: 2 additions & 1 deletion lldb/lit/SymbolFile/PDB/ast-restore.test
@@ -1,6 +1,7 @@
REQUIRES: system-windows, msvc
RUN: %build --compiler=msvc --nodefaultlib --output=%t.exe %S/Inputs/AstRestoreTest.cpp
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=ENUM %s
RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=ENUM %s
RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=ENUM %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=GLOBAL %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=BASE %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=CLASS %s
Expand Down
15 changes: 10 additions & 5 deletions lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
Expand Up @@ -205,6 +205,10 @@ GetNestedTagDefinition(const NestedTypeRecord &Record,
return std::move(child);
}

static bool IsAnonymousNamespaceName(llvm::StringRef name) {
return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
}

PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index)
: m_index(index), m_clang(GetClangASTContext(obj)) {
BuildParentMap();
Expand Down Expand Up @@ -256,7 +260,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
for (llvm::ms_demangle::Node *scope : scopes) {
auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);
std::string str = nii->toString();
context = m_clang.GetUniqueNamespaceDeclaration(str.c_str(), context);
context = GetOrCreateNamespaceDecl(str.c_str(), *context);
}
return {context, uname};
}
Expand Down Expand Up @@ -525,7 +529,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
// If that fails, treat it as a series of namespaces.
for (const MSVCUndecoratedNameSpecifier &spec : specs) {
std::string ns_name = spec.GetBaseName().str();
context = m_clang.GetUniqueNamespaceDeclaration(ns_name.c_str(), context);
context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context);
}
return {context, uname};
}
Expand Down Expand Up @@ -568,7 +572,7 @@ PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) {
clang::DeclContext *context = &GetTranslationUnitDecl();
while (!name_components.empty()) {
std::string ns = name_components.front()->toString();
context = m_clang.GetUniqueNamespaceDeclaration(ns.c_str(), context);
context = GetOrCreateNamespaceDecl(ns.c_str(), *context);
name_components = name_components.drop_front();
}
return context;
Expand Down Expand Up @@ -805,9 +809,10 @@ clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {
}

clang::NamespaceDecl *
PdbAstBuilder::GetOrCreateNamespaceDecl(llvm::StringRef name,
PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
clang::DeclContext &context) {
return m_clang.GetUniqueNamespaceDeclaration(name.str().c_str(), &context);
return m_clang.GetUniqueNamespaceDeclaration(
IsAnonymousNamespaceName(name) ? nullptr : name, &context);
}

clang::BlockDecl *
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
Expand Up @@ -59,8 +59,6 @@ class PdbAstBuilder {
clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
clang::DeclContext *GetParentDeclContext(PdbSymUid uid);

clang::NamespaceDecl *GetOrCreateNamespaceDecl(llvm::StringRef name,
clang::DeclContext &context);
clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id);
clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
Expand Down Expand Up @@ -114,6 +112,9 @@ class PdbAstBuilder {
clang::DeclContext *
GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym);

clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name,
clang::DeclContext &context);

void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
void ParseDeclsForSimpleContext(clang::DeclContext &context);
void ParseBlockChildren(PdbCompilandSymId block_id);
Expand Down

0 comments on commit ee12a75

Please sign in to comment.