diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 80 |
1 files changed, 64 insertions, 16 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index e5761ea475d..c9941086c25 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -534,7 +534,7 @@ void CompileUnit::addBlockByrefAddress(const DbgVariable &DV, DIE *Die, if (Tag == dwarf::DW_TAG_pointer_type) { DIDerivedType DTy = DIDerivedType(Ty); - TmpTy = DTy.getTypeDerivedFrom(); + TmpTy = DD->resolve(DTy.getTypeDerivedFrom()); isPointer = true; } @@ -601,9 +601,10 @@ void CompileUnit::addBlockByrefAddress(const DbgVariable &DV, DIE *Die, } /// isTypeSigned - Return true if the type is signed. -static bool isTypeSigned(DIType Ty, int *SizeInBits) { +static bool isTypeSigned(DwarfDebug *DD, DIType Ty, int *SizeInBits) { if (Ty.isDerivedType()) - return isTypeSigned(DIDerivedType(Ty).getTypeDerivedFrom(), SizeInBits); + return isTypeSigned(DD, DD->resolve(DIDerivedType(Ty).getTypeDerivedFrom()), + SizeInBits); if (Ty.isBasicType()) if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed || DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) { @@ -613,6 +614,51 @@ static bool isTypeSigned(DIType Ty, int *SizeInBits) { return false; } +/// Return true if type encoding is unsigned. +static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) { + DIDerivedType DTy(Ty); + if (DTy.isDerivedType()) + return isUnsignedDIType(DD, DD->resolve(DTy.getTypeDerivedFrom())); + + DIBasicType BTy(Ty); + if (BTy.isBasicType()) { + unsigned Encoding = BTy.getEncoding(); + if (Encoding == dwarf::DW_ATE_unsigned || + Encoding == dwarf::DW_ATE_unsigned_char || + Encoding == dwarf::DW_ATE_boolean) + return true; + } + return false; +} + +/// If this type is derived from a base type then return base type size. +static uint64_t getOriginalTypeSize(DwarfDebug *DD, 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(); + + DIType BaseType = DD->resolve(Ty.getTypeDerivedFrom()); + + // If this type is not derived from any type then take conservative approach. + if (!BaseType.isValid()) + return Ty.getSizeInBits(); + + // 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 (BaseType.isDerivedType()) + return getOriginalTypeSize(DD, DIDerivedType(BaseType)); + + return BaseType.getSizeInBits(); +} + /// addConstantValue - Add constant value entry in variable DIE. void CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO, DIType Ty) { @@ -621,7 +667,7 @@ void CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO, // udata/sdata over dataN as suggested by the DWARF spec) assert(MO.isImm() && "Invalid machine operand!"); int SizeInBits = -1; - bool SignedConstant = isTypeSigned(Ty, &SizeInBits); + bool SignedConstant = isTypeSigned(DD, Ty, &SizeInBits); uint16_t Form; // If we're a signed constant definitely use sdata. @@ -938,7 +984,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { Buffer.setTag(Tag); // Map to main type, void will not have a type. - DIType FromTy = DTy.getTypeDerivedFrom(); + DIType FromTy = DD->resolve(DTy.getTypeDerivedFrom()); if (FromTy) addType(&Buffer, FromTy); @@ -1016,7 +1062,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { Buffer.addChild(ElemDie); } } - DIType DTy = CTy.getTypeDerivedFrom(); + DIType DTy = DD->resolve(CTy.getTypeDerivedFrom()); if (DTy) { addType(&Buffer, DTy); addUInt(&Buffer, dwarf::DW_AT_enum_class, dwarf::DW_FORM_flag, 1); @@ -1082,7 +1128,8 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { DIDerivedType DDTy(Element); if (DDTy.getTag() == dwarf::DW_TAG_friend) { ElemDie = new DIE(dwarf::DW_TAG_friend); - addType(ElemDie, DDTy.getTypeDerivedFrom(), dwarf::DW_AT_friend); + addType(ElemDie, DD->resolve(DDTy.getTypeDerivedFrom()), + dwarf::DW_AT_friend); } else if (DDTy.isStaticMember()) ElemDie = createStaticMemberDIE(DDTy); else @@ -1224,7 +1271,7 @@ CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter VP) { addString(ParamDIE, dwarf::DW_AT_name, VP.getName()); if (Value *Val = VP.getValue()) { if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) - addConstantValue(ParamDIE, CI, VP.getType().isUnsignedDIType()); + addConstantValue(ParamDIE, CI, isUnsignedDIType(DD, VP.getType())); else if (GlobalValue *GV = dyn_cast<GlobalValue>(Val)) { // For declaration non-type template parameters (such as global values and // functions) @@ -1511,7 +1558,7 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) { // emitting AT_const_value multiple times, we only add AT_const_value when // it is not a static member. if (!IsStaticMember) - addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType()); + addConstantValue(VariableDIE, CI, isUnsignedDIType(DD, GTy)); } else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) { addToAccelTable = true; // GV is a merged global. @@ -1572,7 +1619,7 @@ void CompileUnit::constructArrayTypeDIE(DIE &Buffer, addFlag(&Buffer, dwarf::DW_AT_GNU_vector); // Emit the element type. - addType(&Buffer, CTy->getTypeDerivedFrom()); + addType(&Buffer, DD->resolve(CTy->getTypeDerivedFrom())); // Get an anonymous type for index type. // FIXME: This type should be passed down from the front end @@ -1679,7 +1726,7 @@ DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, addConstantFPValue(VariableDie, DVInsn->getOperand(0)); else if (DVInsn->getOperand(0).isCImm()) addConstantValue(VariableDie, DVInsn->getOperand(0).getCImm(), - DV->getType().isUnsignedDIType()); + isUnsignedDIType(DD, DV->getType())); DV->setDIE(VariableDie); return VariableDie; @@ -1707,7 +1754,7 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) { if (!Name.empty()) addString(MemberDie, dwarf::DW_AT_name, Name); - addType(MemberDie, DT.getTypeDerivedFrom()); + addType(MemberDie, DD->resolve(DT.getTypeDerivedFrom())); addSourceLine(MemberDie, DT); @@ -1715,11 +1762,12 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) { addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); uint64_t Size = DT.getSizeInBits(); - uint64_t FieldSize = DT.getOriginalTypeSize(); + uint64_t FieldSize = getOriginalTypeSize(DD, DT); if (Size != FieldSize) { // Handle bitfield. - addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3); + addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, + getOriginalTypeSize(DD, DT)>>3); addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits()); uint64_t Offset = DT.getOffsetInBits(); @@ -1794,7 +1842,7 @@ DIE *CompileUnit::createStaticMemberDIE(const DIDerivedType DT) { return NULL; DIE *StaticMemberDIE = new DIE(DT.getTag()); - DIType Ty = DT.getTypeDerivedFrom(); + DIType Ty = DD->resolve(DT.getTypeDerivedFrom()); addString(StaticMemberDIE, dwarf::DW_AT_name, DT.getName()); addType(StaticMemberDIE, Ty); @@ -1815,7 +1863,7 @@ DIE *CompileUnit::createStaticMemberDIE(const DIDerivedType DT) { dwarf::DW_ACCESS_public); if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT.getConstant())) - addConstantValue(StaticMemberDIE, CI, Ty.isUnsignedDIType()); + addConstantValue(StaticMemberDIE, CI, isUnsignedDIType(DD, Ty)); if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT.getConstant())) addConstantFPValue(StaticMemberDIE, CFP); |