Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -960,12 +960,12 @@ assert(DVInst->isDebugValue() && "Invalid History entry"); // FIXME: Find a way to represent constant variables, since they are // relatively common. - DbgVariableLocation Location; - bool Supported = - DbgVariableLocation::extractFromMachineInstruction(Location, *DVInst); - // If not Supported, don't even look at Location because it's invalid. - if (!Supported) + Expected Location = + DbgVariableLocation::extractFromMachineInstruction(*DVInst); + if (!Location) { + consumeError(Location.takeError()); continue; + } // Because we cannot express DW_OP_deref in CodeView directly, // we use a trick: we encode the type as a reference to the @@ -975,13 +975,13 @@ // we need to remove a level of indirection from incoming locations. // E.g. [RSP+8] with DW_OP_deref becomes [RSP+8], // and [RCX+0] without DW_OP_deref becomes RCX. - if (!Location.Deref) { - if (Location.InMemory) - Location.InMemory = false; + if (!Location->Deref) { + if (Location->InMemory) + Location->InMemory = false; else - Supported = false; + continue; } - } else if (Location.Deref) { + } else if (Location->Deref) { // We've encountered a Deref range when we had not applied the // reference encoding. Start over using reference encoding. Var.Deref = true; @@ -991,19 +991,18 @@ } // If we don't know how to handle this range, skip past it. - if (!Supported || Location.Register == 0 || - (Location.Offset && !Location.InMemory)) + if (Location->Register == 0 || (Location->Offset && !Location->InMemory)) continue; // Handle the two cases we can handle: indirect in memory and in register. { LocalVarDefRange DR; - DR.CVRegister = TRI->getCodeViewRegNum(Location.Register); - DR.InMemory = Location.InMemory; - DR.DataOffset = Location.Offset; - if (Location.FragmentInfo) { + DR.CVRegister = TRI->getCodeViewRegNum(Location->Register); + DR.InMemory = Location->InMemory; + DR.DataOffset = Location->Offset; + if (Location->FragmentInfo) { DR.IsSubfield = true; - DR.StructOffset = Location.FragmentInfo->OffsetInBits / 8; + DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8; } else { DR.IsSubfield = false; DR.StructOffset = 0; Index: llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h +++ llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h @@ -21,6 +21,7 @@ #include "llvm/CodeGen/LexicalScopes.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/Support/Error.h" namespace llvm { @@ -47,12 +48,13 @@ /// Present if the location is part of a larger variable. llvm::Optional FragmentInfo; - /// Extract a VariableLocation from a MachineInstr. The struct passed in as - /// Location is populated. The MachineInstr must be a debug value - /// instruction. - /// @return true if successful and false if not. - static bool extractFromMachineInstruction(DbgVariableLocation &Location, - const MachineInstr &Instruction); + /// Extract a VariableLocation from a MachineInstr. + /// This will only work if Instruction is a debug value instruction + /// and the associated DIExpression is in one of the supported forms. + /// If these requirements are not met, this function will return an + /// Error value. + static Expected + extractFromMachineInstruction(const MachineInstr &Instruction); }; /// Base class for debug information backends. Common functionality related to Index: llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -13,22 +13,30 @@ //===----------------------------------------------------------------------===// #include "DebugHandlerBase.h" +#include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/IR/DebugInfo.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/Support/Error.h" #include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; -bool DbgVariableLocation::extractFromMachineInstruction( - DbgVariableLocation &Location, const MachineInstr &Instruction) { +Expected +DbgVariableLocation::extractFromMachineInstruction( + const MachineInstr &Instruction) { + DbgVariableLocation Location; if (!Instruction.isDebugValue()) - return false; + return make_error("extractFromMachineInstruction instruction " + "is not a debug value instruction", + inconvertibleErrorCode()); if (!Instruction.getOperand(0).isReg()) - return false; + return make_error( + "extractFromMachineInstruction requires first operand to be a register", + inconvertibleErrorCode()); Location.Register = Instruction.getOperand(0).getReg(); Location.InMemory = Instruction.getOperand(1).isImm(); Location.Deref = false; @@ -65,13 +73,15 @@ Location.Deref = true; break; default: - return false; + return make_error("unsupported DW_OP " + Twine(Op->getOp()) + + " in extractFromMachineInstruction", + inconvertibleErrorCode()); } ++Op; } Location.Offset = Offset; - return true; + return Location; } DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}