[LLVM-C] Add DIBuilder Bindings For Variable Creation
authorRobert Widmann <devteam.codafi@gmail.com>
Sun, 22 Apr 2018 19:24:44 +0000 (19:24 +0000)
committerRobert Widmann <devteam.codafi@gmail.com>
Sun, 22 Apr 2018 19:24:44 +0000 (19:24 +0000)
Summary: Wrap LLVMDIBuilderCreateAutoVariable, LLVMDIBuilderCreateParameterVariable, LLVMDIBuilderCreateExpression, and move and correct LLVMDIBuilderInsertDeclareBefore and LLVMDIBuilderInsertDeclareAtEnd from the Go bindings to the C bindings.

Reviewers: harlanhaskins, whitequark, deadalnix

Reviewed By: harlanhaskins, whitequark

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D45928

llvm-svn: 330555

llvm/bindings/go/llvm/DIBuilderBindings.cpp
llvm/bindings/go/llvm/DIBuilderBindings.h
llvm/bindings/go/llvm/dibuilder.go
llvm/include/llvm-c/DebugInfo.h
llvm/lib/IR/DebugInfo.cpp
llvm/test/Bindings/llvm-c/debug_info.ll
llvm/tools/llvm-c-test/debuginfo.c

index d9ffee8..8855c0b 100644 (file)
 
 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<DIScope>(Scope), Name, unwrap<DIFile>(File),
-                            Line, unwrap<DIType>(Ty), AlwaysPreserve,
-                            static_cast<DINode::DIFlags>(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<DIScope>(Scope), Name, ArgNo, unwrap<DIFile>(File), Line,
-      unwrap<DIType>(Ty), AlwaysPreserve, static_cast<DINode::DIFlags>(Flags)));
-}
-
 LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref,
                                            LLVMMetadataRef Ty, const char *Name,
                                            LLVMMetadataRef File, unsigned Line,
@@ -76,28 +55,6 @@ LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref,
   return wrap(A.get());
 }
 
-LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref,
-                                              int64_t *Addr, size_t Length) {
-  DIBuilder *D = unwrap(Dref);
-  return wrap(D->createExpression(ArrayRef<int64_t>(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<DILocalVariable>(VarInfo),
-      unwrap<DIExpression>(Expr), /* DebugLoc */ nullptr, unwrap(Block));
-  return wrap(Instr);
-}
-
 LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef Dref,
                                            LLVMValueRef Val,
                                            LLVMMetadataRef VarInfo,
index effc5d6..4cb612c 100644 (file)
@@ -28,16 +28,6 @@ extern "C" {
 
 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 LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef D,
                                                   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 a7eed58..fd915e7 100644 (file)
@@ -239,12 +239,12 @@ func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadat
        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 @@ func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariabl
        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 @@ func (d *DIBuilder) CreateExpression(addr []int64) Metadata {
 // 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 1fbf3ca..9f71857 100644 (file)
@@ -611,6 +611,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.
  *
  * @see llvm::Function::getSubprogram()
index fbe5689..a2c949b 100644 (file)
@@ -996,6 +996,50 @@ LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder,
     Elts, map_from_llvmDIFlags(Flags)));
 }
 
+LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder,
+                                              int64_t *Addr, size_t Length) {
+  return wrap(unwrap(Builder)->createExpression(ArrayRef<int64_t>(Addr,
+                                                                  Length)));
+}
+
+LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
+  LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo,
+  LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMValueRef Instr) {
+  return wrap(unwrap(Builder)->insertDeclare(
+                  unwrap(Storage), unwrap<DILocalVariable>(VarInfo),
+                  unwrap<DIExpression>(Expr), unwrap<DILocation>(DL),
+                  unwrap<Instruction>(Instr)));
+}
+
+LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
+    LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo,
+    LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMBasicBlockRef Block) {
+  return wrap(unwrap(Builder)->insertDeclare(
+                  unwrap(Storage), unwrap<DILocalVariable>(VarInfo),
+                  unwrap<DIExpression>(Expr), unwrap<DILocation>(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<DIScope>(Scope), {Name, NameLen}, unwrap<DIFile>(File),
+                  LineNo, unwrap<DIType>(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<DIScope>(Scope), Name, ArgNo, unwrap<DIFile>(File),
+                  LineNo, unwrap<DIType>(Ty), AlwaysPreserve,
+                  map_from_llvmDIFlags(Flags)));
+}
+
 LLVMMetadataRef LLVMGetSubprogram(LLVMValueRef Func) {
   return wrap(unwrap<Function>(Func)->getSubprogram());
 }
index d61a47c..a25a7ae 100644 (file)
@@ -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 2d594d0..b1cc851 100644 (file)
@@ -48,6 +48,7 @@ int llvm_test_dibuilder(void) {
   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 @@ int llvm_test_dibuilder(void) {
     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 =