Retry: "Emit CodeView type records for nested classes."

Now with a corrected test to account for a recently supported properties bit in the debug info of a struct.

Original review: http://reviews.llvm.org/D21939

This reverts commit 970c3fd497a28d25dd69526eb52594a696c37968.

llvm-svn: 274661
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index bd4df87..fe63b70 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1414,6 +1414,8 @@
   MemberList Members;
   // Direct overloaded methods gathered by name.
   MethodsMap Methods;
+
+  std::vector<const DICompositeType *> NestedClasses;
 };
 
 void CodeViewDebug::clear() {
@@ -1466,8 +1468,8 @@
         // friends in the past, but modern versions do not.
       }
       // FIXME: Get Clang to emit function virtual table here and handle it.
-      // FIXME: Get clang to emit nested types here and do something with
-      // them.
+    } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {
+      Info.NestedClasses.push_back(Composite);
     }
     // Skip other unrecognized kinds of elements.
   }
@@ -1496,7 +1498,12 @@
   TypeIndex FieldTI;
   TypeIndex VShapeTI;
   unsigned FieldCount;
-  std::tie(FieldTI, VShapeTI, FieldCount) = lowerRecordFieldList(Ty);
+  bool ContainsNestedClass;
+  std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) =
+      lowerRecordFieldList(Ty);
+
+  if (ContainsNestedClass)
+    CO |= ClassOptions::ContainsNestedClass;
 
   std::string FullName = getFullyQualifiedName(Ty);
 
@@ -1532,7 +1539,13 @@
   ClassOptions CO = getCommonClassOptions(Ty);
   TypeIndex FieldTI;
   unsigned FieldCount;
-  std::tie(FieldTI, std::ignore, FieldCount) = lowerRecordFieldList(Ty);
+  bool ContainsNestedClass;
+  std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) =
+      lowerRecordFieldList(Ty);
+
+  if (ContainsNestedClass)
+    CO |= ClassOptions::ContainsNestedClass;
+
   uint64_t SizeInBytes = Ty->getSizeInBits() / 8;
   std::string FullName = getFullyQualifiedName(Ty);
 
@@ -1550,7 +1563,7 @@
   return UnionTI;
 }
 
-std::tuple<TypeIndex, TypeIndex, unsigned>
+std::tuple<TypeIndex, TypeIndex, unsigned, bool>
 CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
   // Manually count members. MSVC appears to count everything that generates a
   // field list record. Each individual overload in a method overload group
@@ -1645,8 +1658,17 @@
           OverloadedMethodRecord(Methods.size(), MethodList, Name));
     }
   }
+
+  // Create nested classes.
+  for (const DICompositeType *Nested : Info.NestedClasses) {
+    NestedTypeRecord R(getTypeIndex(DITypeRef(Nested)), Nested->getName());
+    Fields.writeNestedType(R);
+    MemberCount++;
+  }
+
   TypeIndex FieldTI = TypeTable.writeFieldList(Fields);
-  return std::make_tuple(FieldTI, TypeIndex(), MemberCount);
+  return std::make_tuple(FieldTI, TypeIndex(), MemberCount,
+                         !Info.NestedClasses.empty());
 }
 
 TypeIndex CodeViewDebug::getVBPTypeIndex() {