[NativePDB] Correctly reconstruct DeclContext for nested enums.
authorZachary Turner <zturner@google.com>
Tue, 18 Dec 2018 23:12:08 +0000 (23:12 +0000)
committerZachary Turner <zturner@google.com>
Tue, 18 Dec 2018 23:12:08 +0000 (23:12 +0000)
We reconstruct the AST hierarchy by trying to hack up a mangled
name for the parent type using the child type's mangled name.
This was failing for enums because their tag type is represented
with two letters ("W4") instead of one letter ("T", "U", etc) as
it is with classes, structs, and unions.  After accounting for
this we can now correctly determine when an enum is nested
inside of a namespace or a class.

llvm-svn: 349565

lldb/lit/SymbolFile/NativePDB/Inputs/nested-types.lldbinit
lldb/lit/SymbolFile/NativePDB/nested-types.cpp
lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp

index 21c3001..466df81 100644 (file)
@@ -8,5 +8,6 @@ target variable -T GlobalE
 target variable -T GlobalF
 target variable -T GlobalG
 target variable -T GlobalH
+target variable -T GlobalEnum
 
 target modules dump ast
index 5693f7f..eb2b3ec 100644 (file)
@@ -11,6 +11,11 @@ struct S {
     int A = 0;
     int B = 1;
   };
+
+  enum class NestedEnum {
+    EnumValue1 = 0,
+    EnumValue2 = 1,
+  };
   int C = 2;
   int D = 3;
   using VoidPtrT = void *;
@@ -70,6 +75,7 @@ constexpr T::U GlobalE;
 constexpr U<int> GlobalF;
 constexpr U<int>::V<int> GlobalG;
 constexpr U<int>::W GlobalH;
+constexpr S::NestedEnum GlobalEnum = S::NestedEnum::EnumValue1;
 
 
 int main(int argc, char **argv) {
@@ -113,6 +119,8 @@ int main(int argc, char **argv) {
 // CHECK:   (int) I = 8
 // CHECK:   (int) J = 9
 // CHECK: }
+// CHECK: (lldb) target variable -T GlobalEnum
+// CHECK: (const S::NestedEnum) GlobalEnum = EnumValue1
 // CHECK: (lldb) target modules dump ast
 // CHECK: Dumping clang ast for 1 modules.
 // CHECK: TranslationUnitDecl {{.*}}
@@ -120,9 +128,12 @@ int main(int argc, char **argv) {
 // CHECK: | |-FieldDecl {{.*}} C 'int'
 // CHECK: | |-FieldDecl {{.*}} D 'int'
 // CHECK: | |-FieldDecl {{.*}} DD 'void *'
-// CHECK: | `-CXXRecordDecl {{.*}} struct NestedStruct definition
-// CHECK: |   |-FieldDecl {{.*}} A 'int'
-// CHECK: |   `-FieldDecl {{.*}} B 'int'
+// CHECK: | |-CXXRecordDecl {{.*}} struct NestedStruct definition
+// CHECK: | | |-FieldDecl {{.*}} A 'int'
+// CHECK: | | `-FieldDecl {{.*}} B 'int'
+// CHECK: | `-EnumDecl {{.*}} NestedEnum\r
+// CHECK: |   |-EnumConstantDecl {{.*}} EnumValue1 'S::NestedEnum'\r
+// CHECK: |   `-EnumConstantDecl {{.*}} EnumValue2 'S::NestedEnum'
 // CHECK: |-CXXRecordDecl {{.*}} struct T definition
 // CHECK: | |-FieldDecl {{.*}} NT 'int'
 // CHECK: | |-CXXRecordDecl {{.*}} struct NestedStruct definition
index 956e56f..778c402 100644 (file)
@@ -188,7 +188,10 @@ GetNestedTagRecord(const NestedTypeRecord &Record, const CVTagRecord &parent,
   // inner tag type is not necessarily the same as the outer tag type, re-write
   // it to match the inner tag type.
   qname[3] = child.asTag().getUniqueName()[3];
-  std::string piece = Record.Name;
+  std::string piece;
+  if (qname[3] == 'W')
+    piece = "4";
+  piece += Record.Name;
   piece.push_back('@');
   qname.insert(4, std::move(piece));
   if (qname != child.asTag().UniqueName)