Skip to content

Commit

Permalink
[bindings/go] Add debug information accessors
Browse files Browse the repository at this point in the history
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

llvm-svn: 364198
  • Loading branch information
aykevl committed Jun 24, 2019
1 parent 3a4a60e commit 9f4c7e8
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
90 changes: 90 additions & 0 deletions llvm/bindings/go/llvm/dibuilder.go
Expand Up @@ -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)}
}
3 changes: 3 additions & 0 deletions llvm/bindings/go/llvm/ir.go
Expand Up @@ -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)) }
Expand Down Expand Up @@ -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 }
Expand Down

0 comments on commit 9f4c7e8

Please sign in to comment.