LLVMDIBuilder.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Thu, 17 Sep 2015 17:09:43 +0100
changeset 41 e4cbc8e75207
parent 33 feabf14b6c1d
child 42 23ae490859cd
permissions -rw-r--r--
Added testing and assestion methods to test metadata nodes for their type ...such as DIFile, DILocalVariable. These should be used by the Smalltalk API to make sure it passes valid data to the C library. Otherwise the behaviour is undefined :-) (except for Debug+Assert LLVM builds which calls abort(), not nice in Smalltalk context)

"
    Copyright (C) 2015-now Jan Vrany

    This code is not an open-source (yet). You may use this code
    for your own experiments and projects, given that:

    * all modification to the code will be sent to the
      original author for inclusion in future releases
    * this is not used in any commercial software

    This license is provisional and may (will) change in
    a future.
"
"{ Package: 'jv:llvm_s' }"

"{ NameSpace: Smalltalk }"

LLVMDisposableObject subclass:#LLVMDIBuilder
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:'LLVMModuleFlagBehavior'
	category:'LLVM-S-Core'
!

!LLVMDIBuilder class methodsFor:'documentation'!

copyright
"
    Copyright (C) 2015-now Jan Vrany

    This code is not an open-source (yet). You may use this code
    for your own experiments and projects, given that:

    * all modification to the code will be sent to the
      original author for inclusion in future releases
    * this is not used in any commercial software

    This license is provisional and may (will) change in
    a future.
"
! !

!LLVMDIBuilder class methodsFor:'instance creation'!

newForModule: module
    | dib |
    dib := LLVMCEXT NewDIBuilder: module.
    "/ Now we have to add module flags otherwise llc won't
    "/ produce debug info.
    "/ See http://lists.llvm.org/pipermail/llvm-dev/2014-October/077815.html
    module addFlag: 'Dwarf Version' value: (LLVMConstant uint32: 4) asLLVMMetadata behavior: LLVMModuleFlagBehaviorWarning.  
    module addFlag: 'Debug Info Version' value: (LLVMConstant uint32: 3) asLLVMMetadata behavior: LLVMModuleFlagBehaviorError.  

    ^ dib

    "Created: / 13-08-2015 / 06:35:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 15-08-2015 / 23:39:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!LLVMDIBuilder methodsFor:'assertions'!

assertIsStringOrFilename: value
    <resource: #skipInDebuggersWalkback>
    self assert: (value isString or:[ value isFilename ]) message: 'value is not a String or Filename'

    "Created: / 13-08-2015 / 06:47:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!LLVMDIBuilder methodsFor:'building'!

