index c54fc98956959f03c101053e233f3574a42a1f98..4745974a3d2fbbdd96bd473451d1f5fda2f4cf1e 100644 (file)
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));
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);
}
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.
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);
// 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
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();
}
// 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);
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);
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");
}
}
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());
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());
}
}
// 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
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.
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");
}
} 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;
}
// 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