Add C API bindings for DIBuilder 'Type' APIs
authorHarlan Haskins <harlan@harlanhaskins.com>
Mon, 2 Apr 2018 00:17:40 +0000 (00:17 +0000)
committerHarlan Haskins <harlan@harlanhaskins.com>
Mon, 2 Apr 2018 00:17:40 +0000 (00:17 +0000)
This patch adds a set of unstable C API bindings to the DIBuilder interface for
creating structure, function, and aggregate types.

This patch also removes the existing implementations of these functions from
the Go bindings and updates the Go API to fit the new C APIs.

llvm-svn: 328953

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 ea53694..9083bd3 100644 (file)
 
 using namespace llvm;
 
-LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef mref) {
-  Module *m = unwrap(mref);
-  return wrap(new DIBuilder(*m));
-}
-
-void LLVMDIBuilderDestroy(LLVMDIBuilderRef dref) {
-  DIBuilder *d = unwrap(dref);
-  delete d;
-}
-
 LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
                                                 LLVMMetadataRef Scope,
                                                 LLVMMetadataRef File,
@@ -83,82 +73,6 @@ LLVMMetadataRef LLVMDIBuilderCreateParameterVariable(
       unwrap<DIType>(Ty), AlwaysPreserve, static_cast<DINode::DIFlags>(Flags)));
 }
 
-LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref,
-                                             const char *Name,
-                                             uint64_t SizeInBits,
-                                             unsigned Encoding) {
-  DIBuilder *D = unwrap(Dref);
-  return wrap(D->createBasicType(Name, SizeInBits, Encoding));
-}
-
-LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
-                                               LLVMMetadataRef PointeeType,
-                                               uint64_t SizeInBits,
-                                               uint32_t AlignInBits,
-                                               const char *Name) {
-  DIBuilder *D = unwrap(Dref);
-  return wrap(D->createPointerType(unwrap<DIType>(PointeeType), SizeInBits,
-                                   AlignInBits, /* DWARFAddressSpace */ None,
-                                   Name));
-}
-
-LLVMMetadataRef
-LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref, LLVMMetadataRef File,
-                                  LLVMMetadataRef ParameterTypes) {
-  DIBuilder *D = unwrap(Dref);
-  return wrap(
-      D->createSubroutineType(DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
-}
-
-LLVMMetadataRef LLVMDIBuilderCreateStructType(
-    LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name,
-    LLVMMetadataRef File, unsigned Line, uint64_t SizeInBits,
-    uint32_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom,
-    LLVMMetadataRef ElementTypes) {
-  DIBuilder *D = unwrap(Dref);
-  return wrap(D->createStructType(
-      unwrap<DIScope>(Scope), Name, File ? unwrap<DIFile>(File) : nullptr, Line,
-      SizeInBits, AlignInBits, static_cast<DINode::DIFlags>(Flags),
-      DerivedFrom ? unwrap<DIType>(DerivedFrom) : nullptr,
-      ElementTypes ? DINodeArray(unwrap<MDTuple>(ElementTypes)) : nullptr));
-}
-
-LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType(
-    LLVMDIBuilderRef Dref, unsigned Tag, const char *Name,
-    LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line,
-    unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,
-    unsigned Flags) {
-  DIBuilder *D = unwrap(Dref);
-  return wrap(D->createReplaceableCompositeType(
-      Tag, Name, unwrap<DIScope>(Scope), File ? unwrap<DIFile>(File) : nullptr,
-      Line, RuntimeLang, SizeInBits, AlignInBits,
-      static_cast<DINode::DIFlags>(Flags)));
-}
-
-LLVMMetadataRef
-LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef Dref, LLVMMetadataRef Scope,
-                              const char *Name, LLVMMetadataRef File,
-                              unsigned Line, uint64_t SizeInBits,
-                              uint32_t AlignInBits, uint64_t OffsetInBits,
-                              unsigned Flags, LLVMMetadataRef Ty) {
-  DIBuilder *D = unwrap(Dref);
-  return wrap(D->createMemberType(
-      unwrap<DIScope>(Scope), Name, File ? unwrap<DIFile>(File) : nullptr, Line,
-      SizeInBits, AlignInBits, OffsetInBits,
-      static_cast<DINode::DIFlags>(Flags), unwrap<DIType>(Ty)));
-}
-
-LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref,
-                                             uint64_t SizeInBits,
-                                             uint32_t AlignInBits,
-                                             LLVMMetadataRef ElementType,
-                                             LLVMMetadataRef Subscripts) {
-  DIBuilder *D = unwrap(Dref);
-  return wrap(D->createArrayType(SizeInBits, AlignInBits,
-                                 unwrap<DIType>(ElementType),
-                                 DINodeArray(unwrap<MDTuple>(Subscripts))));
-}
-
 LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref,
                                            LLVMMetadataRef Ty, const char *Name,
                                            LLVMMetadataRef File, unsigned Line,
index cc5d2c1..a3063fa 100644 (file)
@@ -28,10 +28,6 @@ extern "C" {
 
 typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef;
 
-LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef m);
-
-void LLVMDIBuilderDestroy(LLVMDIBuilderRef d);
-
 LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef D,
                                                 LLVMMetadataRef Scope,
                                                 LLVMMetadataRef File,
@@ -58,45 +54,6 @@ LLVMMetadataRef LLVMDIBuilderCreateParameterVariable(
     LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve,
     unsigned Flags);
 
-LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef D,
-                                             const char *Name,
-                                             uint64_t SizeInBits,
-                                             unsigned Encoding);
-
-LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef D,
-                                               LLVMMetadataRef PointeeType,
-                                               uint64_t SizeInBits,
-                                               uint32_t AlignInBits,
-                                               const char *Name);
-
-LLVMMetadataRef
-LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef D, LLVMMetadataRef File,
-                                  LLVMMetadataRef ParameterTypes);
-
-LLVMMetadataRef LLVMDIBuilderCreateStructType(
-    LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name,
-    LLVMMetadataRef File, unsigned Line, uint64_t SizeInBits,
-    uint32_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom,
-    LLVMMetadataRef ElementTypes);
-
-LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType(
-    LLVMDIBuilderRef D, unsigned Tag, const char *Name, LLVMMetadataRef Scope,
-    LLVMMetadataRef File, unsigned Line, unsigned RuntimeLang,
-    uint64_t SizeInBits, uint32_t AlignInBits, unsigned Flags);
-
-LLVMMetadataRef
-LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef D, LLVMMetadataRef Scope,
-                              const char *Name, LLVMMetadataRef File,
-                              unsigned Line, uint64_t SizeInBits,
-                              uint32_t AlignInBits, uint64_t OffsetInBits,
-                              unsigned Flags, LLVMMetadataRef Ty);
-
-LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef D,
-                                             uint64_t SizeInBits,
-                                             uint32_t AlignInBits,
-                                             LLVMMetadataRef ElementType,
-                                             LLVMMetadataRef Subscripts);
-
 LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef D,
                                            LLVMMetadataRef Ty, const char *Name,
                                            LLVMMetadataRef File, unsigned Line,
index 475fa68..72131bd 100644 (file)
@@ -95,13 +95,13 @@ type DIBuilder struct {
 
 // NewDIBuilder creates a new DIBuilder, associated with the given module.
 func NewDIBuilder(m Module) *DIBuilder {
-       d := C.LLVMNewDIBuilder(m.C)
+       d := C.LLVMCreateDIBuilder(m.C)
        return &DIBuilder{ref: d, m: m}
 }
 
 // Destroy destroys the DIBuilder.
 func (d *DIBuilder) Destroy() {
-       C.LLVMDIBuilderDestroy(d.ref)
+       C.LLVMDisposeDIBuilder(d.ref)
 }
 
 // FInalize finalizes the debug information generated by the DIBuilder.
@@ -147,7 +147,7 @@ func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Metadata {
        return Metadata{C: result}
 }
 
-// CreateCompileUnit creates file debug metadata.
+// CreateFile creates file debug metadata.
 func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
        cfilename := C.CString(filename)
        defer C.free(unsafe.Pointer(cfilename))
@@ -166,7 +166,7 @@ type DILexicalBlock struct {
        Column int
 }
 
-// CreateCompileUnit creates lexical block debug metadata.
+// CreateLexicalBlock creates lexical block debug metadata.
 func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
        result := C.LLVMDIBuilderCreateLexicalBlock(
                d.ref,
@@ -198,7 +198,7 @@ type DIFunction struct {
        Optimized    bool
 }
 
-// CreateCompileUnit creates function debug metadata.
+// CreateFunction creates function debug metadata.
 func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata {
        name := C.CString(f.Name)
        defer C.free(unsafe.Pointer(name))
@@ -296,7 +296,8 @@ func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
        result := C.LLVMDIBuilderCreateBasicType(
                d.ref,
                name,
-               C.uint64_t(t.SizeInBits),
+               C.size_t(len(t.Name)),
+               C.unsigned(t.SizeInBits),
                C.unsigned(t.Encoding),
        )
        return Metadata{C: result}
@@ -307,19 +308,22 @@ type DIPointerType struct {
        Pointee     Metadata
        SizeInBits  uint64
        AlignInBits uint32 // optional
+       AddressSpace uint32
        Name        string // optional
 }
 
-// CreateBasicType creates basic type debug metadata.
+// CreatePointerType creates a type that represents a pointer to another type.
 func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
        name := C.CString(t.Name)
        defer C.free(unsafe.Pointer(name))
        result := C.LLVMDIBuilderCreatePointerType(
                d.ref,
                t.Pointee.C,
-               C.uint64_t(t.SizeInBits),
-               C.uint32_t(t.AlignInBits),
+               C.unsigned(t.SizeInBits),
+               C.unsigned(t.AlignInBits),
+               C.unsigned(t.AddressSpace),
                name,
+               C.size_t(len(t.Name)),
        )
        return Metadata{C: result}
 }
@@ -332,12 +336,20 @@ type DISubroutineType struct {
        // Parameters contains the subroutine parameter types,
        // including the return type at the 0th index.
        Parameters []Metadata
+
+       Flags int
 }
 
 // CreateSubroutineType creates subroutine type debug metadata.
 func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
-       params := d.getOrCreateTypeArray(t.Parameters)
-       result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C)
+       params, length := llvmMetadataRefs(t.Parameters)
+       result := C.LLVMDIBuilderCreateSubroutineType(
+               d.ref,
+               t.File.C,
+               params,
+               length,
+               C.LLVMDIFlags(t.Flags),
+       )
        return Metadata{C: result}
 }
 
@@ -351,24 +363,34 @@ type DIStructType struct {
        Flags       int
        DerivedFrom Metadata
        Elements    []Metadata
+       VTableHolder Metadata // optional
+       UniqueID     string
 }
 
 // CreateStructType creates struct type debug metadata.
 func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
-       elements := d.getOrCreateArray(t.Elements)
+       elements, length := llvmMetadataRefs(t.Elements)
        name := C.CString(t.Name)
+       uniqueID := C.CString(t.UniqueID)
        defer C.free(unsafe.Pointer(name))
+       defer C.free(unsafe.Pointer(uniqueID))
        result := C.LLVMDIBuilderCreateStructType(
                d.ref,
                scope.C,
                name,
+               C.size_t(len(t.Name)),
                t.File.C,
                C.unsigned(t.Line),
-               C.uint64_t(t.SizeInBits),
-               C.uint32_t(t.AlignInBits),
-               C.unsigned(t.Flags),
+               C.unsigned(t.SizeInBits),
+               C.unsigned(t.AlignInBits),
+               C.LLVMDIFlags(t.Flags),
                t.DerivedFrom.C,
-               elements.C,
+               elements,
+               length,
+               C.unsigned(0), // Optional Objective-C runtime version.
+               t.VTableHolder.C,
+               uniqueID,
+               C.uint64_t(len(t.UniqueID)),
        )
        return Metadata{C: result}
 }
@@ -384,23 +406,29 @@ type DIReplaceableCompositeType struct {
        SizeInBits  uint64
        AlignInBits uint32
        Flags       int
+       UniqueID    string
 }
 
 // CreateReplaceableCompositeType creates replaceable composite type debug metadata.
 func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
        name := C.CString(t.Name)
+       uniqueID := C.CString(t.UniqueID)
        defer C.free(unsafe.Pointer(name))
+       defer C.free(unsafe.Pointer(uniqueID))
        result := C.LLVMDIBuilderCreateReplaceableCompositeType(
                d.ref,
                C.unsigned(t.Tag),
                name,
+               C.size_t(len(t.Name)),
                scope.C,
                t.File.C,
                C.unsigned(t.Line),
                C.unsigned(t.RuntimeLang),
-               C.uint64_t(t.SizeInBits),
-               C.uint32_t(t.AlignInBits),
-               C.unsigned(t.Flags),
+               C.unsigned(t.SizeInBits),
+               C.unsigned(t.AlignInBits),
+               C.LLVMDIFlags(t.Flags),
+               uniqueID,
+               C.size_t(len(t.UniqueID)),
        )
        return Metadata{C: result}
 }
@@ -425,12 +453,13 @@ func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
                d.ref,
                scope.C,
                name,
+               C.size_t(len(t.Name)),
                t.File.C,
                C.unsigned(t.Line),
-               C.uint64_t(t.SizeInBits),
-               C.uint32_t(t.AlignInBits),
-               C.uint64_t(t.OffsetInBits),
-               C.unsigned(t.Flags),
+               C.unsigned(t.SizeInBits),
+               C.unsigned(t.AlignInBits),
+               C.unsigned(t.OffsetInBits),
+               C.LLVMDIFlags(t.Flags),
                t.Type.C,
        )
        return Metadata{C: result}
@@ -456,13 +485,14 @@ func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
        for i, s := range t.Subscripts {
                subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
        }
-       subscripts := d.getOrCreateArray(subscriptsSlice)
+       subscripts, length := llvmMetadataRefs(subscriptsSlice)
        result := C.LLVMDIBuilderCreateArrayType(
                d.ref,
-               C.uint64_t(t.SizeInBits),
-               C.uint32_t(t.AlignInBits),
+               C.unsigned(t.SizeInBits),
+               C.unsigned(t.AlignInBits),
                t.ElementType.C,
-               subscripts.C,
+               subscripts,
+               length,
        )
        return Metadata{C: result}
 }
index a5e5653..ee1dff5 100644 (file)
@@ -122,6 +122,11 @@ typedef enum {
 } LLVMDWARFEmissionKind;
 
 /**
+ * An LLVM DWARF type encoding.
+ */
+typedef unsigned LLVMDWARFTypeEncoding;
+
+/**
  * The current debug metadata version number.
  */
 unsigned LLVMDebugMetadataVersion(void);
@@ -227,6 +232,325 @@ LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line,
                                  unsigned Column, LLVMMetadataRef Scope,
                                  LLVMMetadataRef InlinedAt);
 
+/**
+ * Create subroutine type.
+ * \param File            The file in which the subroutine resides.
+ * \param ParameterTypes  An array of subroutine parameter types. This
+ *                        includes return type at 0th index.
+ * \param NumParameterTypes The number of parameter types in \c ParameterTypes
+ * \param Flags           E.g.: \c LLVMDIFlagLValueReference.
+ *                        These flags are used to emit dwarf attributes.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder,
+                                  LLVMMetadataRef File,
+                                  LLVMMetadataRef *ParameterTypes,
+                                  unsigned NumParameterTypes,
+                                  LLVMDIFlags Flags);
+
+/**
+ * Create debugging information entry for an enumeration.
+ * \param Builder        The DIBuilder.
+ * \param Scope          Scope in which this enumeration is defined.
+ * \param Name           Enumeration name.
+ * \param NameLen        Length of enumeration name.
+ * \param File           File where this member is defined.
+ * \param LineNumber     Line number.
+ * \param SizeInBits     Member size.
+ * \param AlignInBits    Member alignment.
+ * \param Elements       Enumeration elements.
+ * \param NumElements    Number of enumeration elements.
+ * \param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
+ * \param UniqueIdentifier A unique identifier for the enum.
+ */
+LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
+    unsigned SizeInBits, unsigned AlignInBits, LLVMMetadataRef *Elements,
+    unsigned NumElements, LLVMMetadataRef ClassTy);
+
+/**
+ * Create debugging information entry for a union.
+ * \param Builder      The DIBuilder.
+ * \param Scope        Scope in which this union is defined.
+ * \param Name         Union name.
+ * \param NameLen      Length of union name.
+ * \param File         File where this member is defined.
+ * \param LineNumber   Line number.
+ * \param SizeInBits   Member size.
+ * \param AlignInBits  Member alignment.
+ * \param Flags        Flags to encode member attribute, e.g. private
+ * \param Elements     Union elements.
+ * \param NumElements  Number of union elements.
+ * \param RunTimeLang  Optional parameter, Objective-C runtime version.
+ * \param UniqueIdentifier A unique identifier for the union.
+ * \param UniqueIdentifierLen Length of unique identifier.
+ */
+LLVMMetadataRef LLVMDIBuilderCreateUnionType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
+    unsigned SizeInBits, unsigned AlignInBits, LLVMDIFlags Flags,
+    LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang,
+     const char *UniqueId, size_t UniqueIdLen);
+
+
+/**
+ * Create debugging information entry for an array.
+ * \param Builder      The DIBuilder.
+ * \param Size         Array size.
+ * \param AlignInBits  Alignment.
+ * \param Ty           Element type.
+ * \param Subscripts   Subscripts.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, unsigned Size,
+                             unsigned AlignInBits, LLVMMetadataRef Ty,
+                             LLVMMetadataRef *Subscripts,
+                             unsigned NumSubscripts);
+
+/**
+ * Create debugging information entry for a vector type.
+ * \param Builder      The DIBuilder.
+ * \param Size         Vector size.
+ * \param AlignInBits  Alignment.
+ * \param Ty           Element type.
+ * \param Subscripts   Subscripts.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateVectorType(LLVMDIBuilderRef Builder, unsigned Size,
+                              unsigned AlignInBits, LLVMMetadataRef Ty,
+                              LLVMMetadataRef *Subscripts,
+                              unsigned NumSubscripts);
+
+/**
+ * Create a DWARF unspecified type.
+ * \param Builder   The DIBuilder.
+ * \param Name      The unspecified type's name.
+ * \param NameLen   Length of type name.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateUnspecifiedType(LLVMDIBuilderRef Builder, const char *Name,
+                                   size_t NameLen);
+
+/**
+ * Create debugging information entry for a basic
+ * type.
+ * \param Builder     The DIBuilder.
+ * \param Name        Type name.
+ * \param Name        Length of type name.
+ * \param SizeInBits  Size of the type.
+ * \param Encoding    DWARF encoding code, e.g. \c LLVMDWARFTypeEncoding_float.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name,
+                             size_t NameLen, unsigned SizeInBits,
+                             LLVMDWARFTypeEncoding Encoding);
+
+/**
+ * Create debugging information entry for a pointer.
+ * \param Builder     The DIBuilder.
+ * \param PointeeTy         Type pointed by this pointer.
+ * \param SizeInBits        Size.
+ * \param AlignInBits       Alignment. (optional, pass 0 to ignore)
+ * \param DWARFAddressSpace DWARF address space. (optional, pass 0 to ignore)
+ * \param Name              Pointer type name. (optional)
+ * \param Name              Length of pointer type name. (optional)
+ */
+LLVMMetadataRef LLVMDIBuilderCreatePointerType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
+    unsigned SizeInBits, unsigned AlignInBits, unsigned AddressSpace,
+    const char *Name, size_t NameLen);
+
+/**
+ * Create debugging information entry for a struct.
+ * \param Builder     The DIBuilder.
+ * \param Scope        Scope in which this struct is defined.
+ * \param Name         Struct name.
+ * \param Name         Struct name length.
+ * \param File         File where this member is defined.
+ * \param LineNumber   Line number.
+ * \param SizeInBits   Member size.
+ * \param AlignInBits  Member alignment.
+ * \param Flags        Flags to encode member attribute, e.g. private
+ * \param Elements     Struct elements.
+ * \param RunTimeLang  Optional parameter, Objective-C runtime version.
+ * \param VTableHolder The object containing the vtable for the struct.
+ * \param UniqueIdentifier A unique identifier for the struct.
+ * \param UniqueIdentifierLen Length of the unique identifier for the struct.
+ */
+LLVMMetadataRef LLVMDIBuilderCreateStructType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
+    unsigned SizeInBits, unsigned AlignInBits, LLVMDIFlags Flags,
+    LLVMMetadataRef DerivedFrom, LLVMMetadataRef *Elements,
+    unsigned NumElements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
+    const char *UniqueId, size_t UniqueIdLen);
+
+/**
+ * Create debugging information entry for a member.
+ * \param Builder      The DIBuilder.
+ * \param Scope        Member scope.
+ * \param Name         Member name.
+ * \param File         File where this member is defined.
+ * \param LineNo       Line number.
+ * \param SizeInBits   Member size.
+ * \param AlignInBits  Member alignment.
+ * \param OffsetInBits Member offset.
+ * \param Flags        Flags to encode member attribute, e.g. private
+ * \param Ty           Parent type.
+ */
+LLVMMetadataRef LLVMDIBuilderCreateMemberType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
+    unsigned SizeInBits, unsigned AlignInBits, unsigned OffsetInBits,
+    LLVMDIFlags Flags, LLVMMetadataRef Ty);
+
+/**
+ * Create debugging information entry for a
+ * C++ static data member.
+ * \param Builder      The DIBuilder.
+ * \param Scope        Member scope.
+ * \param Name         Member name.
+ * \param Name         Length of member name.
+ * \param File         File where this member is declared.
+ * \param LineNo       Line number.
+ * \param Ty           Type of the static member.
+ * \param Flags        Flags to encode member attribute, e.g. private.
+ * \param Val          Const initializer of the member.
+ * \param AlignInBits  Member alignment.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateStaticMemberType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
+    LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal,
+    unsigned AlignInBits);
+
+/**
+ * Create debugging information entry for a pointer to member.
+ * \param Builder      The DIBuilder.
+ * \param PointeeType Type pointed to by this pointer.
+ * \param Class Type for which this pointer points to members of.
+ * \param SizeInBits  Size.
+ * \param AlignInBits Alignment. (optional)
+ * \param Flags Flags.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateMemberPointerType(LLVMDIBuilderRef Builder,
+                                     LLVMMetadataRef PointeeType,
+                                     LLVMMetadataRef ClassType,
+                                     unsigned SizeInBits,
+                                     unsigned AlignInBits,
+                                     LLVMDIFlags Flags);
+
+/**
+ * Create a new DIType* with the "object pointer"
+ * flag set.
+ * \param Builder   The DIBuilder.
+ * \param Type      The underlying type to which this pointer points.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,
+                                     LLVMMetadataRef Type);
+
+/**
+ * Create debugging information entry for a qualified
+ * type, e.g. 'const int'.
+ * \param Tag         Tag identifing type,
+ *                    e.g. LLVMDWARFTypeQualifier_volatile_type
+ * \param FromTy      Base Type.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag,
+                                 LLVMMetadataRef Type);
+
+/**
+ * Create debugging information entry for a c++
+ * style reference or rvalue reference type.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateReferenceType(LLVMDIBuilderRef Builder, unsigned Tag,
+                                 LLVMMetadataRef Type);
+
+/**
+ * Create C++11 nullptr type.
+ * \param Builder   The DIBuilder.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateNullPtrType(LLVMDIBuilderRef Builder);
+
+/**
+ * Create a temporary forward-declared type.
+ * \param Builder   The DIBuilder.
+ * \param Tag       A unique tag for this type.
+ * \param Name      Type name.
+ * \param NameLen   Length of type name.
+ * \param Scope     Type scope.
+ * \param File      File where this type is defined.
+ * \param Line      Line number where this type is defined.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateReplaceableCompositeType(
+    LLVMDIBuilderRef Builder, unsigned Tag, const char *Name,
+    size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line,
+    unsigned RuntimeLang, unsigned SizeInBits, unsigned AlignInBits,
+    LLVMDIFlags Flags, const char *UniqueIdentifier,
+    size_t UniqueIdentifierLen);
+
+/**
+ * Create debugging information entry for a bit field member.
+ * \param Builder             The DIBuilder.
+ * \param Scope               Member scope.
+ * \param Name                Member name.
+ * \param NameLen             Length of member name.
+ * \param File                File where this member is defined.
+ * \param LineNo              Line number.
+ * \param SizeInBits          Member size.
+ * \param OffsetInBits        Member offset.
+ * \param StorageOffsetInBits Member storage offset.
+ * \param Flags               Flags to encode member attribute.
+ * \param Type                Parent type.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateBitFieldMemberType(LLVMDIBuilderRef Builder,
+                                      LLVMMetadataRef Scope,
+                                      const char *Name, size_t NameLen,
+                                      LLVMMetadataRef File, unsigned LineNumber,
+                                      unsigned SizeInBits,
+                                      unsigned OffsetInBits,
+                                      unsigned StorageOffsetInBits,
+                                      LLVMDIFlags Flags, LLVMMetadataRef Type);
+
+/**
+ * Create debugging information entry for a class.
+ * \param Scope        Scope in which this class is defined.
+ * \param Name         class name.
+ * \param File         File where this member is defined.
+ * \param LineNumber   Line number.
+ * \param SizeInBits   Member size.
+ * \param AlignInBits  Member alignment.
+ * \param OffsetInBits Member offset.
+ * \param Flags        Flags to encode member attribute, e.g. private
+ * \param Elements     class members.
+ * \param DerivedFrom  Debug info of the base class of this type.
+ * \param TemplateParms Template type parameters.
+ */
+LLVMMetadataRef LLVMDIBuilderCreateClassType(LLVMDIBuilderRef Builder,
+    LLVMMetadataRef Scope, const char *Name, size_t NameLen,
+    LLVMMetadataRef File, unsigned LineNumber, unsigned SizeInBits,
+    unsigned AlignInBits, unsigned OffsetInBits, LLVMDIFlags Flags,
+    LLVMMetadataRef *Elements, unsigned NumElements,
+    LLVMMetadataRef DerivedFrom, LLVMMetadataRef TemplateParamsNode);
+
+/**
+ * Create a new DIType* with "artificial" flag set.
+ * \param Builder     The DIBuilder.
+ * \param Type        The underlying type.
+ */
+LLVMMetadataRef
+LLVMDIBuilderCreateArtificialType(LLVMDIBuilderRef Builder,
+                                  LLVMMetadataRef Type);
+
 #ifdef __cplusplus
 } /* end extern "C" */
 #endif
index 7fff752..3752703 100644 (file)
@@ -692,6 +692,14 @@ case LLVMDWARFSourceLanguage##NAME: return ID;
   llvm_unreachable("Unhandled Tag");
 }
 
+template <typename DIT> DIT *unwrapDI(LLVMMetadataRef Ref) {
+  return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
+}
+
+static DINode::DIFlags map_from_llvmDIFlags(LLVMDIFlags Flags) {
+  return static_cast<DINode::DIFlags>(Flags);
+}
+
 unsigned LLVMDebugMetadataVersion() {
   return DEBUG_METADATA_VERSION;
 }
@@ -727,7 +735,7 @@ LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
     unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen,
     LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining,
     LLVMBool DebugInfoForProfiling) {
-  auto File = unwrap<DIFile>(FileRef);
+  auto File = unwrapDI<DIFile>(FileRef);
 
   return wrap(unwrap(Builder)->createCompileUnit(
                  map_from_llvmDWARFsourcelanguage(Lang), File,
@@ -753,3 +761,184 @@ LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line,
   return wrap(DILocation::get(*unwrap(Ctx), Line, Column, unwrap(Scope),
                               unwrap(InlinedAt)));
 }
+
+LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
+  LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+  size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
+  unsigned SizeInBits, unsigned AlignInBits, LLVMMetadataRef *Elements,
+  unsigned NumElements, LLVMMetadataRef ClassTy) {
+auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),
+                                               NumElements});
+return wrap(unwrap(Builder)->createEnumerationType(
+    unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),
+    LineNumber, SizeInBits, AlignInBits, Elts, unwrapDI<DIType>(ClassTy)));
+}
+
+LLVMMetadataRef LLVMDIBuilderCreateUnionType(
+  LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+  size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
+  unsigned SizeInBits, unsigned AlignInBits, LLVMDIFlags Flags,
+  LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang,
+  const char *UniqueId, size_t UniqueIdLen) {
+  auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),
+                                                 NumElements});
+  return wrap(unwrap(Builder)->createUnionType(
+     unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),
+     LineNumber, SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags),
+     Elts, RunTimeLang, {UniqueId, UniqueIdLen}));
+}
+
+
+LLVMMetadataRef
+LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, unsigned Size,
+                             unsigned AlignInBits, LLVMMetadataRef Ty,
+                             LLVMMetadataRef *Subscripts,
+                             unsigned NumSubscripts) {
+  auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts),
+                                                 NumSubscripts});
+  return wrap(unwrap(Builder)->createArrayType(Size, AlignInBits,
+                                               unwrapDI<DIType>(Ty), Subs));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateVectorType(LLVMDIBuilderRef Builder, unsigned Size,
+                              unsigned AlignInBits, LLVMMetadataRef Ty,
+                              LLVMMetadataRef *Subscripts,
+                              unsigned NumSubscripts) {
+  auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts),
+                                                 NumSubscripts});
+  return wrap(unwrap(Builder)->createVectorType(Size, AlignInBits,
+                                                unwrapDI<DIType>(Ty), Subs));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name,
+                             size_t NameLen, unsigned SizeInBits,
+                             LLVMDWARFTypeEncoding Encoding) {
+  return wrap(unwrap(Builder)->createBasicType({Name, NameLen},
+                                               SizeInBits, Encoding));
+}
+
+LLVMMetadataRef LLVMDIBuilderCreatePointerType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
+    unsigned SizeInBits, unsigned AlignInBits, unsigned AddressSpace,
+    const char *Name, size_t NameLen) {
+  return wrap(unwrap(Builder)->createPointerType(unwrapDI<DIType>(PointeeTy),
+                                         SizeInBits, AlignInBits,
+                                         AddressSpace, {Name, NameLen}));
+}
+
+LLVMMetadataRef LLVMDIBuilderCreateStructType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
+    unsigned SizeInBits, unsigned AlignInBits, LLVMDIFlags Flags,
+    LLVMMetadataRef DerivedFrom, LLVMMetadataRef *Elements,
+    unsigned NumElements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
+    const char *UniqueId, size_t UniqueIdLen) {
+  auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),
+                                                 NumElements});
+  return wrap(unwrap(Builder)->createStructType(
+      unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),
+      LineNumber, SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags),
+      unwrapDI<DIType>(DerivedFrom), Elts, RunTimeLang,
+      unwrapDI<DIType>(VTableHolder), {UniqueId, UniqueIdLen}));
+}
+
+LLVMMetadataRef LLVMDIBuilderCreateMemberType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
+    uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags,
+    LLVMMetadataRef Ty) {
+  return wrap(unwrap(Builder)->createMemberType(unwrapDI<DIScope>(Scope),
+      {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, SizeInBits, AlignInBits,
+      OffsetInBits, map_from_llvmDIFlags(Flags), unwrapDI<DIType>(Ty)));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateUnspecifiedType(LLVMDIBuilderRef Builder, const char *Name,
+                                   size_t NameLen) {
+  return wrap(unwrap(Builder)->createUnspecifiedType({Name, NameLen}));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateStaticMemberType(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
+    LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal,
+    unsigned AlignInBits) {
+  return wrap(unwrap(Builder)->createStaticMemberType(
+                  unwrapDI<DIScope>(Scope), {Name, NameLen},
+                  unwrapDI<DIFile>(File), LineNumber, unwrapDI<DIType>(Type),
+                  map_from_llvmDIFlags(Flags), unwrap<Constant>(ConstantVal),
+                  AlignInBits));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,
+                                     LLVMMetadataRef Type) {
+  return wrap(unwrap(Builder)->createObjectPointerType(unwrapDI<DIType>(Type)));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateReplaceableCompositeType(
+    LLVMDIBuilderRef Builder, unsigned Tag, const char *Name, size_t NameLen,
+    LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line,
+    unsigned RuntimeLang, unsigned SizeInBits, unsigned AlignInBits,
+    LLVMDIFlags Flags, const char *UniqueIdentifier,
+    unsigned UniqueIdentifierLen) {
+  return wrap(unwrap(Builder)->createReplaceableCompositeType(
+                  Tag, {Name, NameLen}, unwrapDI<DIScope>(Scope),
+                  unwrapDI<DIFile>(File), Line, RuntimeLang, SizeInBits,
+                  AlignInBits, map_from_llvmDIFlags(Flags),
+                  {UniqueIdentifier, UniqueIdentifierLen}));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag,
+                                 LLVMMetadataRef Type) {
+  return wrap(unwrap(Builder)->createQualifiedType(Tag,
+                                                   unwrapDI<DIType>(Type)));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateReferenceType(LLVMDIBuilderRef Builder, unsigned Tag,
+                                 LLVMMetadataRef Type) {
+  return wrap(unwrap(Builder)->createReferenceType(Tag,
+                                                   unwrapDI<DIType>(Type)));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateNullPtrType(LLVMDIBuilderRef Builder) {
+  return wrap(unwrap(Builder)->createNullPtrType());
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateMemberPointerType(LLVMDIBuilderRef Builder,
+                                     LLVMMetadataRef PointeeType,
+                                     LLVMMetadataRef ClassType,
+                                     unsigned SizeInBits,
+                                     unsigned AlignInBits,
+                                     LLVMDIFlags Flags) {
+  return wrap(unwrap(Builder)->createMemberPointerType(
+                  unwrapDI<DIType>(PointeeType),
+                  unwrapDI<DIType>(ClassType), AlignInBits, SizeInBits,
+                  map_from_llvmDIFlags(Flags)));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateArtificialType(LLVMDIBuilderRef Builder,
+                                  LLVMMetadataRef Type) {
+  return wrap(unwrap(Builder)->createArtificialType(unwrapDI<DIType>(Type)));
+}
+
+LLVMMetadataRef
+LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder,
+                                  LLVMMetadataRef File,
+                                  LLVMMetadataRef *ParameterTypes,
+                                  unsigned NumParameterTypes,
+                                  LLVMDIFlags Flags) {
+  auto Elts = unwrap(Builder)->getOrCreateTypeArray({unwrap(ParameterTypes),
+                                                     NumParameterTypes});
+  return wrap(unwrap(Builder)->createSubroutineType(
+    Elts, map_from_llvmDIFlags(Flags)));
+}
index 7c62abf..0b555fc 100644 (file)
@@ -4,5 +4,11 @@
 ; CHECK-NEXT: source_filename = "debuginfo.c"
 
 ; CHECK: !llvm.dbg.cu = !{!0}
+; CHECK-NEXT: !FooType = !{!2}
+
 ; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false)
-; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c\00", directory: ".")
+; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c", directory: ".")
+; CHECK-NEXT: !2 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3, size: 192, dwarfAddressSpace: 0)
+; CHECK-NEXT: !3 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", file: !1, size: 192, elements: !4, runtimeLang: DW_LANG_C89, identifier: "MyStruct")
+; CHECK-NEXT: !4 = !{!5, !5, !5}
+; CHECK-NEXT: !5 = !DIBasicType(name: "Int64", size: 64)
\ No newline at end of file
index c88c741..a35d63e 100644 (file)
 |*                                                                            *|
 \*===----------------------------------------------------------------------===*/
 
+#include "llvm-c-test.h"
+#include "llvm-c/Core.h"
 #include "llvm-c/DebugInfo.h"
 #include <stdio.h>
+#include <string.h>
 
 int llvm_test_dibuilder(void) {
-  LLVMModuleRef M = LLVMModuleCreateWithName("debuginfo.c");
+  const char *Filename = "debuginfo.c";
+  LLVMModuleRef M = LLVMModuleCreateWithName(Filename);
   LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M);
 
-  LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, "debuginfo.c", 12,
-                                                 ".", 1);
+  LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, Filename,
+    strlen(Filename), ".", 1);
 
-  LLVMDIBuilderCreateCompileUnit(DIB,
+  LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit(DIB,
       LLVMDWARFSourceLanguageC, File,"llvm-c-test", 11, 0, NULL, 0, 0,
       NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0);
 
+  LLVMMetadataRef Int64Ty =
+    LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0);
+
+  LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty};
+  LLVMMetadataRef StructDbgTy =
+    LLVMDIBuilderCreateStructType(DIB, CompileUnit, "MyStruct",
+    8, File, 0, 192, 0, 0, NULL, StructDbgElts, 3,
+    LLVMDWARFSourceLanguageC, NULL, "MyStruct", 8);
+
+  LLVMMetadataRef StructDbgPtrTy =
+    LLVMDIBuilderCreatePointerType(DIB, StructDbgTy, 192, 0, 0, "", 0);
+
+  LLVMAddNamedMetadataOperand(M, "FooType",
+    LLVMMetadataAsValue(LLVMGetModuleContext(M), StructDbgPtrTy));
+
   char *MStr = LLVMPrintModuleToString(M);
   puts(MStr);
   LLVMDisposeMessage(MStr);