diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index e01ee0984ed..4e463a2ec5c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -912,8 +912,55 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) { ? TypeIndex(SimpleTypeKind::UInt64Quad) : TypeIndex(SimpleTypeKind::UInt32Long); uint64_t Size = Ty->getSizeInBits() / 8; - ArrayRecord Record(ElementTypeIndex, IndexType, Size, Ty->getName()); - return TypeTable.writeArray(Record); + assert(ElementTypeRef.resolve()); + uint64_t ElementSize = ElementTypeRef.resolve()->getSizeInBits() / 8; + + bool UndefinedSubrange = false; + + // FIXME: + // There is a bug in the front-end where an array of a structure, which was + // declared as incomplete structure first, ends up not getting a size assigned + // to it. (PR28303) + // Example: + // struct A(*p)[3]; + // struct A { int f; } a[3]; + // + // This needs to be fixed in the front-end, but in the meantime we don't want + // to trigger an assertion because of this. + if (Ty->getSizeInBits() == 0) { + UndefinedSubrange = true; + } + + // Add subranges to array type. + DINodeArray Elements = Ty->getElements(); + for (int i = Elements.size() - 1; i >= 0; --i) { + const DINode *Element = Elements[i]; + assert(Element->getTag() == dwarf::DW_TAG_subrange_type); + + const DISubrange *Subrange = cast<DISubrange>(Element); + assert(Subrange->getLowerBound() == 0 && + "codeview doesn't support subranges with lower bounds"); + int64_t Count = Subrange->getCount(); + + // Variable Length Array (VLA) has Count equal to '-1'. + // Replace with Count '1', assume it is the minimum VLA length. + // FIXME: Make front-end support VLA subrange and emit LF_DIMVARLU. + if (Count == -1) { + Count = 1; + UndefinedSubrange = true; + } + + StringRef Name = (i == 0) ? Ty->getName() : ""; + // Update the element size and element type index for subsequent subranges. + ElementSize *= Count; + ElementTypeIndex = TypeTable.writeArray( + ArrayRecord(ElementTypeIndex, IndexType, ElementSize, Name)); + } + + (void)UndefinedSubrange; + assert(UndefinedSubrange || ElementSize == Size); + + return ElementTypeIndex; } TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) { |