diff options
author | Amjad Aboud <amjad.aboud@intel.com> | 2016-07-12 12:06:34 +0000 |
---|---|---|
committer | Amjad Aboud <amjad.aboud@intel.com> | 2016-07-12 12:06:34 +0000 |
commit | acee56854533780d94b1aa38c5aaa33720b3a596 (patch) | |
tree | 825f1bca4a20d5e9eb6f6fc0ce01711cc681c1be /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | |
parent | 6892afaa2df7c88d7913a1253e7b3b810994a9ef (diff) | |
download | bcm5719-llvm-acee56854533780d94b1aa38c5aaa33720b3a596.tar.gz bcm5719-llvm-acee56854533780d94b1aa38c5aaa33720b3a596.zip |
[codeview] Improved array type support.
Added support for:
1. Multi dimension array.
2. Array of structure type, which previously was declared incompletely.
3. Dynamic size array.
4. Array where element type is a typedef, volatile or constant (this should resolve PR28311).
Differential Revision: http://reviews.llvm.org/D21526
llvm-svn: 275167
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index bb959e26a8e..b0ba5712220 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -271,8 +271,9 @@ TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP, return recordTypeIndexForDINode(SP, TI, Class); } -TypeIndex CodeViewDebug::recordTypeIndexForDINode(const DINode *Node, TypeIndex TI, - const DIType *ClassTy) { +TypeIndex CodeViewDebug::recordTypeIndexForDINode(const DINode *Node, + TypeIndex TI, + const DIType *ClassTy) { auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI}); (void)InsertResult; assert(InsertResult.second && "DINode was already assigned a type index"); @@ -987,9 +988,55 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) { TypeIndex IndexType = Asm->MAI->getPointerSize() == 8 ? TypeIndex(SimpleTypeKind::UInt64Quad) : TypeIndex(SimpleTypeKind::UInt32Long); - uint64_t Size = Ty->getSizeInBits() / 8; - ArrayRecord Record(ElementTypeIndex, IndexType, Size, Ty->getName()); - return TypeTable.writeArray(Record); + + uint64_t ElementSize = getBaseTypeSize(ElementTypeRef) / 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 == (Ty->getSizeInBits() / 8)); + + return ElementTypeIndex; } TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) { @@ -1771,7 +1818,8 @@ TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) { } /// Emit all the deferred complete record types. Try to do this in FIFO order, -/// and do this until fixpoint, as each complete record type typically references +/// and do this until fixpoint, as each complete record type typically +/// references /// many other record types. void CodeViewDebug::emitDeferredCompleteTypes() { SmallVector<const DICompositeType *, 4> TypesToEmit; |