[NativePDB] Correctly reconstruct DeclContext for nested enums.

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.

git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@349565 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lit/SymbolFile/NativePDB/Inputs/nested-types.lldbinit b/lit/SymbolFile/NativePDB/Inputs/nested-types.lldbinit
index 21c3001..466df81 100644
--- a/lit/SymbolFile/NativePDB/Inputs/nested-types.lldbinit
+++ b/lit/SymbolFile/NativePDB/Inputs/nested-types.lldbinit
@@ -8,5 +8,6 @@
 target variable -T GlobalF
 target variable -T GlobalG
 target variable -T GlobalH
+target variable -T GlobalEnum
 
 target modules dump ast
diff --git a/lit/SymbolFile/NativePDB/nested-types.cpp b/lit/SymbolFile/NativePDB/nested-types.cpp
index 5693f7f..eb2b3ec 100644
--- a/lit/SymbolFile/NativePDB/nested-types.cpp
+++ b/lit/SymbolFile/NativePDB/nested-types.cpp
@@ -11,6 +11,11 @@
     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 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 @@
 // 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 @@
 // 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

+// CHECK: |   |-EnumConstantDecl {{.*}} EnumValue1 'S::NestedEnum'

+// CHECK: |   `-EnumConstantDecl {{.*}} EnumValue2 'S::NestedEnum'
 // CHECK: |-CXXRecordDecl {{.*}} struct T definition
 // CHECK: | |-FieldDecl {{.*}} NT 'int'
 // CHECK: | |-CXXRecordDecl {{.*}} struct NestedStruct definition
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 956e56f..778c402 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -188,7 +188,10 @@
   // 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)