Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -987,27 +987,54 @@ bool InMemory = DVInst->getOperand(1).isImm(); bool IsSubfield = false; unsigned StructOffset = 0; - // Recognize a +Offset expression. - int Offset = 0; DIExpressionCursor Ops(DIExpr); - auto Op = Ops.peek(); - if (Op && Op->getOp() == dwarf::DW_OP_plus_uconst) { - Offset = Op->getArg(0); + auto Fragment = Ops.getFragmentInfo(); + bool Deref = false; + bool Supported = true; + // Extract the offset from DIExpr. + Optional Op; + std::vector Stack{0}; + while ((Op = Ops.peek())) { + switch (Op->getOp()) { + case dwarf::DW_OP_constu: + Stack.push_back(Op->getArg(0)); + break; + case dwarf::DW_OP_minus: + Stack[Stack.size() - 2] -= Stack[Stack.size() - 1]; + Stack.pop_back(); + break; + case dwarf::DW_OP_plus: + Stack[Stack.size() - 2] += Stack[Stack.size() - 1]; + Stack.pop_back(); + break; + case dwarf::DW_OP_plus_uconst: + Stack[Stack.size() - 1] += Op->getArg(0); + break; + // Ignore ops that don't affect the computation. + case dwarf::DW_OP_LLVM_fragment: + case dwarf::DW_OP_deref: + Deref = true; + break; + // Mark the range as unsupported if we encounter an unknown op. + default: + Supported = false; + } Ops.take(); } + int Offset = Stack.empty() ? 0 : Stack[0]; + if (Stack.size() != 1) + Supported = false; + + // If we don't know how to handle this range, skip past it. + if (!Supported || (Offset && !InMemory)) + continue; + // Handle fragments. - auto Fragment = Ops.getFragmentInfo(); if (Fragment) { IsSubfield = true; StructOffset = Fragment->OffsetInBits / 8; } - // Ignore unrecognized exprs. - if (Ops.peek() && Ops.peek()->getOp() != dwarf::DW_OP_LLVM_fragment) - continue; - if (!InMemory && Offset) - continue; - // Bail if operand 0 is not a valid register. This means the variable is a // simple constant, or is described by a complex expression. // FIXME: Find a way to represent constant variables, since they are