Generate debug descriptors for array types while generating the debug info.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52140 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 70a6f66..813efd2 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -48,6 +48,7 @@
 , VariableDescList()
 , GlobalVarDescList()
 , EnumDescList()
+, SubrangeDescList()
 , Subprogram(NULL)
 {
   SR = new llvm::DISerializer();
@@ -96,6 +97,12 @@
     delete *I;
   }
 
+  // Free subrange descriptors.
+  for (std::vector<llvm::SubrangeDesc *>::iterator I
+       = SubrangeDescList.begin(); I != SubrangeDescList.end(); ++I) {
+    delete *I;
+  }
+
   delete CompileUnitAnchor;
   delete SubprogramAnchor;
   delete GlobalVariableAnchor;
@@ -457,6 +464,52 @@
   return EnumTy;
 }
 
+/// getOrCreateArrayType - get or create array types.
+llvm::TypeDesc *
+CGDebugInfo::getOrCreateArrayType(QualType type, llvm::CompileUnitDesc *Unit)
+{
+  llvm::CompositeTypeDesc *ArrayTy 
+    = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_array_type);
+
+  // Size, align and offset of the type.
+  uint64_t Size = M->getContext().getTypeSize(type);
+  uint64_t Align = M->getContext().getTypeAlign(type);
+
+  SourceManager &SM = M->getContext().getSourceManager();
+  uint64_t Line = SM.getLogicalLineNumber(CurLoc);
+
+  // Add the dimensions of the array.
+  std::vector<llvm::DebugInfoDesc *> &Elements = ArrayTy->getElements();
+  do {
+    llvm::SubrangeDesc *Subrange = new llvm::SubrangeDesc();
+
+    // push it back on the subrange desc list so that we can free it later.
+    SubrangeDescList.push_back(Subrange);
+
+    uint64_t Upper = 0;
+    if (type->getTypeClass() == Type::ConstantArray) {
+      const ConstantArrayType *ConstArrTy = type->getAsConstantArrayType();
+      Upper = ConstArrTy->getSize().getZExtValue() - 1;
+    }
+    Subrange->setLo(0);
+    Subrange->setHi(Upper);
+    Elements.push_back(Subrange);
+    type = type->getAsArrayType()->getElementType();
+  } while (type->isArrayType());
+
+  ArrayTy->setFromType(getOrCreateType(type, Unit));
+
+  if (ArrayTy) {
+    ArrayTy->setContext(Unit);
+    ArrayTy->setSize(Size);
+    ArrayTy->setAlign(Align);
+    ArrayTy->setOffset(0);
+    ArrayTy->setFile(getOrCreateCompileUnit(CurLoc));
+    ArrayTy->setLine(Line);
+  }
+  return ArrayTy;
+}
+
 
 /// getOrCreateTaggedType - get or create structure/union/Enum type.
 llvm::TypeDesc *
@@ -492,9 +545,6 @@
   switch(type->getTypeClass()) {
     case Type::Complex:
     case Type::Reference:
-    case Type::ConstantArray:
-    case Type::VariableArray:
-    case Type::IncompleteArray:
     case Type::Vector:
     case Type::ExtVector:
     case Type::ASQual:
@@ -528,6 +578,12 @@
     case Type::Tagged:
       Slot = getOrCreateTaggedType(type, Unit);
       break;
+
+    case Type::ConstantArray:
+    case Type::VariableArray:
+    case Type::IncompleteArray:
+      Slot = getOrCreateArrayType(type, Unit);
+      break;
   }
 
   return Slot;