diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h @@ -25,13 +25,15 @@ class iterator; /// This class represents an Operation in the Expression. Each operation can - /// have up to 2 oprerands. + /// have up to MaxOperands oprerands. /// /// An Operation can be in Error state (check with isError()). This /// means that it couldn't be decoded successfully and if it is the /// case, all others fields contain undefined values. class Operation { public: + /// The maximum number of operands an Operation can have. + static constexpr size_t MaxOperands = 3u; /// Size and signedness of expression operations' operands. enum Encoding : uint8_t { Size1 = 0, @@ -63,13 +65,23 @@ /// Description of the encoding of one expression Op. struct Description { - DwarfVersion Version; ///< Dwarf version where the Op was introduced. - Encoding Op[2]; ///< Encoding for Op operands, or SizeNA. - - constexpr Description() : Description(DwarfNA, SizeNA, SizeNA) {} - constexpr Description(DwarfVersion Version, Encoding Op1 = SizeNA, - Encoding Op2 = SizeNA) - : Version(Version), Op{Op1, Op2} {} + DwarfVersion Version; ///< Dwarf version where the Op was introduced. + Encoding Op[MaxOperands]; ///< Encoding for Op operands, or SizeNA. + + private: + template + constexpr Description(std::index_sequence, DwarfVersion Version, + Ts... Ops) + : Version(Version), Op{Ops..., ((void)Is, SizeNA)...} {} + + public: + template + constexpr Description(DwarfVersion Version, Ts... Ops) + : Description(std::make_index_sequence{}, + Version, Ops...) { + static_assert(sizeof...(Ts) <= MaxOperands); + } + constexpr Description() : Description(DwarfNA) {} ~Description() = default; }; @@ -79,8 +91,8 @@ Description Desc; bool Error = false; uint64_t EndOffset; - uint64_t Operands[2]; - uint64_t OperandEndOffsets[2]; + uint64_t Operands[MaxOperands]; + uint64_t OperandEndOffsets[MaxOperands]; public: const Description &getDescription() const { return Desc; } @@ -164,7 +176,7 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode, - const uint64_t Operands[2]); + const ArrayRef Operands); private: DataExtractor Data; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h @@ -33,22 +33,17 @@ // OP_[GNU_]deref_type, OP_[GNU_]entry_value, OP_implicit_value, // OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type, OP_xderef_type. LVSmall Opcode = 0; - uint64_t Operands[2]; + SmallVector Operands; public: LVOperation() = delete; - LVOperation(LVSmall Opcode, LVUnsigned Operand1, LVUnsigned Operand2) - : Opcode(Opcode) { - Operands[0] = Operand1; - Operands[1] = Operand2; - } + LVOperation(LVSmall Opcode, ArrayRef Operands) + : Opcode(Opcode), Operands(Operands) {} LVOperation(const LVOperation &) = delete; LVOperation &operator=(const LVOperation &) = delete; ~LVOperation() = default; LVSmall getOpcode() const { return Opcode; } - uint64_t getOperand1() const { return Operands[0]; } - uint64_t getOperand2() const { return Operands[1]; } std::string getOperandsDWARFInfo(); std::string getOperandsCodeViewInfo(); @@ -154,8 +149,7 @@ virtual void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset, uint64_t LocDescOffset) {} - virtual void addObject(LVSmall Opcode, LVUnsigned Operand1, - LVUnsigned Operand2) {} + virtual void addObject(LVSmall Opcode, ArrayRef Operands) {} static void print(LVLocations *Locations, raw_ostream &OS, bool Full = true); void printInterval(raw_ostream &OS, bool Full = true) const; @@ -184,8 +178,7 @@ void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset, uint64_t LocDescOffset) override; - void addObject(LVSmall Opcode, LVUnsigned Operand1, - LVUnsigned Operand2) override; + void addObject(LVSmall Opcode, ArrayRef Operands) override; void printRawExtra(raw_ostream &OS, bool Full = true) const override; void printExtra(raw_ostream &OS, bool Full = true) const override; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h @@ -228,10 +228,8 @@ #undef LV_CREATE_OBJECT // Operations creation. - LVOperation *createOperation(LVSmall OpCode, LVUnsigned Operand1, - LVUnsigned Operand2) { - return new (AllocatedOperation.Allocate()) - LVOperation(OpCode, Operand1, Operand2); + LVOperation *createOperation(LVSmall OpCode, ArrayRef Operands) { + return new (AllocatedOperation.Allocate()) LVOperation(OpCode, Operands); } StringRef getFilename(LVObject *Object, size_t Index) const; @@ -263,7 +261,8 @@ Error doPrint(); Error doLoad(); - virtual std::string getRegisterName(LVSmall Opcode, uint64_t Operands[2]) { + virtual std::string getRegisterName(LVSmall Opcode, + ArrayRef Operands) { llvm_unreachable("Invalid instance reader."); return {}; } diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h @@ -126,8 +126,7 @@ // Add a Location Entry. void addLocationConstant(dwarf::Attribute Attr, LVUnsigned Constant, uint64_t LocDescOffset); - void addLocationOperands(LVSmall Opcode, uint64_t Operand1, - uint64_t Operand2); + void addLocationOperands(LVSmall Opcode, ArrayRef Operands); void addLocation(dwarf::Attribute Attr, LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset, uint64_t LocDescOffset, bool CallSiteLocation = false); diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h --- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h @@ -215,7 +215,8 @@ static StringRef getSymbolKindName(SymbolKind Kind); static std::string formatRegisterId(RegisterId Register, CPUType CPU); - std::string getRegisterName(LVSmall Opcode, uint64_t Operands[2]) override; + std::string getRegisterName(LVSmall Opcode, + ArrayRef Operands) override; bool isSystemEntry(LVElement *Element, StringRef Name) const override; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVELFReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVELFReader.h --- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVELFReader.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVELFReader.h @@ -139,7 +139,8 @@ return SymbolsWithLocations; } - std::string getRegisterName(LVSmall Opcode, uint64_t Operands[2]) override; + std::string getRegisterName(LVSmall Opcode, + ArrayRef Operands) override; void print(raw_ostream &OS) const; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2564,7 +2564,7 @@ "3 operand ops not yet supported"); Streamer.emitInt8(Op.getCode(), Comment != End ? *(Comment++) : ""); Offset++; - for (unsigned I = 0; I < 2; ++I) { + for (unsigned I = 0; I < DWARFExpression::Operation::MaxOperands; ++I) { if (Op.getDescription().Op[I] == Encoding::SizeNA) continue; if (Op.getDescription().Op[I] == Encoding::BaseTypeRef) { diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -1039,7 +1039,7 @@ for (auto &Op : Expression) { auto Description = Op.getDescription(); // DW_OP_const_type is variable-length and has 3 - // operands. DWARFExpression thus far only supports 2. + // operands. Thus far we only support 2. auto Op0 = Description.Op[0]; auto Op1 = Description.Op[1]; if ((Op0 == Encoding::BaseTypeRef && Op1 != Encoding::SizeNA) || diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -123,7 +123,7 @@ if (Desc.Version == Operation::DwarfNA) return false; - for (unsigned Operand = 0; Operand < 2; ++Operand) { + for (unsigned Operand = 0; Operand < MaxOperands; ++Operand) { unsigned Size = Desc.Op[Operand]; unsigned Signed = Size & Operation::SignBit; @@ -204,9 +204,9 @@ static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, - const uint64_t Operands[2], + ArrayRef Operands, unsigned Operand) { - assert(Operand < 2 && "operand out of bounds"); + assert(Operand < Operands.size() && "operand out of bounds"); auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]); if (Die && Die.getTag() == dwarf::DW_TAG_base_type) { OS << " ("; @@ -224,7 +224,7 @@ bool DWARFExpression::prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode, - const uint64_t Operands[2]) { + ArrayRef Operands) { if (!DumpOpts.GetNameForDWARFReg) return false; @@ -274,7 +274,7 @@ if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands)) return true; - for (unsigned Operand = 0; Operand < 2; ++Operand) { + for (unsigned Operand = 0; Operand < MaxOperands; ++Operand) { unsigned Size = Desc.Op[Operand]; unsigned Signed = Size & Operation::SignBit; @@ -352,7 +352,7 @@ } bool DWARFExpression::Operation::verify(const Operation &Op, DWARFUnit *U) { - for (unsigned Operand = 0; Operand < 2; ++Operand) { + for (unsigned Operand = 0; Operand < MaxOperands; ++Operand) { unsigned Size = Op.Desc.Op[Operand]; if (Size == Operation::SizeNA) diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp --- a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp @@ -352,7 +352,7 @@ uint16_t OperationCode = getCodeViewOperationCode(Opcode); switch (OperationCode) { - // Operands: [Offset, 0]. + // Operands: [Offset]. case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL: Stream << "frame_pointer_rel " << int(Operands[0]); break; @@ -360,7 +360,7 @@ Stream << "frame_pointer_rel_full_scope " << int(Operands[0]); break; - // Operands: [Register, 0]. + // Operands: [Register]. case codeview::SymbolKind::S_DEFRANGE_REGISTER: Stream << "register " << getReader().getRegisterName(Opcode, Operands); break; @@ -375,7 +375,7 @@ << " offset " << int(Operands[1]); break; - // Operands: [Program, 0]. + // Operands: [Program]. case codeview::SymbolKind::S_DEFRANGE: Stream << "frame " << int(Operands[0]); break; @@ -576,11 +576,11 @@ } // Add a Location Record. -void LVLocationSymbol::addObject(LVSmall Opcode, LVUnsigned Operand1, - LVUnsigned Operand2) { +void LVLocationSymbol::addObject(LVSmall Opcode, + ArrayRef Operands) { if (!Entries) Entries = std::make_unique(); - Entries->push_back(getReader().createOperation(Opcode, Operand1, Operand2)); + Entries->push_back(getReader().createOperation(Opcode, Operands)); } // Based on the DWARF attribute, define the location kind. diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp --- a/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp @@ -82,10 +82,10 @@ } // Add a Location Record. -void LVSymbol::addLocationOperands(LVSmall Opcode, uint64_t Operand1, - uint64_t Operand2) { +void LVSymbol::addLocationOperands(LVSmall Opcode, + ArrayRef Operands) { if (CurrentLocation) - CurrentLocation->addObject(Opcode, Operand1, Operand2); + CurrentLocation->addObject(Opcode, Operands); } // Add a Location Entry. @@ -97,8 +97,7 @@ /*SectionOffset=*/0, LocDescOffset); // Add records to Location Entry. - addLocationOperands(/*Opcode=*/LVLocationMemberOffset, - /*Operand1=*/Constant, /*Operand2=*/0); + addLocationOperands(/*Opcode=*/LVLocationMemberOffset, {Constant}); } LVLocations::iterator LVSymbol::addLocationGap(LVLocations::iterator Pos, @@ -115,8 +114,7 @@ LVLocations::iterator Iter = Locations->insert(Pos, Gap); // Add gap to Location Entry. - Gap->addObject(/*op=*/dwarf::DW_OP_hi_user, - /*opd1=*/0, /*opd2=*/0); + Gap->addObject(dwarf::DW_OP_hi_user, {}); // Mark the entry as a gap. Gap->setIsGapEntry(); diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp --- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp @@ -1212,7 +1212,7 @@ } std::string LVCodeViewReader::getRegisterName(LVSmall Opcode, - uint64_t Operands[2]) { + ArrayRef Operands) { // Get Compilation Unit CPU Type. CPUType CPU = getCompileUnitCPUType(); // For CodeView the register always is in Operands[0]; diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp --- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp @@ -1065,7 +1065,7 @@ uint64_t Operand1 = DefRangeFramePointerRelFullScope.Offset; Symbol->addLocation(Attr, 0, 0, 0, 0); - Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0); + Symbol->addLocationOperands(LVSmall(Attr), {Operand1}); } return Error::success(); @@ -1103,7 +1103,7 @@ Reader->linearAddress(Range.ISectStart, Range.OffsetStart); Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0); - Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0); + Symbol->addLocationOperands(LVSmall(Attr), {Operand1}); } return Error::success(); @@ -1142,7 +1142,7 @@ Reader->linearAddress(Range.ISectStart, Range.OffsetStart); Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0); - Symbol->addLocationOperands(LVSmall(Attr), Operand1, Operand2); + Symbol->addLocationOperands(LVSmall(Attr), {Operand1, Operand2}); } return Error::success(); @@ -1177,7 +1177,7 @@ Reader->linearAddress(Range.ISectStart, Range.OffsetStart); Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0); - Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0); + Symbol->addLocationOperands(LVSmall(Attr), {Operand1}); } return Error::success(); @@ -1215,7 +1215,7 @@ Reader->linearAddress(Range.ISectStart, Range.OffsetStart); Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0); - Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0); + Symbol->addLocationOperands(LVSmall(Attr), {Operand1}); } return Error::success(); @@ -1258,7 +1258,7 @@ Reader->linearAddress(Range.ISectStart, Range.OffsetStart); Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0); - Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0); + Symbol->addLocationOperands(LVSmall(Attr), {Operand1, /*Operand2=*/0}); } return Error::success(); @@ -1299,7 +1299,7 @@ Reader->linearAddress(Range.ISectStart, Range.OffsetStart); Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0); - Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0); + Symbol->addLocationOperands(LVSmall(Attr), {Operand1, /*Operand2=*/0}); } return Error::success(); diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp --- a/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp @@ -759,7 +759,8 @@ } } -std::string LVELFReader::getRegisterName(LVSmall Opcode, uint64_t Operands[2]) { +std::string LVELFReader::getRegisterName(LVSmall Opcode, + ArrayRef Operands) { // The 'prettyPrintRegisterOp' function uses the DWARFUnit to support // DW_OP_regval_type. At this point we are operating on a logical view // item, with no access to the underlying DWARF data used by LLVM. @@ -973,18 +974,16 @@ bool CallSiteLocation) { auto ProcessLocationExpression = [&](const DWARFExpression &Expression) { - // DW_OP_const_type is variable-length and has 3 - // operands. DWARFExpression thus far only supports 2. - uint64_t Operands[2] = {0}; + std::array Operands{0}; for (const DWARFExpression::Operation &Op : Expression) { DWARFExpression::Operation::Description Description = Op.getDescription(); - for (unsigned Operand = 0; Operand < 2; ++Operand) { + for (unsigned Operand = 0; + Operand < DWARFExpression::Operation::MaxOperands; ++Operand) { if (Description.Op[Operand] == DWARFExpression::Operation::SizeNA) break; Operands[Operand] = Op.getRawOperand(Operand); } - CurrentSymbol->addLocationOperands(Op.getCode(), Operands[0], - Operands[1]); + CurrentSymbol->addLocationOperands(Op.getCode(), Operands); } };