Index: llvm/include/llvm/CodeGen/DIE.h =================================================================== --- llvm/include/llvm/CodeGen/DIE.h +++ llvm/include/llvm/CodeGen/DIE.h @@ -234,12 +234,12 @@ /// A BaseTypeRef DIE. class DIEBaseTypeRef { const DwarfCompileUnit *CU; - const uint64_t Index; + const uint64_t Key; static constexpr unsigned ULEB128PadSize = 4; public: - explicit DIEBaseTypeRef(const DwarfCompileUnit *TheCU, uint64_t Idx) - : CU(TheCU), Index(Idx) {} + explicit DIEBaseTypeRef(const DwarfCompileUnit *TheCU, uint64_t TheKey) + : CU(TheCU), Key(TheKey) {} /// EmitValue - Emit base type reference. void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; Index: llvm/lib/CodeGen/AsmPrinter/DIE.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -511,7 +511,7 @@ //===----------------------------------------------------------------------===// void DIEBaseTypeRef::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { - uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset(); + uint64_t Offset = CU->getBaseTypeDIE(Key)->getOffset(); assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit"); AP->emitULEB128(Offset, nullptr, ULEB128PadSize); } @@ -521,7 +521,9 @@ } LLVM_DUMP_METHOD -void DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index; } +void DIEBaseTypeRef::print(raw_ostream &O) const { + O << "BaseTypeRef: " << Key; +} //===----------------------------------------------------------------------===// // DIEDelta Implementation Index: llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -104,6 +104,16 @@ void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override; + struct BaseTypeRef { + BaseTypeRef(unsigned BitSize, dwarf::TypeKind Encoding) + : BitSize(BitSize), Encoding(Encoding) {} + unsigned BitSize; + dwarf::TypeKind Encoding; + DIE *Die = nullptr; + }; + + std::vector ExprRefedBaseTypes; + public: DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, @@ -129,15 +139,35 @@ const DIExpression *Expr; }; - struct BaseTypeRef { - BaseTypeRef(unsigned BitSize, dwarf::TypeKind Encoding) : - BitSize(BitSize), Encoding(Encoding) {} - unsigned BitSize; - dwarf::TypeKind Encoding; - DIE *Die = nullptr; - }; + /// Return the placeholder key for the base type with the given properties and + /// create one if necessary. + unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding) { + // Reuse the base_type if we already have one in this CU otherwise we + // create a new one. + unsigned I = 0, E = ExprRefedBaseTypes.size(); + for (; I != E; ++I) + if (ExprRefedBaseTypes[I].BitSize == BitSize && + ExprRefedBaseTypes[I].Encoding == Encoding) + break; + + if (I == E) + ExprRefedBaseTypes.emplace_back(BitSize, Encoding); + + // Some operations that take base type reference operands can have a + // zero-valued operand to indicate the generic type in DWARF, rather than a + // base type. An example of such an operation is DW_OP_convert. To be able + // to distinguish between the generic type and the placeholder keys we + // return from this function we increment the index by one here, and that is + // later on accounted for by getBaseTypeDIE(). + return I + 1; + } - std::vector ExprRefedBaseTypes; + /// Return the DIE corresponding to the given placeholder key. + DIE *getBaseTypeDIE(unsigned Key) const { + assert(Key > 0 && + "The value 0 is reserved for the generic type, not base type DIEs"); + return ExprRefedBaseTypes[Key - 1].Die; + } /// Get or create global variable DIE. DIE * @@ -353,7 +383,7 @@ bool hasDwarfPubSections() const; - void addBaseTypeRef(DIEValueList &Die, int64_t Idx); + void addBaseTypeRef(DIEValueList &Die, int64_t Key); }; } // end namespace llvm Index: llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1338,9 +1338,9 @@ Label, TLOF.getDwarfAddrSection()->getBeginSymbol()); } -void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) { +void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Key) { Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, dwarf::DW_FORM_udata, - new (DIEValueAllocator) DIEBaseTypeRef(this, Idx)); + new (DIEValueAllocator) DIEBaseTypeRef(this, Key)); } void DwarfCompileUnit::createBaseTypeDIEs() { Index: llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -187,9 +187,9 @@ getActiveStreamer().EmitInt8(Value, Twine(Value)); } -void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) { - assert(Idx < (1ULL << (ULEB128PadSize * 7)) && "Idx wont fit"); - getActiveStreamer().emitULEB128(Idx, Twine(Idx), ULEB128PadSize); +void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Key) { + assert(Key < (1ULL << (ULEB128PadSize * 7)) && "Key wont fit"); + getActiveStreamer().emitULEB128(Key, Twine(Key), ULEB128PadSize); } bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI, @@ -2298,8 +2298,9 @@ if (Op.getDescription().Op[I] == Encoding::SizeNA) continue; if (Op.getDescription().Op[I] == Encoding::BaseTypeRef) { - uint64_t Offset = - CU->ExprRefedBaseTypes[Op.getRawOperand(I)].Die->getOffset(); + assert(Op.getRawOperand(I) && + "BaseTypeRefs referring to the generic type are not supported"); + uint64_t Offset = CU->getBaseTypeDIE(Op.getRawOperand(I))->getOffset(); assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit"); Streamer.emitULEB128(Offset, "", ULEB128PadSize); // Make sure comments stay aligned. Index: llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -187,7 +187,7 @@ virtual void emitData1(uint8_t Value) = 0; - virtual void emitBaseTypeRef(uint64_t Idx) = 0; + virtual void emitBaseTypeRef(uint64_t Key) = 0; /// Start emitting data to the temporary buffer. The data stored in the /// temporary buffer can be committed to the main output using @@ -321,10 +321,6 @@ /// any operands here. void beginEntryValueExpression(DIExpressionCursor &ExprCursor); - /// Return the index of a base type with the given properties and - /// create one if necessary. - unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding); - /// Emit all remaining operations in the DIExpressionCursor. /// /// \param FragmentOffsetInBits If this is one fragment out of multiple @@ -367,7 +363,7 @@ void emitSigned(int64_t Value) override; void emitUnsigned(uint64_t Value) override; void emitData1(uint8_t Value) override; - void emitBaseTypeRef(uint64_t Idx) override; + void emitBaseTypeRef(uint64_t Key) override; void enableTemporaryBuffer() override; void disableTemporaryBuffer() override; @@ -397,7 +393,7 @@ void emitSigned(int64_t Value) override; void emitUnsigned(uint64_t Value) override; void emitData1(uint8_t Value) override; - void emitBaseTypeRef(uint64_t Idx) override; + void emitBaseTypeRef(uint64_t Key) override; void enableTemporaryBuffer() override; void disableTemporaryBuffer() override; Index: llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -348,21 +348,6 @@ IsEmittingEntryValue = false; } -unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize, - dwarf::TypeKind Encoding) { - // Reuse the base_type if we already have one in this CU otherwise we - // create a new one. - unsigned I = 0, E = CU.ExprRefedBaseTypes.size(); - for (; I != E; ++I) - if (CU.ExprRefedBaseTypes[I].BitSize == BitSize && - CU.ExprRefedBaseTypes[I].Encoding == Encoding) - break; - - if (I == E) - CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding); - return I; -} - /// Assuming a well-formed expression, match "DW_OP_deref* /// DW_OP_LLVM_fragment?". static bool isMemoryLocation(DIExpressionCursor ExprCursor) { @@ -471,13 +456,13 @@ dwarf::TypeKind Encoding = static_cast(Op->getArg(1)); if (DwarfVersion >= 5) { emitOp(dwarf::DW_OP_convert); - // If targeting a location-list; simply emit the index into the raw - // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been + // If targeting a location-list; simply emit a placeholder key into the + // raw byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been // fitted with means to extract it later. // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef - // (containing the index and a resolve mechanism during emit) into the - // DIE value list. - emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding)); + // (containing the placeholder key and a resolve mechanism during emit) + // into the DIE value list. + emitBaseTypeRef(CU.getOrCreateBaseType(BitSize, Encoding)); } else { if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) { if (Encoding == dwarf::DW_ATE_signed) Index: llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -66,8 +66,8 @@ CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Value); } -void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) { - CU.addBaseTypeRef(getActiveDIE(), Idx); +void DIEDwarfExpression::emitBaseTypeRef(uint64_t Key) { + CU.addBaseTypeRef(getActiveDIE(), Key); } void DIEDwarfExpression::enableTemporaryBuffer() {