Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -4821,6 +4821,10 @@ metadata !DIExpression(DW_OP_LLVM_arg0, DW_OP_LLVM_arg1, DW_OP_plus))`` ``DW_OP_LLVM_arg0`` represents ``DILocalVariable("x")`` and ``DW_OP_LLVM_arg1`` represents ``DILocalVariable("y")``. +- ``DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0 N`` can only appear at the + beginning of a ``DIExpression``, and it specifies the value of variable + represented by the ``DILocalVariable`` referred to by the instructions + value/address operand at offset N. DWARF specifies three kinds of simple location descriptions: Register, memory, and implicit location descriptions. Note that a location description is Index: llvm/include/llvm/BinaryFormat/Dwarf.h =================================================================== --- llvm/include/llvm/BinaryFormat/Dwarf.h +++ llvm/include/llvm/BinaryFormat/Dwarf.h @@ -129,6 +129,7 @@ DW_OP_LLVM_arg5 = 0x1009, ///< Only used in LLVM metadata. DW_OP_LLVM_arg6 = 0x100a, ///< Only used in LLVM metadata. DW_OP_LLVM_arg7 = 0x100b, ///< Only used in LLVM metadata. + DW_OP_LLVM_implicit_pointer = 0x100c, ///< Only used in LLVM metadata. }; enum TypeKind : uint8_t { Index: llvm/lib/BinaryFormat/Dwarf.cpp =================================================================== --- llvm/lib/BinaryFormat/Dwarf.cpp +++ llvm/lib/BinaryFormat/Dwarf.cpp @@ -167,6 +167,8 @@ return "DW_OP_LLVM_arg6"; case DW_OP_LLVM_arg7: return "DW_OP_LLVM_arg7"; + case DW_OP_LLVM_implicit_pointer: + return "DW_OP_LLVM_implicit_pointer"; } } @@ -187,6 +189,7 @@ .Case("DW_OP_LLVM_arg5", DW_OP_LLVM_arg5) .Case("DW_OP_LLVM_arg6", DW_OP_LLVM_arg6) .Case("DW_OP_LLVM_arg7", DW_OP_LLVM_arg7) + .Case("DW_OP_LLVM_implicit_pointer", DW_OP_LLVM_implicit_pointer) .Default(0); } Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -2150,6 +2150,9 @@ if (I->getOp() == dwarf::DW_OP_LLVM_convert) { Out << FS << I->getArg(0); Out << FS << dwarf::AttributeEncodingString(I->getArg(1)); + } else if (I->getOp() == dwarf::DW_OP_LLVM_implicit_pointer) { + Out << FS << dwarf::OperationEncodingString(I->getArg(0)); + Out << FS << I->getArg(1); } else { for (unsigned A = 0, AE = I->getNumArgs(); A != AE; ++A) Out << FS << I->getArg(A); Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -837,6 +837,7 @@ case dwarf::DW_OP_LLVM_convert: case dwarf::DW_OP_LLVM_fragment: case dwarf::DW_OP_bregx: + case dwarf::DW_OP_LLVM_implicit_pointer: return 3; case dwarf::DW_OP_constu: case dwarf::DW_OP_consts: @@ -899,6 +900,13 @@ return I->get() == expr_op_begin()->get() && I->getArg(0) == 1 && getNumElements() == 2; } + case dwarf::DW_OP_LLVM_implicit_pointer: { + // A DW_OP_LLVM_implicit_pointer operator must appear at the beginning + // and it has two arguments, DW_OP_LLVM_arg0 and offset N. + return (I == expr_op_begin()) && + (I->getArg(0) == dwarf::DW_OP_LLVM_arg0) && + (getNumElements() == 3); + } case dwarf::DW_OP_LLVM_convert: case dwarf::DW_OP_LLVM_tag_offset: case dwarf::DW_OP_constu: