OSDN Git Service

[bindings/go] Add debug information accessors
authorAyke van Laethem <aykevanlaethem@gmail.com>
Mon, 24 Jun 2019 16:23:17 +0000 (16:23 +0000)
committerAyke van Laethem <aykevanlaethem@gmail.com>
Mon, 24 Jun 2019 16:23:17 +0000 (16:23 +0000)
Add debug information accessors, as provided in the following patches:

https://reviews.llvm.org/D46627 (DILocation)
https://reviews.llvm.org/D52693 metadata kind
https://reviews.llvm.org/D60481 get/set debug location on a Value
https://reviews.llvm.org/D60489 (DIScope)

The API as proposed in this patch is similar to the current Value API,
with a single root type and methods that are only valid for certain
subclasses. I have considered just implementing generic Line() calls
(that are valid on all DINodes that have a line) but the implementation
of that got a bit awkward without support from the C API. I've also
considered creating generic getters like a Metadata.DebugLoc() that
returns a DebugLoc, but there is a mismatch between the Go DI nodes in
the LLVM API and the actual DINode class hierarchy, so that's also hard
to get right (without being confusing or breaking the API).

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364198 91177308-0d34-0410-b5e6-96231b3b80d8

bindings/go/llvm/dibuilder.go
bindings/go/llvm/ir.go

index 41e29c9..da1bb0f 100644 (file)
@@ -604,3 +604,93 @@ func (c Context) TemporaryMDNode(mds []Metadata) (md Metadata) {
 func (md Metadata) ReplaceAllUsesWith(new Metadata) {
        C.LLVMMetadataReplaceAllUsesWith(md.C, new.C)
 }
+
+type MetadataKind C.LLVMMetadataKind
+
+const (
+       MDStringMetadataKind                     = C.LLVMMDStringMetadataKind
+       ConstantAsMetadataMetadataKind           = C.LLVMConstantAsMetadataMetadataKind
+       LocalAsMetadataMetadataKind              = C.LLVMLocalAsMetadataMetadataKind
+       DistinctMDOperandPlaceholderMetadataKind = C.LLVMDistinctMDOperandPlaceholderMetadataKind
+       MDTupleMetadataKind                      = C.LLVMMDTupleMetadataKind
+       DILocationMetadataKind                   = C.LLVMDILocationMetadataKind
+       DIExpressionMetadataKind                 = C.LLVMDIExpressionMetadataKind
+       DIGlobalVariableExpressionMetadataKind   = C.LLVMDIGlobalVariableExpressionMetadataKind
+       GenericDINodeMetadataKind                = C.LLVMGenericDINodeMetadataKind
+       DISubrangeMetadataKind                   = C.LLVMDISubrangeMetadataKind
+       DIEnumeratorMetadataKind                 = C.LLVMDIEnumeratorMetadataKind
+       DIBasicTypeMetadataKind                  = C.LLVMDIBasicTypeMetadataKind
+       DIDerivedTypeMetadataKind                = C.LLVMDIDerivedTypeMetadataKind
+       DICompositeTypeMetadataKind              = C.LLVMDICompositeTypeMetadataKind
+       DISubroutineTypeMetadataKind             = C.LLVMDISubroutineTypeMetadataKind
+       DIFileMetadataKind                       = C.LLVMDIFileMetadataKind
+       DICompileUnitMetadataKind                = C.LLVMDICompileUnitMetadataKind
+       DISubprogramMetadataKind                 = C.LLVMDISubprogramMetadataKind
+       DILexicalBlockMetadataKind               = C.LLVMDILexicalBlockMetadataKind
+       DILexicalBlockFileMetadataKind           = C.LLVMDILexicalBlockFileMetadataKind
+       DINamespaceMetadataKind                  = C.LLVMDINamespaceMetadataKind
+       DIModuleMetadataKind                     = C.LLVMDIModuleMetadataKind
+       DITemplateTypeParameterMetadataKind      = C.LLVMDITemplateTypeParameterMetadataKind
+       DITemplateValueParameterMetadataKind     = C.LLVMDITemplateValueParameterMetadataKind
+       DIGlobalVariableMetadataKind             = C.LLVMDIGlobalVariableMetadataKind
+       DILocalVariableMetadataKind              = C.LLVMDILocalVariableMetadataKind
+       DILabelMetadataKind                      = C.LLVMDILabelMetadataKind
+       DIObjCPropertyMetadataKind               = C.LLVMDIObjCPropertyMetadataKind
+       DIImportedEntityMetadataKind             = C.LLVMDIImportedEntityMetadataKind
+       DIMacroMetadataKind                      = C.LLVMDIMacroMetadataKind
+       DIMacroFileMetadataKind                  = C.LLVMDIMacroFileMetadataKind
+       DICommonBlockMetadataKind                = C.LLVMDICommonBlockMetadataKind
+)
+
+// Kind returns the metadata kind.
+func (md Metadata) Kind() MetadataKind {
+       return MetadataKind(C.LLVMGetMetadataKind(md.C))
+}
+
+// FileDirectory returns the directory of a DIFile metadata node.
+func (md Metadata) FileDirectory() string {
+       var length C.unsigned
+       ptr := C.LLVMDIFileGetDirectory(md.C, &length)
+       return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
+}
+
+// FileFilename returns the filename of a DIFile metadata node.
+func (md Metadata) FileFilename() string {
+       var length C.unsigned
+       ptr := C.LLVMDIFileGetFilename(md.C, &length)
+       return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
+}
+
+// FileSource returns the source of a DIFile metadata node.
+func (md Metadata) FileSource() string {
+       var length C.unsigned
+       ptr := C.LLVMDIFileGetSource(md.C, &length)
+       return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
+}
+
+// LocationLine returns the line number of a DILocation.
+func (md Metadata) LocationLine() uint {
+       return uint(C.LLVMDILocationGetLine(md.C))
+}
+
+// LocationColumn returns the column (offset from the start of the line) of a
+// DILocation.
+func (md Metadata) LocationColumn() uint {
+       return uint(C.LLVMDILocationGetColumn(md.C))
+}
+
+// LocationScope returns the local scope associated with this debug location.
+func (md Metadata) LocationScope() Metadata {
+       return Metadata{C.LLVMDILocationGetScope(md.C)}
+}
+
+// LocationInlinedAt return the "inline at" location associated with this debug
+// location.
+func (md Metadata) LocationInlinedAt() Metadata {
+       return Metadata{C.LLVMDILocationGetInlinedAt(md.C)}
+}
+
+// ScopeFile returns the file (DIFile) of a given scope.
+func (md Metadata) ScopeFile() Metadata {
+       return Metadata{C.LLVMDIScopeGetFile(md.C)}
+}
index ab2baea..1a144ea 100644 (file)
@@ -89,6 +89,7 @@ func (c MemoryBuffer) IsNil() bool   { return c.C == nil }
 func (c PassManager) IsNil() bool    { return c.C == nil }
 func (c Use) IsNil() bool            { return c.C == nil }
 func (c Attribute) IsNil() bool      { return c.C == nil }
+func (c Metadata) IsNil() bool       { return c.C == nil }
 
 // helpers
 func llvmTypeRefPtr(t *Type) *C.LLVMTypeRef    { return (*C.LLVMTypeRef)(unsafe.Pointer(t)) }
@@ -1256,6 +1257,8 @@ func (bb BasicBlock) MoveAfter(pos BasicBlock)  { C.LLVMMoveBasicBlockAfter(bb.C
 // Operations on instructions
 func (v Value) EraseFromParentAsInstruction()      { C.LLVMInstructionEraseFromParent(v.C) }
 func (v Value) InstructionParent() (bb BasicBlock) { bb.C = C.LLVMGetInstructionParent(v.C); return }
+func (v Value) InstructionDebugLoc() (md Metadata) { md.C = C.LLVMInstructionGetDebugLoc(v.C); return }
+func (v Value) InstructionSetDebugLoc(md Metadata) { C.LLVMInstructionSetDebugLoc(v.C, md.C) }
 func (bb BasicBlock) FirstInstruction() (v Value)  { v.C = C.LLVMGetFirstInstruction(bb.C); return }
 func (bb BasicBlock) LastInstruction() (v Value)   { v.C = C.LLVMGetLastInstruction(bb.C); return }
 func NextInstruction(v Value) (rv Value)           { rv.C = C.LLVMGetNextInstruction(v.C); return }