[NativePDB] Add anonymous namespaces support
authorAleksandr Urakov <aleksandr.urakov@jetbrains.com>
Mon, 22 Apr 2019 07:14:40 +0000 (07:14 +0000)
committerAleksandr Urakov <aleksandr.urakov@jetbrains.com>
Mon, 22 Apr 2019 07:14:40 +0000 (07:14 +0000)
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

lldb/lit/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
lldb/lit/SymbolFile/NativePDB/ast-types.cpp
lldb/lit/SymbolFile/NativePDB/typedefs.cpp
lldb/lit/SymbolFile/PDB/ast-restore.test
lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h

index 3c0cf6d3cdfdd3e96b67f844b62ddf8ebc0d74ea..b317c4ab3430c629b6375608282c858bd1f57f48 100644 (file)
@@ -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
index 224c7c26e84657f1b7f5594712c9f636e730a251..9d4ac139f59276fad43a218731bf88eaff78d49f 100644 (file)
@@ -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.
@@ -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
@@ -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'
@@ -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;
 }
index 738fbe615d90e30181d897804a5538d5ab970e6d..e303a4f43636deb8cf4895d0dc331962beda0552 100644 (file)
@@ -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];
index 2158fc1b3d449bbda60a7b92c10bd6d7ef59c913..14ec0d52f2ed63a33e3e4374845893b293a41539 100644 (file)
@@ -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 6e5640c1ea0c12d588b6cce77954a28032cef7fc..e8fd59c7b745393a3075502a0ea3f26f799a57fc 100644 (file)
@@ -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();
@@ -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};
   }
@@ -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};
 }
@@ -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;
@@ -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 *
index 60eece71661906e46dbe8fae8cece3e3cd330be0..e4241594845a9cbcb2c6e033debc64364f091368 100644 (file)
@@ -59,8 +59,6 @@ public:
   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,
@@ -114,6 +112,9 @@ private:
   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);