createAutomaticVariable: name in: scope file: file line: line type: type
    ^ self createAutomaticVariable: name in: scope file: file line: line type: type flags: 0

    "Created: / 14-08-2015 / 13:58:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createAutomaticVariable: name in: scope file: file line: line type: type flags: flags
    ^ self createAutomaticVariable: name in: scope file: file line: line type: type flags: flags preserve: true.

    "Created: / 14-08-2015 / 13:57:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createAutomaticVariable: name in: scope file: file line: line type: type flags: flags preserve: preserve
    "Creates a debg info metadata describing a local variable"

    self assertIsString: name.
    self assertIsDILocalScope: scope.  
    self assertIsDIFile: file.
    self assertIsIntegerUnsigned: line.
    self assertIsDIType: type.
    self assertIsIntegerUnsigned: flags.
    self assertIsBoolean: preserve.

    ^ LLVMCEXT DIBuilderCreateAutoVariable: self _: scope _: name _: file _: line _: type _: (preserve ifTrue:[1] ifFalse:[0]) _: flags

    "Created: / 14-08-2015 / 13:56:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 17-09-2015 / 17:00:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createCompilationUnit: path language: lang producer: producer
    ^ self createCompilationUnit: path language: lang producer: producer runtimeVersion: 0 optimized: false flags: ''

    "Created: / 13-08-2015 / 06:58:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createCompilationUnit: path language: lang producer: producer runtimeVersion: rv optimized: isOptimized flags: compilerFlags
    | filename |
    self assertIsStringOrFilename: path.
    self assertIsIntegerUnsigned: lang.
    self assertIsString: producer.
    self assertIsIntegerUnsigned: rv.
    self assertIsBoolean: isOptimized.
    self assertIsString: compilerFlags.

    filename := path asFilename.

    ^ LLVMCEXT DIBuilderCreateCompileUnit: self _: lang _: filename baseName _: filename directory pathName _: producer _: (isOptimized ifTrue:[1] ifFalse:[0]) _: compilerFlags _: rv

    "Created: / 13-08-2015 / 06:47:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createExpression
    ^ LLVMCEXT DIBuilderCreateExpression: self _: ExternalAddress new _: 0

    "Created: / 14-08-2015 / 14:06:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createFile: path
    | filename |

    self assertIsStringOrFilename: path.    

    filename := path asFilename.
    ^ LLVMCEXT DIBuilderCreateFile: self _: filename baseName _: filename directory pathName

    "Created: / 15-08-2015 / 22:08:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createFunction: name in: scope file: file  line: line type: type function: function local: isLocal definition: isDefinition optimized: isOptimized
    ^ self createFunction: name in: scope file: file  line: line type: type function: function local: isLocal definition: isDefinition optimized: isOptimized flags: 0

    "Created: / 14-08-2015 / 13:47:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createFunction: name in: scope file: file  line: line type: type function: function local: isLocal definition: isDefinition optimized: isOptimized flags: flags
    ^ self createFunction: name in: scope file: file  line: line type: type function: function local: isLocal definition: isDefinition optimized: isOptimized flags: flags scopeLine: line

    "Created: / 14-08-2015 / 13:47:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createFunction: name in: scope file: file  line: line type: type function: function local: isLocal definition: isDefinition optimized: isOptimized flags: flags scopeLine: scopeLine
    ^ self createFunction: name in: scope file: file  line: line type: type function: function local: isLocal definition: isDefinition optimized: isOptimized flags: flags scopeLine: scopeLine linkageName: function name

    "Created: / 14-08-2015 / 13:46:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createFunction: name in: scope file: file  line: line type: type function: function local: isLocal definition: isDefinition optimized: isOptimized flags: flags scopeLine: scopeLine linkageName: linkageName

    self assertIsDIScope: scope.          
    self assertIsDIFile: file.
    self assertIsString: name.
    self assertIsIntegerUnsigned: line.
    self assertIsFunctionValue: function.
    self assertIsBoolean: isLocal.
    self assertIsBoolean: isDefinition.
    self assertIsBoolean: isOptimized.
    self assertIsIntegerUnsigned: flags.
    self assertIsIntegerUnsigned: scopeLine.
    self assertIsString: linkageName.

    ^ LLVMCEXT DIBuilderCreateFunction: self  _: scope _: name _: linkageName _: file _: line _: type _: (isLocal ifTrue:[1] ifFalse:[0]) _: (isDefinition ifTrue:[1] ifFalse:[0]) _: scopeLine _: flags _: (isOptimized ifTrue:[1] ifFalse:[0]) _: function.

    "Created: / 14-08-2015 / 13:46:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 17-09-2015 / 17:04:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createParameterVariable: name in: scope file: file line: line type: type flags: flags index: index
    ^  self createParameterVariable: name in: scope file: file line: line type: type flags: flags index: index preserve: true

    "Created: / 14-08-2015 / 13:54:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createParameterVariable: name in: scope file: file line: line type: type flags: flags index: index  preserve: preserve
    "Creates a debg info metadata describing a local variable"

    self assertIsString: name.
    self assertIsDILocalScope: scope.  
    self assertIsDIFile: file.
    self assertIsIntegerUnsigned: line.
    self assertIsDIType: type.
    self assertIsIntegerUnsigned: flags.
    self assertIsIntegerUnsigned: index.
    self assertIsBoolean: preserve.

    ^ LLVMCEXT DIBuilderCreateParameterVariable: self _: scope _: name _: file _: line _: type _: (preserve ifTrue:[1] ifFalse:[0]) _: flags _: index - 1

    "Created: / 14-08-2015 / 13:54:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 17-09-2015 / 17:01:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createTypeFunctionIn: file parameterTypes: parameterTypes
    | parameterTypesAsTuple |

    self assertIsDIFile: file.
    self assertIsDITypeArray: parameterTypes.

    parameterTypesAsTuple := LLVMCEXT MDNode2: LLVM GetGlobalContext _: parameterTypes asLLVMObjectArray _: parameterTypes size.
    ^ LLVMCEXT DIBuilderCreateSubroutineType: self  _: file _: parameterTypesAsTuple

    "Created: / 14-08-2015 / 08:57:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 17-09-2015 / 17:01:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createTypeScalar: name size: sizeInBits alignment: alignmentInBits encoding: encoding
    self assertIsString: name.
    self assertIsInteger64Unsigned: sizeInBits.
    self assertIsInteger64Unsigned: alignmentInBits.
    self assertIsIntegerUnsigned: alignmentInBits.

    ^ LLVMCEXT DIBuilderCreateBasicType: self _: name _: sizeInBits _: alignmentInBits _: encoding

    "Created: / 14-08-2015 / 07:32:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createTypeScalar: name type: type encoding: encoding
    self assertIsString: name.
    self assertIsType: type.

    ^ self createTypeScalar: name size: type sizeInBits alignment:type alignmentInBits encoding: encoding

    "Created: / 14-08-2015 / 09:17:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

finish
    LLVMCEXT DIBuilderFinalize: self

    "Created: / 14-08-2015 / 13:11:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

insertDeclare: alloca variable: variable expression: expr location: location atEndOf: basicblock
    "Inserts @llvm.dbg.declare() intrinsic at the end of given `basicblock`"

    self assertIsValue: alloca.
    self assertIsDILocalVariable: variable.
    self assertIsDIExpression: expr.
    self assertIsDILocation: location.
    self assertIsBasicBlock: basicblock.

    ^ LLVMCEXT DIBuilderInsertDeclareAtEnd: self  _: alloca _: variable _: expr _: location _: basicblock

    "Created: / 15-08-2015 / 23:44:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 17-09-2015 / 17:03:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

insertValue: alloca variable: variable expression: expr location: location atEndOf: basicblock offset: offset
    "Inserts @llvm.dbg.value() intrinsic at the end of given `basicblock`"

    self assertIsValue: alloca.
    self assertIsDILocalVariable: variable.
    self assertIsDIExpression: expr.
    self assertIsDILocation: location.
    self assertIsBasicBlock: basicblock.
    self assertIsInteger64Unsigned: offset.  

    ^ LLVMCEXT DIBuilderInsertValueAtEnd: self _: alloca _: offset _: variable _: expr _: location _: basicblock

    "Created: / 15-08-2015 / 23:49:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 17-09-2015 / 17:03:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!LLVMDIBuilder methodsFor:'initialization & release'!

dispose
    "superclass LLVMDisposableObject says that I am responsible to implement this method"

    ^ LLVMCEXT DIBuilderDestroy: self

    "Modified: / 14-08-2015 / 13:20:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !