Index: lit/SymbolFile/NativePDB/Inputs/ast-types.lldbinit =================================================================== --- lit/SymbolFile/NativePDB/Inputs/ast-types.lldbinit +++ lit/SymbolFile/NativePDB/Inputs/ast-types.lldbinit @@ -10,11 +10,16 @@ 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 Index: lit/SymbolFile/NativePDB/ast-types.cpp =================================================================== --- lit/SymbolFile/NativePDB/ast-types.cpp +++ lit/SymbolFile/NativePDB/ast-types.cpp @@ -72,15 +72,18 @@ 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 AnonInt; Anonymous> AnonABCVoid; -Anonymous>::D AnonABCVoidD; +Anonymous>::D AnonABCVoidD; // FIXME: Enum size isn't being correctly determined. // FIXME: Can't read memory for variable values. @@ -98,6 +101,9 @@ // 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) AnonInt = (AnonymousMember = 0) +// CHECK: ((anonymous namespace)::Anonymous>) AnonABCVoid = (AnonymousMember = 0) +// CHECK: ((anonymous namespace)::Anonymous>::D) AnonABCVoidD = (AnonymousDMember = 0) // CHECK: Dumping clang ast for 1 modules. // CHECK: TranslationUnitDecl {{.*}} // CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition @@ -125,7 +131,18 @@ // CHECK: | `-CXXRecordDecl {{.*}} struct D definition // CHECK: | `-CXXRecordDecl {{.*}} struct E definition // CHECK: | `-FieldDecl {{.*}} ADDMember 'int' +// CHECK: |-NamespaceDecl +// CHECK: | |-CXXRecordDecl {{.*}} struct Anonymous definition +// CHECK: | | `-FieldDecl {{.*}} AnonymousMember 'int' +// CHECK: | `-CXXRecordDecl {{.*}} struct Anonymous> 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; } Index: lit/SymbolFile/NativePDB/typedefs.cpp =================================================================== --- lit/SymbolFile/NativePDB/typedefs.cpp +++ lit/SymbolFile/NativePDB/typedefs.cpp @@ -54,7 +54,7 @@ } -// CHECK: namespace `anonymous namespace' { +// CHECK: namespace { // CHECK-NEXT: typedef bool AnonNamespaceTypedef; // CHECK-NEXT: } // CHECK-NEXT: typedef unsigned long ULongArrayTypedef[10]; Index: lit/SymbolFile/PDB/ast-restore.test =================================================================== --- lit/SymbolFile/PDB/ast-restore.test +++ 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 Index: source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp =================================================================== --- source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -205,6 +205,10 @@ 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(); @@ -256,7 +260,7 @@ for (llvm::ms_demangle::Node *scope : scopes) { auto *nii = static_cast(scope); std::string str = nii->toString(); - context = m_clang.GetUniqueNamespaceDeclaration(str.c_str(), context); + context = GetOrCreateNamespaceDecl(str.c_str(), *context); } return {context, uname}; } @@ -525,7 +529,7 @@ // 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}; } @@ -568,7 +572,7 @@ 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; @@ -807,7 +811,8 @@ clang::NamespaceDecl * PdbAstBuilder::GetOrCreateNamespaceDecl(llvm::StringRef name, clang::DeclContext &context) { - return m_clang.GetUniqueNamespaceDeclaration(name.str().c_str(), &context); + return m_clang.GetUniqueNamespaceDeclaration( + IsAnonymousNamespaceName(name) ? nullptr : name.str().c_str(), &context); } clang::BlockDecl *