Index: bindings/go/llvm/DIBuilderBindings.h =================================================================== --- bindings/go/llvm/DIBuilderBindings.h +++ bindings/go/llvm/DIBuilderBindings.h @@ -28,16 +28,6 @@ typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef; -LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( - LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name, - LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve, - unsigned Flags, uint32_t AlignInBits); - -LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( - LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name, unsigned ArgNo, - LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve, - unsigned Flags); - LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef D, LLVMMetadataRef Ty, const char *Name, LLVMMetadataRef File, unsigned Line, @@ -54,15 +44,6 @@ LLVMMetadataRef *Data, size_t Length); -LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, - int64_t *Addr, size_t Length); - -LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef D, - LLVMValueRef Storage, - LLVMMetadataRef VarInfo, - LLVMMetadataRef Expr, - LLVMBasicBlockRef Block); - LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef D, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, Index: bindings/go/llvm/DIBuilderBindings.cpp =================================================================== --- bindings/go/llvm/DIBuilderBindings.cpp +++ bindings/go/llvm/DIBuilderBindings.cpp @@ -19,27 +19,6 @@ using namespace llvm; -LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( - LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name, - LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve, - unsigned Flags, uint32_t AlignInBits) { - DIBuilder *D = unwrap(Dref); - return wrap( - D->createAutoVariable(unwrap(Scope), Name, unwrap(File), - Line, unwrap(Ty), AlwaysPreserve, - static_cast(Flags), AlignInBits)); -} - -LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( - LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name, - unsigned ArgNo, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, - int AlwaysPreserve, unsigned Flags) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createParameterVariable( - unwrap(Scope), Name, ArgNo, unwrap(File), Line, - unwrap(Ty), AlwaysPreserve, static_cast(Flags))); -} - LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref, LLVMMetadataRef Ty, const char *Name, LLVMMetadataRef File, unsigned Line, @@ -76,28 +55,6 @@ return wrap(A.get()); } -LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, - int64_t *Addr, size_t Length) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createExpression(ArrayRef(Addr, Length))); -} - -LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref, - LLVMValueRef Storage, - LLVMMetadataRef VarInfo, - LLVMMetadataRef Expr, - LLVMBasicBlockRef Block) { - // Fail immediately here until the llgo folks update their bindings. The - // called function is going to assert out anyway. - llvm_unreachable("DIBuilder API change requires a DebugLoc"); - - DIBuilder *D = unwrap(Dref); - Instruction *Instr = D->insertDeclare( - unwrap(Storage), unwrap(VarInfo), - unwrap(Expr), /* DebugLoc */ nullptr, unwrap(Block)); - return wrap(Instr); -} - LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef Dref, LLVMValueRef Val, LLVMMetadataRef VarInfo, Index: bindings/go/llvm/dibuilder.go =================================================================== --- bindings/go/llvm/dibuilder.go +++ bindings/go/llvm/dibuilder.go @@ -239,12 +239,12 @@ result := C.LLVMDIBuilderCreateAutoVariable( d.ref, scope.C, - name, + name, C.size_t(len(v.Name)), v.File.C, C.unsigned(v.Line), v.Type.C, - boolToCInt(v.AlwaysPreserve), - C.unsigned(v.Flags), + C.LLVMBool(boolToCInt(v.AlwaysPreserve)), + C.LLVMDIFlags(v.Flags), C.uint32_t(v.AlignInBits), ) return Metadata{C: result} @@ -271,13 +271,13 @@ result := C.LLVMDIBuilderCreateParameterVariable( d.ref, scope.C, - name, + name, C.size_t(len(v.Name)), C.unsigned(v.ArgNo), v.File.C, C.unsigned(v.Line), v.Type.C, - boolToCInt(v.AlwaysPreserve), - C.unsigned(v.Flags), + C.LLVMBool(boolToCInt(v.AlwaysPreserve)), + C.LLVMDIFlags(v.Flags), ) return Metadata{C: result} } @@ -564,7 +564,7 @@ // InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the // specified basic block for the given value and associated debug metadata. func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value { - result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C) + result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, nil, bb.C) return Value{C: result} } Index: include/llvm-c/DebugInfo.h =================================================================== --- include/llvm-c/DebugInfo.h +++ include/llvm-c/DebugInfo.h @@ -610,6 +610,80 @@ LLVMDIBuilderCreateArtificialType(LLVMDIBuilderRef Builder, LLVMMetadataRef Type); +/** + * Create a new descriptor for the specified variable which has a complex + * address expression for its address. + * \param Builder The DIBuilder. + * \param Addr An array of complex address operations. + * \param Length Length of the address operation array. + */ +LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder, + int64_t *Addr, size_t Length); + +/** + * Insert a new llvm.dbg.declare intrinsic call before the given instruction. + * \param Builder The DIBuilder. + * \param Storage The storage of the variable to declare. + * \param VarInfo The variable's debug info descriptor. + * \param Expr A complex location expression for the variable. + * \param DebugLoc Debug info location. + * \param Instr Instruction acting as a location for the new intrinsic. + */ +LLVMValueRef LLVMDIBuilderInsertDeclareBefore( + LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr); + +/** + * Insert a new llvm.dbg.declare intrinsic call at the end of the given basic + * block. If the basic block has a terminator instruction, the intrinsic is + * inserted before that terminator instruction. + * \param Builder The DIBuilder. + * \param Storage The storage of the variable to declare. + * \param VarInfo The variable's debug info descriptor. + * \param Expr A complex location expression for the variable. + * \param DebugLoc Debug info location. + * \param Block Basic block acting as a location for the new intrinsic. + */ +LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd( + LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block); + +/** + * Create a new descriptor for a local auto variable. + * \param Builder The DIBuilder. + * \param Scope The local scope the variable is declared in. + * \param Name Variable name. + * \param NameLen Length of variable name. + * \param File File where this variable is defined. + * \param LineNo Line number. + * \param Ty Metadata describing the type of the variable. + * \param AlwaysPreserve If true, this descriptor will survive optimizations. + * \param Flags Flags. + * \param AlignInBits Variable alignment. + */ +LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, + LLVMBool AlwaysPreserve, LLVMDIFlags Flags, uint32_t AlignInBits); + +/** + * Create a new descriptor for a function parameter variable. + * \param Builder The DIBuilder. + * \param Scope The local scope the variable is declared in. + * \param Name Variable name. + * \param NameLen Length of variable name. + * \param ArgNo Unique argument number for this variable; starts at 1. + * \param File File where this variable is defined. + * \param LineNo Line number. + * \param Ty Metadata describing the type of the variable. + * \param AlwaysPreserve If true, this descriptor will survive optimizations. + * \param Flags Flags. + */ +LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo, + LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags); + /** * Get the metadata of the subprogram attached to a function. * Index: lib/IR/DebugInfo.cpp =================================================================== --- lib/IR/DebugInfo.cpp +++ lib/IR/DebugInfo.cpp @@ -996,6 +996,50 @@ Elts, map_from_llvmDIFlags(Flags))); } +LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder, + int64_t *Addr, size_t Length) { + return wrap(unwrap(Builder)->createExpression(ArrayRef(Addr, + Length))); +} + +LLVMValueRef LLVMDIBuilderInsertDeclareBefore( + LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMValueRef Instr) { + return wrap(unwrap(Builder)->insertDeclare( + unwrap(Storage), unwrap(VarInfo), + unwrap(Expr), unwrap(DL), + unwrap(Instr))); +} + +LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd( + LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMBasicBlockRef Block) { + return wrap(unwrap(Builder)->insertDeclare( + unwrap(Storage), unwrap(VarInfo), + unwrap(Expr), unwrap(DL), + unwrap(Block))); +} + +LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, + LLVMBool AlwaysPreserve, LLVMDIFlags Flags, uint32_t AlignInBits) { + return wrap(unwrap(Builder)->createAutoVariable( + unwrap(Scope), {Name, NameLen}, unwrap(File), + LineNo, unwrap(Ty), AlwaysPreserve, + map_from_llvmDIFlags(Flags), AlignInBits)); +} + +LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo, + LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags) { + return wrap(unwrap(Builder)->createParameterVariable( + unwrap(Scope), Name, ArgNo, unwrap(File), + LineNo, unwrap(Ty), AlwaysPreserve, + map_from_llvmDIFlags(Flags))); +} + LLVMMetadataRef LLVMGetSubprogram(LLVMValueRef Func) { return wrap(unwrap(Func)->getSubprogram()); } Index: test/Bindings/llvm-c/debug_info.ll =================================================================== --- test/Bindings/llvm-c/debug_info.ll +++ test/Bindings/llvm-c/debug_info.ll @@ -3,22 +3,33 @@ ; CHECK: ; ModuleID = 'debuginfo.c' ; CHECK-NEXT: source_filename = "debuginfo.c" -; CHECK: declare !dbg !7 i64 @foo(i64, i64) +; CHECK: define i64 @foo(i64, i64) !dbg !7 { +; CHECK-NEXT: entry: +; CHECK-NEXT: call void @llvm.dbg.declare(metadata i64 0, metadata !11, metadata !DIExpression()), !dbg !13 +; CHECK-NEXT: call void @llvm.dbg.declare(metadata i64 0, metadata !12, metadata !DIExpression()), !dbg !13 +; CHECK-NEXT: } -; CHECK: declare !dbg !10 i64 @foo_inner_scope(i64, i64) +; CHECK: declare void @llvm.dbg.declare(metadata, metadata, metadata) #0 + +; CHECK: declare !dbg !14 i64 @foo_inner_scope(i64, i64) ; CHECK: !llvm.dbg.cu = !{!0} ; CHECK-NEXT: !FooType = !{!3} -; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false) +; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false) ; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c", directory: ".") ; CHECK-NEXT: !2 = !{} ; CHECK-NEXT: !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 192, dwarfAddressSpace: 0) ; CHECK-NEXT: !4 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", file: !1, size: 192, elements: !5, runtimeLang: DW_LANG_C89, identifier: "MyStruct") ; CHECK-NEXT: !5 = !{!6, !6, !6} ; CHECK-NEXT: !6 = !DIBasicType(name: "Int64", size: 64) -; CHECK-NEXT: !7 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !8, isLocal: true, isDefinition: true, scopeLine: 42, isOptimized: false, unit: !0, variables: !2) +; CHECK-NEXT: !7 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !8, isLocal: true, isDefinition: true, scopeLine: 42, isOptimized: false, unit: !0, variables: !10) ; CHECK-NEXT: !8 = !DISubroutineType(types: !9) ; CHECK-NEXT: !9 = !{!6, !6} -; CHECK-NEXT: !10 = distinct !DISubprogram(name: "foo_inner_scope", linkageName: "foo_inner_scope", scope: !11, file: !1, line: 42, type: !8, isLocal: true, isDefinition: true, scopeLine: 42, isOptimized: false, unit: !0, variables: !2) -; CHECK-NEXT: !11 = distinct !DILexicalBlock(scope: !7, file: !1, line: 42) +; CHECK-NEXT: !10 = !{!11, !12} +; CHECK-NEXT: !11 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 42, type: !6) +; CHECK-NEXT: !12 = !DILocalVariable(name: "b", arg: 2, scope: !7, file: !1, line: 42, type: !6) +; CHECK-NEXT: !13 = !DILocation(line: 42, scope: !7) +; CHECK-NEXT: !14 = distinct !DISubprogram(name: "foo_inner_scope", linkageName: "foo_inner_scope", scope: !15, file: !1, line: 42, type: !8, isLocal: true, isDefinition: true, scopeLine: 42, isOptimized: false, unit: !0, variables: !2) +; CHECK-NEXT: !15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 42) + Index: tools/llvm-c-test/debuginfo.c =================================================================== --- tools/llvm-c-test/debuginfo.c +++ tools/llvm-c-test/debuginfo.c @@ -48,6 +48,7 @@ LLVMTypeRef FooParamTys[] = { LLVMInt64Type(), LLVMInt64Type() }; LLVMTypeRef FooFuncTy = LLVMFunctionType(LLVMInt64Type(), FooParamTys, 2, 0); LLVMValueRef FooFunction = LLVMAddFunction(M, "foo", FooFuncTy); + LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(FooFunction, "entry"); LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty}; LLVMMetadataRef FunctionTy = @@ -56,6 +57,23 @@ LLVMDIBuilderCreateFunction(DIB, File, "foo", 3, "foo", 3, File, 42, FunctionTy, true, true, 42, 0, false); + LLVMMetadataRef FooParamLocation = + LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 42, 0, + FunctionMetadata, NULL); + LLVMMetadataRef FooParamExpression = + LLVMDIBuilderCreateExpression(DIB, NULL, 0); + LLVMMetadataRef FooParamVar1 = + LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File, + 42, Int64Ty, true, 0); + LLVMDIBuilderInsertDeclareAtEnd(DIB, LLVMConstInt(LLVMInt64Type(), 0, false), + FooParamVar1, FooParamExpression, + FooParamLocation, FooEntryBlock); + LLVMMetadataRef FooParamVar2 = + LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "b", 1, 2, File, + 42, Int64Ty, true, 0); + LLVMDIBuilderInsertDeclareAtEnd(DIB, LLVMConstInt(LLVMInt64Type(), 0, false), + FooParamVar2, FooParamExpression, + FooParamLocation, FooEntryBlock); LLVMSetSubprogram(FooFunction, FunctionMetadata); LLVMMetadataRef FooLexicalBlock =