summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
authorAmjad Aboud <amjad.aboud@intel.com>2016-07-12 12:06:34 +0000
committerAmjad Aboud <amjad.aboud@intel.com>2016-07-12 12:06:34 +0000
commitacee56854533780d94b1aa38c5aaa33720b3a596 (patch)
tree825f1bca4a20d5e9eb6f6fc0ce01711cc681c1be /llvm/lib/CodeGen/AsmPrinter
parent6892afaa2df7c88d7913a1253e7b3b810994a9ef (diff)
downloadbcm5719-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')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp60
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp29
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h3
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp28
4 files changed, 87 insertions, 33 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;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index c1300774c4f..16ffe2e15ac 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -85,6 +85,35 @@ bool DebugHandlerBase::piecesOverlap(const DIExpression *P1, const DIExpression
return pieceCmp(P1, P2) == 0;
}
+/// If this type is derived from a base type then return base type size.
+uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) {
+ DIType *Ty = TyRef.resolve();
+ assert(Ty);
+ DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty);
+ if (!DDTy)
+ return Ty->getSizeInBits();
+
+ unsigned Tag = DDTy->getTag();
+
+ if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
+ Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
+ Tag != dwarf::DW_TAG_restrict_type)
+ return DDTy->getSizeInBits();
+
+ DIType *BaseType = DDTy->getBaseType().resolve();
+
+ assert(BaseType && "Unexpected invalid base type");
+
+ // If this is a derived type, go ahead and get the base type, unless it's a
+ // reference then it's just the size of the field. Pointer types have no need
+ // of this since they're a different type of qualification on the type.
+ if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
+ BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
+ return Ty->getSizeInBits();
+
+ return getBaseTypeSize(BaseType);
+}
+
void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
// Grab the lexical scopes for the function, if we don't have any of those
// then we're not going to be able to do anything.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
index 826023602c1..b8bbcec133f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
@@ -99,6 +99,9 @@ public:
/// Determine whether two variable pieces overlap.
static bool piecesOverlap(const DIExpression *P1, const DIExpression *P2);
+
+ /// If this type is derived from a base type then return base type size.
+ static uint64_t getBaseTypeSize(const DITypeRef TyRef);
};
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e2e6954bd1c..4100d728a53 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -561,32 +561,6 @@ static bool isUnsignedDIType(DwarfDebug *DD, const DIType *Ty) {
Ty->getTag() == dwarf::DW_TAG_unspecified_type;
}
-/// If this type is derived from a base type then return base type size.
-static uint64_t getBaseTypeSize(DwarfDebug *DD, const DIDerivedType *Ty) {
- unsigned Tag = Ty->getTag();
-
- if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
- Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
- Tag != dwarf::DW_TAG_restrict_type)
- return Ty->getSizeInBits();
-
- auto *BaseType = DD->resolve(Ty->getBaseType());
-
- assert(BaseType && "Unexpected invalid base type");
-
- // If this is a derived type, go ahead and get the base type, unless it's a
- // reference then it's just the size of the field. Pointer types have no need
- // of this since they're a different type of qualification on the type.
- if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
- BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
- return Ty->getSizeInBits();
-
- if (auto *DT = dyn_cast<DIDerivedType>(BaseType))
- return getBaseTypeSize(DD, DT);
-
- return BaseType->getSizeInBits();
-}
-
void DwarfUnit::addConstantFPValue(DIE &Die, const MachineOperand &MO) {
assert(MO.isFPImm() && "Invalid machine operand!");
DIEBlock *Block = new (DIEValueAllocator) DIEBlock;
@@ -1408,7 +1382,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
} else {
uint64_t Size = DT->getSizeInBits();
- uint64_t FieldSize = getBaseTypeSize(DD, DT);
+ uint64_t FieldSize = DD->getBaseTypeSize(DT);
uint64_t OffsetInBytes;
bool IsBitfield = FieldSize && Size != FieldSize;
OpenPOWER on IntegriCloud