diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h | 46 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 94 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 21 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 24 |
6 files changed, 85 insertions, 118 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index faba9f17c5f..4eb289afc18 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -614,8 +614,8 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) { /// of DBG_VALUE, returning true if it was able to do so. A false return /// means the target will need to handle MI in EmitInstruction. static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { - // This code handles only the 4-operand target-independent form. - if (MI->getNumOperands() != 4) + // This code handles only the 3-operand target-independent form. + if (MI->getNumOperands() != 3) return false; SmallString<128> Str; @@ -629,11 +629,9 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { OS << Name << ":"; } OS << V.getName(); - - DIExpression Expr = MI->getDebugExpression(); - if (Expr.isVariablePiece()) - OS << " [piece offset=" << Expr.getPieceOffset() - << " size=" << Expr.getPieceSize() << "]"; + if (V.isVariablePiece()) + OS << " [piece offset=" << V.getPieceOffset() + << " size="<<V.getPieceSize()<<"]"; OS << " <- "; // The second operand is only an offset if it's an immediate. diff --git a/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp index a258d621a6a..998c396924b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp @@ -27,7 +27,7 @@ namespace llvm { // In the other case, returns 0. static unsigned isDescribedByReg(const MachineInstr &MI) { assert(MI.isDebugValue()); - assert(MI.getNumOperands() == 4); + assert(MI.getNumOperands() == 3); // If location of variable is described using a register (directly or // indirecltly), this register is always a first operand. return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0; @@ -37,7 +37,7 @@ void DbgValueHistoryMap::startInstrRange(const MDNode *Var, const MachineInstr &MI) { // Instruction range should start with a DBG_VALUE instruction for the // variable. - assert(MI.isDebugValue() && "not a DBG_VALUE"); + assert(MI.isDebugValue() && getEntireVariable(MI.getDebugVariable()) == Var); auto &Ranges = VarInstrRanges[Var]; if (!Ranges.empty() && Ranges.back().second == nullptr && Ranges.back().first->isIdenticalTo(&MI)) { @@ -193,7 +193,7 @@ void calculateDbgValueHistory(const MachineFunction *MF, // Use the base variable (without any DW_OP_piece expressions) // as index into History. The full variables including the // piece expressions are attached to the MI. - DIVariable Var = MI.getDebugVariable(); + DIVariable Var = getEntireVariable(MI.getDebugVariable()); if (unsigned PrevReg = Result.getRegisterForVar(Var)) dropRegDescribedVar(RegVars, PrevReg, Var); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index 6cca985cfce..6af049ad683 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -26,30 +26,25 @@ class DebugLocEntry { public: /// A single location or constant. struct Value { - Value(const MDNode *Var, const MDNode *Expr, int64_t i) - : Variable(Var), Expression(Expr), EntryKind(E_Integer) { + Value(const MDNode *Var, int64_t i) + : Variable(Var), EntryKind(E_Integer) { Constant.Int = i; } - Value(const MDNode *Var, const MDNode *Expr, const ConstantFP *CFP) - : Variable(Var), Expression(Expr), EntryKind(E_ConstantFP) { + Value(const MDNode *Var, const ConstantFP *CFP) + : Variable(Var), EntryKind(E_ConstantFP) { Constant.CFP = CFP; } - Value(const MDNode *Var, const MDNode *Expr, const ConstantInt *CIP) - : Variable(Var), Expression(Expr), EntryKind(E_ConstantInt) { + Value(const MDNode *Var, const ConstantInt *CIP) + : Variable(Var), EntryKind(E_ConstantInt) { Constant.CIP = CIP; } - Value(const MDNode *Var, const MDNode *Expr, MachineLocation Loc) - : Variable(Var), Expression(Expr), EntryKind(E_Location), Loc(Loc) { - assert(DIVariable(Var).Verify()); - assert(DIExpression(Expr).Verify()); + Value(const MDNode *Var, MachineLocation Loc) + : Variable(Var), EntryKind(E_Location), Loc(Loc) { } // The variable to which this location entry corresponds. const MDNode *Variable; - // Any complex address location expression for this Value. - const MDNode *Expression; - // Type of entry that this represents. enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt }; enum EntryType EntryKind; @@ -74,8 +69,7 @@ public: MachineLocation getLoc() const { return Loc; } const MDNode *getVariableNode() const { return Variable; } DIVariable getVariable() const { return DIVariable(Variable); } - bool isVariablePiece() const { return getExpression().isVariablePiece(); } - DIExpression getExpression() const { return DIExpression(Expression); } + bool isVariablePiece() const { return getVariable().isVariablePiece(); } friend bool operator==(const Value &, const Value &); friend bool operator<(const Value &, const Value &); }; @@ -96,13 +90,11 @@ public: // list of values. // Return true if the merge was successful. bool MergeValues(const DebugLocEntry &Next) { - if (Begin == Next.Begin) { - DIExpression Expr(Values[0].Expression); + if (Begin == Next.Begin && Values.size() > 0 && Next.Values.size() > 0) { DIVariable Var(Values[0].Variable); - DIExpression NextExpr(Next.Values[0].Expression); DIVariable NextVar(Next.Values[0].Variable); - if (Var == NextVar && Expr.isVariablePiece() && - NextExpr.isVariablePiece()) { + if (Var.getName() == NextVar.getName() && + Var.isVariablePiece() && NextVar.isVariablePiece()) { addValues(Next.Values); End = Next.End; return true; @@ -141,10 +133,8 @@ public: std::sort(Values.begin(), Values.end()); Values.erase(std::unique(Values.begin(), Values.end(), [](const Value &A, const Value &B) { - return A.getVariable() == B.getVariable() && - A.getExpression() == B.getExpression(); - }), - Values.end()); + return A.getVariable() == B.getVariable(); + }), Values.end()); } }; @@ -154,10 +144,7 @@ inline bool operator==(const DebugLocEntry::Value &A, if (A.EntryKind != B.EntryKind) return false; - if (A.Expression != B.Expression) - return false; - - if (A.Variable != B.Variable) + if (A.getVariable() != B.getVariable()) return false; switch (A.EntryKind) { @@ -176,8 +163,7 @@ inline bool operator==(const DebugLocEntry::Value &A, /// Compare two pieces based on their offset. inline bool operator<(const DebugLocEntry::Value &A, const DebugLocEntry::Value &B) { - return A.getExpression().getPieceOffset() < - B.getExpression().getPieceOffset(); + return A.getVariable().getPieceOffset() < B.getVariable().getPieceOffset(); } } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index c54fc989569..4745974a3d2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -901,7 +901,7 @@ void DwarfDebug::collectDeadVariables() { for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { DIVariable DV(Variables.getElement(vi)); assert(DV.isVariable()); - DbgVariable NewVar(DV, DIExpression(nullptr), this); + DbgVariable NewVar(DV, this); auto VariableDie = SPCU->constructVariableDIE(NewVar); SPCU->applyVariableAttributes(NewVar, *VariableDie); SPDIE->addChild(std::move(VariableDie)); @@ -1121,7 +1121,7 @@ DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV) { void DwarfDebug::createAbstractVariable(const DIVariable &Var, LexicalScope *Scope) { - auto AbsDbgVariable = make_unique<DbgVariable>(Var, DIExpression(), this); + auto AbsDbgVariable = make_unique<DbgVariable>(Var, this); addScopeVariable(Scope, AbsDbgVariable.get()); AbstractVariables[Var] = std::move(AbsDbgVariable); } @@ -1177,7 +1177,6 @@ void DwarfDebug::collectVariableInfoFromMMITable( continue; Processed.insert(VI.Var); DIVariable DV(VI.Var); - DIExpression Expr(VI.Expr); LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc); // If variable scope is not found then skip this variable. @@ -1185,7 +1184,7 @@ void DwarfDebug::collectVariableInfoFromMMITable( continue; ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); - ConcreteVariables.push_back(make_unique<DbgVariable>(DV, Expr, this)); + ConcreteVariables.push_back(make_unique<DbgVariable>(DV, this)); DbgVariable *RegVar = ConcreteVariables.back().get(); RegVar->setFrameIndex(VI.Slot); addScopeVariable(Scope, RegVar); @@ -1194,10 +1193,9 @@ void DwarfDebug::collectVariableInfoFromMMITable( // Get .debug_loc entry for the instruction range starting at MI. static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) { - const MDNode *Expr = MI->getDebugExpression(); const MDNode *Var = MI->getDebugVariable(); - assert(MI->getNumOperands() == 4); + assert(MI->getNumOperands() == 3); if (MI->getOperand(0).isReg()) { MachineLocation MLoc; // If the second operand is an immediate, this is a @@ -1206,20 +1204,20 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) { MLoc.set(MI->getOperand(0).getReg()); else MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); - return DebugLocEntry::Value(Var, Expr, MLoc); + return DebugLocEntry::Value(Var, MLoc); } if (MI->getOperand(0).isImm()) - return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getImm()); + return DebugLocEntry::Value(Var, MI->getOperand(0).getImm()); if (MI->getOperand(0).isFPImm()) - return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getFPImm()); + return DebugLocEntry::Value(Var, MI->getOperand(0).getFPImm()); if (MI->getOperand(0).isCImm()) - return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getCImm()); + return DebugLocEntry::Value(Var, MI->getOperand(0).getCImm()); - llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!"); + llvm_unreachable("Unexpected 3 operand DBG_VALUE instruction!"); } /// Determine whether two variable pieces overlap. -static bool piecesOverlap(DIExpression P1, DIExpression P2) { +static bool piecesOverlap(DIVariable P1, DIVariable P2) { if (!P1.isVariablePiece() || !P2.isVariablePiece()) return true; unsigned l1 = P1.getPieceOffset(); @@ -1270,11 +1268,11 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc, } // If this piece overlaps with any open ranges, truncate them. - DIExpression DIExpr = Begin->getDebugExpression(); + DIVariable DIVar = Begin->getDebugVariable(); auto Last = std::remove_if(OpenRanges.begin(), OpenRanges.end(), [&](DebugLocEntry::Value R) { - return piecesOverlap(DIExpr, R.getExpression()); - }); + return piecesOverlap(DIVar, R.getVariable()); + }); OpenRanges.erase(Last, OpenRanges.end()); const MCSymbol *StartLabel = getLabelBeforeInsn(Begin); @@ -1296,7 +1294,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc, bool couldMerge = false; // If this is a piece, it may belong to the current DebugLocEntry. - if (DIExpr.isVariablePiece()) { + if (DIVar.isVariablePiece()) { // Add this value to the list of open ranges. OpenRanges.push_back(Value); @@ -1322,14 +1320,10 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc, if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry)) DebugLoc.pop_back(); - DEBUG({ - dbgs() << CurEntry->getValues().size() << " Values:\n"; - for (auto Value : CurEntry->getValues()) { - Value.getVariable()->dump(); - Value.getExpression()->dump(); - } - dbgs() << "-----\n"; - }); + DEBUG(dbgs() << "Values:\n"; + for (auto Value : CurEntry->getValues()) + Value.getVariable()->dump(); + dbgs() << "-----\n"); } } @@ -1364,7 +1358,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl<const MDNode *> &Processed) { if (!Scope) continue; - Processed.insert(DV); + Processed.insert(getEntireVariable(DV)); const MachineInstr *MInsn = Ranges.front().first; assert(MInsn->isDebugValue() && "History must begin with debug value"); ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); @@ -1398,8 +1392,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl<const MDNode *> &Processed) { continue; if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) { ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); - DIExpression NoExpr; - ConcreteVariables.push_back(make_unique<DbgVariable>(DV, NoExpr, this)); + ConcreteVariables.push_back(make_unique<DbgVariable>(DV, this)); addScopeVariable(Scope, ConcreteVariables.back().get()); } } @@ -1587,17 +1580,18 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // The first mention of a function argument gets the FunctionBeginSym // label, so arguments are visible when breaking at function entry. - DIVariable DIVar(Ranges.front().first->getDebugVariable()); - if (DIVar.isVariable() && DIVar.getTag() == dwarf::DW_TAG_arg_variable && - getDISubprogram(DIVar.getContext()).describes(MF->getFunction())) { - LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym; - if (Ranges.front().first->getDebugExpression().isVariablePiece()) { + DIVariable DV(Ranges.front().first->getDebugVariable()); + if (DV.isVariable() && DV.getTag() == dwarf::DW_TAG_arg_variable && + getDISubprogram(DV.getContext()).describes(MF->getFunction())) { + if (!DV.isVariablePiece()) + LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym; + else { // Mark all non-overlapping initial pieces. for (auto I = Ranges.begin(); I != Ranges.end(); ++I) { - DIExpression Piece = I->first->getDebugExpression(); + DIVariable Piece = I->first->getDebugVariable(); if (std::all_of(Ranges.begin(), I, - [&](DbgValueHistoryMap::InstrRange Pred) { - return !piecesOverlap(Piece, Pred.first->getDebugExpression()); + [&](DbgValueHistoryMap::InstrRange Pred){ + return !piecesOverlap(Piece, Pred.first->getDebugVariable()); })) LabelsBeforeInsn[I->first] = FunctionBeginSym; else @@ -2095,9 +2089,9 @@ void DwarfDebug::emitLocPieces(ByteStreamer &Streamer, unsigned Offset = 0; for (auto Piece : Values) { - DIExpression Expr = Piece.getExpression(); - unsigned PieceOffset = Expr.getPieceOffset(); - unsigned PieceSize = Expr.getPieceSize(); + DIVariable Var = Piece.getVariable(); + unsigned PieceOffset = Var.getPieceOffset(); + unsigned PieceSize = Var.getPieceSize(); assert(Offset <= PieceOffset && "overlapping or duplicate pieces"); if (Offset < PieceOffset) { // The DWARF spec seriously mandates pieces with no locations for gaps. @@ -2108,9 +2102,8 @@ void DwarfDebug::emitLocPieces(ByteStreamer &Streamer, Offset += PieceSize; const unsigned SizeOfByte = 8; -#ifndef NDEBUG - DIVariable Var = Piece.getVariable(); assert(!Var.isIndirect() && "indirect address for piece"); +#ifndef NDEBUG unsigned VarSize = Var.getSizeInBits(Map); assert(PieceSize+PieceOffset <= VarSize/SizeOfByte && "piece is larger than or outside of variable"); @@ -2156,25 +2149,24 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer, } } else if (Value.isLocation()) { MachineLocation Loc = Value.getLoc(); - DIExpression Expr = Value.getExpression(); - if (!Expr) + if (!DV.hasComplexAddress()) // Regular entry. Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect()); else { // Complex address entry. - unsigned N = Expr.getNumElements(); + unsigned N = DV.getNumAddrElements(); unsigned i = 0; - if (N >= 2 && Expr.getElement(0) == dwarf::DW_OP_plus) { + if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { if (Loc.getOffset()) { i = 2; Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect()); Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref"); Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst"); - Streamer.EmitSLEB128(Expr.getElement(1)); + Streamer.EmitSLEB128(DV.getAddrElement(1)); } else { // If first address element is OpPlus then emit // DW_OP_breg + Offset instead of DW_OP_reg + Offset. - MachineLocation TLoc(Loc.getReg(), Expr.getElement(1)); + MachineLocation TLoc(Loc.getReg(), DV.getAddrElement(1)); Asm->EmitDwarfRegOp(Streamer, TLoc, DV.isIndirect()); i = 2; } @@ -2184,14 +2176,14 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer, // Emit remaining complex address elements. for (; i < N; ++i) { - uint64_t Element = Expr.getElement(i); - if (Element == dwarf::DW_OP_plus) { + uint64_t Element = DV.getAddrElement(i); + if (Element == DIBuilder::OpPlus) { Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst"); - Streamer.EmitULEB128(Expr.getElement(++i)); - } else if (Element == dwarf::DW_OP_deref) { + Streamer.EmitULEB128(DV.getAddrElement(++i)); + } else if (Element == DIBuilder::OpDeref) { if (!Loc.isReg()) Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref"); - } else if (Element == dwarf::DW_OP_piece) { + } else if (Element == DIBuilder::OpPiece) { i += 3; // handled in emitDebugLocEntry. } else diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 1432ecd58ae..80f81853ddd 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -70,7 +70,6 @@ public: /// \brief This class is used to track local variable information. class DbgVariable { DIVariable Var; // Variable Descriptor. - DIExpression Expr; // Complex address location expression. DIE *TheDIE; // Variable DIE. unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries. const MachineInstr *MInsn; // DBG_VALUE instruction of the variable. @@ -79,22 +78,18 @@ class DbgVariable { public: /// Construct a DbgVariable from a DIVariable. - DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD) - : Var(V), Expr(E), TheDIE(nullptr), DotDebugLocOffset(~0U), - MInsn(nullptr), FrameIndex(~0), DD(DD) { - assert(Var.Verify() && Expr.Verify()); - } + DbgVariable(DIVariable V, DwarfDebug *DD) + : Var(V), TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(nullptr), + FrameIndex(~0), DD(DD) {} /// Construct a DbgVariable from a DEBUG_VALUE. /// AbstractVar may be NULL. DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD) - : Var(DbgValue->getDebugVariable()), Expr(DbgValue->getDebugExpression()), - TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(DbgValue), - FrameIndex(~0), DD(DD) {} + : Var(DbgValue->getDebugVariable()), TheDIE(nullptr), + DotDebugLocOffset(~0U), MInsn(DbgValue), FrameIndex(~0), DD(DD) {} // Accessors. DIVariable getVariable() const { return Var; } - DIExpression getExpression() const { return Expr; } void setDIE(DIE &D) { TheDIE = &D; } DIE *getDIE() const { return TheDIE; } void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } @@ -129,14 +124,14 @@ public: bool variableHasComplexAddress() const { assert(Var.isVariable() && "Invalid complex DbgVariable!"); - return Expr.getNumElements() > 0; + return Var.hasComplexAddress(); } bool isBlockByrefVariable() const; unsigned getNumAddrElements() const { assert(Var.isVariable() && "Invalid complex DbgVariable!"); - return Expr.getNumElements(); + return Var.getNumAddrElements(); } - uint64_t getAddrElement(unsigned i) const { return Expr.getElement(i); } + uint64_t getAddrElement(unsigned i) const { return Var.getAddrElement(i); } DIType getType() const; private: diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index b19b576cdf3..806b0e76fc6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -607,20 +607,16 @@ void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, unsigned N = DV.getNumAddrElements(); unsigned i = 0; if (Location.isReg()) { - if (N >= 2 && DV.getAddrElement(0) == dwarf::DW_OP_plus) { - assert(!DV.getVariable().isIndirect() && - "double indirection not handled"); + if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { // If first address element is OpPlus then emit // DW_OP_breg + Offset instead of DW_OP_reg + Offset. addRegisterOffset(*Loc, Location.getReg(), DV.getAddrElement(1)); i = 2; - } else if (N >= 2 && DV.getAddrElement(0) == dwarf::DW_OP_deref) { - assert(!DV.getVariable().isIndirect() && - "double indirection not handled"); - addRegisterOpPiece(*Loc, Location.getReg(), - DV.getExpression().getPieceSize(), - DV.getExpression().getPieceOffset()); - i = 3; + } else if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpDeref) { + addRegisterOpPiece(*Loc, Location.getReg(), + DV.getVariable().getPieceSize(), + DV.getVariable().getPieceOffset()); + i = 3; } else addRegisterOpPiece(*Loc, Location.getReg()); } else @@ -628,15 +624,15 @@ void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, for (; i < N; ++i) { uint64_t Element = DV.getAddrElement(i); - if (Element == dwarf::DW_OP_plus) { + if (Element == DIBuilder::OpPlus) { addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); addUInt(*Loc, dwarf::DW_FORM_udata, DV.getAddrElement(++i)); - } else if (Element == dwarf::DW_OP_deref) { + } else if (Element == DIBuilder::OpDeref) { if (!Location.isReg()) addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); - } else if (Element == dwarf::DW_OP_piece) { + } else if (Element == DIBuilder::OpPiece) { const unsigned SizeOfByte = 8; unsigned PieceOffsetInBits = DV.getAddrElement(++i)*SizeOfByte; unsigned PieceSizeInBits = DV.getAddrElement(++i)*SizeOfByte; @@ -1865,7 +1861,7 @@ std::unique_ptr<DIE> DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV, // Check if variable is described by a DBG_VALUE instruction. if (const MachineInstr *DVInsn = DV.getMInsn()) { - assert(DVInsn->getNumOperands() == 4); + assert(DVInsn->getNumOperands() == 3); if (DVInsn->getOperand(0).isReg()) { const MachineOperand RegOp = DVInsn->getOperand(0); // If the second operand is an immediate, this is an indirect value. |