Index: llvm/lib/DWARFLinker/DWARFLinker.cpp =================================================================== --- llvm/lib/DWARFLinker/DWARFLinker.cpp +++ llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -923,15 +923,20 @@ OutputBuffer.push_back(Op.getRawOperand(0)); RefOffset = Op.getRawOperand(1); } - auto RefDie = Unit.getOrigUnit().getDIEForOffset(RefOffset); - uint32_t RefIdx = Unit.getOrigUnit().getDIEIndex(RefDie); - CompileUnit::DIEInfo &Info = Unit.getInfo(RefIdx); uint32_t Offset = 0; - if (DIE *Clone = Info.Clone) - Offset = Clone->getOffset(); - else - Linker.reportWarning("base type ref doesn't point to DW_TAG_base_type.", - File); + // Look up the base type. For DW_OP_convert, the operand may be 0 to + // instead indicate the generic type. The same holds for + // DW_OP_reinterpret, which currently is not supported. + if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) { + auto RefDie = Unit.getOrigUnit().getDIEForOffset(RefOffset); + uint32_t RefIdx = Unit.getOrigUnit().getDIEIndex(RefDie); + CompileUnit::DIEInfo &Info = Unit.getInfo(RefIdx); + if (DIE *Clone = Info.Clone) + Offset = Clone->getOffset(); + else + Linker.reportWarning("base type ref doesn't point to DW_TAG_base_type.", + File); + } uint8_t ULEB[16]; unsigned RealSize = encodeULEB128(Offset, ULEB, ULEBsize); if (RealSize > ULEBsize) { Index: llvm/test/tools/dsymutil/Inputs/op-convert.ll =================================================================== --- llvm/test/tools/dsymutil/Inputs/op-convert.ll +++ llvm/test/tools/dsymutil/Inputs/op-convert.ll @@ -9,6 +9,7 @@ call void @llvm.dbg.value(metadata i8 42, metadata !17, metadata !DIExpression(DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value)), !dbg !12 call void @llvm.dbg.value(metadata i8 %x, metadata !11, metadata !DIExpression()), !dbg !12 call void @llvm.dbg.value(metadata i8 %x, metadata !13, metadata !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value)), !dbg !15 + call void @llvm.dbg.value(metadata i8 51, metadata !18, metadata !DIExpression(DW_OP_LLVM_convert_generic, DW_OP_stack_value)), !dbg !15 ret i8 %x, !dbg !16 } @@ -43,3 +44,4 @@ !15 = !DILocation(line: 3, column: 14, scope: !7) !16 = !DILocation(line: 4, column: 3, scope: !7) !17 = !DILocalVariable(name: "c", scope: !7, file: !1, line: 3, type: !14) +!18 = !DILocalVariable(name: "d", scope: !7, file: !1, line: 3, type: !14) Index: llvm/test/tools/dsymutil/X86/op-convert.test =================================================================== --- llvm/test/tools/dsymutil/X86/op-convert.test +++ llvm/test/tools/dsymutil/X86/op-convert.test @@ -26,6 +26,10 @@ CHECK-NEXT: [0x0000000000001002, 0x0000000000001003): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_convert (0x0000002a) "DW_ATE_signed_8", DW_OP_convert (0x00000031) "DW_ATE_signed_32", DW_OP_stack_value) CHECK-NEXT: DW_AT_name ("y") +CHECK: DW_TAG_variable +CHECK-NEXT: DW_AT_location (DW_OP_constu 0x33, DW_OP_convert 0x0, DW_OP_stack_value) +CHECK-NEXT: DW_AT_name ("d") + CHECK: DW_TAG_variable CHECK-NEXT: DW_AT_location (DW_OP_constu 0x2a, DW_OP_convert (0x00000031) "DW_ATE_signed_32", DW_OP_stack_value) CHECK-NEXT: DW_AT_name ("c")