| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,222 @@ | ||
| //===- DIBuilderBindings.cpp - Bindings for DIBuilder ---------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines C bindings for the DIBuilder class. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "DIBuilderBindings.h" | ||
|
|
||
| #include "llvm/IR/Module.h" | ||
| #include "llvm/IR/DIBuilder.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| namespace { | ||
| template <typename T> | ||
| T unwrapDI(LLVMValueRef v) { | ||
| return v ? T(unwrap<MDNode>(v)) : T(); | ||
| } | ||
| } | ||
|
|
||
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef) | ||
|
|
||
| LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef mref) { | ||
| Module *m = unwrap(mref); | ||
| return wrap(new DIBuilder(*m)); | ||
| } | ||
|
|
||
| void LLVMDIBuilderDestroy(LLVMDIBuilderRef dref) { | ||
| DIBuilder *d = unwrap(dref); | ||
| delete d; | ||
| } | ||
|
|
||
| void LLVMDIBuilderFinalize(LLVMDIBuilderRef dref) { unwrap(dref)->finalize(); } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef Dref, | ||
| unsigned Lang, const char *File, | ||
| const char *Dir, | ||
| const char *Producer, int Optimized, | ||
| const char *Flags, | ||
| unsigned RuntimeVersion) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DICompileUnit CU = D->createCompileUnit(Lang, File, Dir, Producer, Optimized, | ||
| Flags, RuntimeVersion); | ||
| return wrap(CU); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Dref, const char *File, | ||
| const char *Dir) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DIFile F = D->createFile(File, Dir); | ||
| return wrap(F); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref, | ||
| LLVMValueRef Scope, | ||
| LLVMValueRef File, unsigned Line, | ||
| unsigned Column) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DILexicalBlock LB = D->createLexicalBlock( | ||
| unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Column); | ||
| return wrap(LB); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref, | ||
| LLVMValueRef Scope, | ||
| LLVMValueRef File, | ||
| unsigned Discriminator) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DILexicalBlockFile LBF = D->createLexicalBlockFile( | ||
| unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Discriminator); | ||
| return wrap(LBF); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateFunction( | ||
| LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name, | ||
| const char *LinkageName, LLVMValueRef File, unsigned Line, | ||
| LLVMValueRef CompositeType, int IsLocalToUnit, int IsDefinition, | ||
| unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Func) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DISubprogram SP = D->createFunction( | ||
| unwrapDI<DIDescriptor>(Scope), Name, LinkageName, unwrapDI<DIFile>(File), | ||
| Line, unwrapDI<DICompositeType>(CompositeType), IsLocalToUnit, | ||
| IsDefinition, ScopeLine, Flags, IsOptimized, unwrap<Function>(Func)); | ||
| return wrap(SP); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateLocalVariable( | ||
| LLVMDIBuilderRef Dref, unsigned Tag, LLVMValueRef Scope, const char *Name, | ||
| LLVMValueRef File, unsigned Line, LLVMValueRef Ty, int AlwaysPreserve, | ||
| unsigned Flags, unsigned ArgNo) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DIVariable V = D->createLocalVariable( | ||
| Tag, unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line, | ||
| unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo); | ||
| return wrap(V); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref, | ||
| const char *Name, uint64_t SizeInBits, | ||
| uint64_t AlignInBits, | ||
| unsigned Encoding) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DIBasicType T = D->createBasicType(Name, SizeInBits, AlignInBits, Encoding); | ||
| return wrap(T); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref, | ||
| LLVMValueRef PointeeType, | ||
| uint64_t SizeInBits, | ||
| uint64_t AlignInBits, | ||
| const char *Name) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DIDerivedType T = D->createPointerType(unwrapDI<DIType>(PointeeType), | ||
| SizeInBits, AlignInBits, Name); | ||
| return wrap(T); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref, | ||
| LLVMValueRef File, | ||
| LLVMValueRef ParameterTypes) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DICompositeType CT = D->createSubroutineType( | ||
| unwrapDI<DIFile>(File), unwrapDI<DITypeArray>(ParameterTypes)); | ||
| return wrap(CT); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateStructType( | ||
| LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name, | ||
| LLVMValueRef File, unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, | ||
| unsigned Flags, LLVMValueRef DerivedFrom, LLVMValueRef ElementTypes) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DICompositeType CT = D->createStructType( | ||
| unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line, | ||
| SizeInBits, AlignInBits, Flags, unwrapDI<DIType>(DerivedFrom), | ||
| unwrapDI<DIArray>(ElementTypes)); | ||
| return wrap(CT); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateMemberType( | ||
| LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name, | ||
| LLVMValueRef File, unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, | ||
| uint64_t OffsetInBits, unsigned Flags, LLVMValueRef Ty) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DIDerivedType DT = D->createMemberType( | ||
| unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line, | ||
| SizeInBits, AlignInBits, OffsetInBits, Flags, unwrapDI<DIType>(Ty)); | ||
| return wrap(DT); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref, | ||
| uint64_t SizeInBits, | ||
| uint64_t AlignInBits, | ||
| LLVMValueRef ElementType, | ||
| LLVMValueRef Subscripts) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DICompositeType CT = | ||
| D->createArrayType(SizeInBits, AlignInBits, unwrapDI<DIType>(ElementType), | ||
| unwrapDI<DIArray>(Subscripts)); | ||
| return wrap(CT); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref, LLVMValueRef Ty, | ||
| const char *Name, LLVMValueRef File, | ||
| unsigned Line, LLVMValueRef Context) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DIDerivedType DT = | ||
| D->createTypedef(unwrapDI<DIType>(Ty), Name, unwrapDI<DIFile>(File), Line, | ||
| unwrapDI<DIDescriptor>(Context)); | ||
| return wrap(DT); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Dref, int64_t Lo, | ||
| int64_t Count) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DISubrange S = D->getOrCreateSubrange(Lo, Count); | ||
| return wrap(S); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref, | ||
| LLVMValueRef *Data, size_t Length) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| Value **DataValue = unwrap(Data); | ||
| ArrayRef<Value *> Elements(DataValue, Length); | ||
| DIArray A = D->getOrCreateArray(Elements); | ||
| return wrap(A); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref, | ||
| LLVMValueRef *Data, | ||
| size_t Length) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| Value **DataValue = unwrap(Data); | ||
| ArrayRef<Value *> Elements(DataValue, Length); | ||
| DITypeArray A = D->getOrCreateTypeArray(Elements); | ||
| return wrap(A); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, int64_t *Addr, | ||
| size_t Length) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| DIExpression Expr = D->createExpression(ArrayRef<int64_t>(Addr, Length)); | ||
| return wrap(Expr); | ||
| } | ||
|
|
||
| LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref, | ||
| LLVMValueRef Storage, | ||
| LLVMValueRef VarInfo, | ||
| LLVMValueRef Expr, | ||
| LLVMBasicBlockRef Block) { | ||
| DIBuilder *D = unwrap(Dref); | ||
| Instruction *Instr = | ||
| D->insertDeclare(unwrap(Storage), unwrapDI<DIVariable>(VarInfo), | ||
| unwrapDI<DIExpression>(Expr), unwrap(Block)); | ||
| return wrap(Instr); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| //===- DIBuilderBindings.h - Bindings for DIBuilder -------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines C bindings for the DIBuilder class. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H | ||
| #define LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H | ||
|
|
||
| #include "llvm-c/Core.h" | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| // FIXME: These bindings shouldn't be Go-specific and should eventually move to | ||
| // a (somewhat) less stable collection of C APIs for use in creating bindings of | ||
| // LLVM in other languages. | ||
|
|
||
| typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef; | ||
|
|
||
| LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef m); | ||
|
|
||
| void LLVMDIBuilderDestroy(LLVMDIBuilderRef d); | ||
| void LLVMDIBuilderFinalize(LLVMDIBuilderRef d); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef D, | ||
| unsigned Language, const char *File, | ||
| const char *Dir, | ||
| const char *Producer, int Optimized, | ||
| const char *Flags, | ||
| unsigned RuntimeVersion); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef D, const char *File, | ||
| const char *Dir); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef D, | ||
| LLVMValueRef Scope, | ||
| LLVMValueRef File, unsigned Line, | ||
| unsigned Column); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef D, | ||
| LLVMValueRef Scope, | ||
| LLVMValueRef File, | ||
| unsigned Discriminator); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateFunction( | ||
| LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name, | ||
| const char *LinkageName, LLVMValueRef File, unsigned Line, | ||
| LLVMValueRef CompositeType, int IsLocalToUnit, int IsDefinition, | ||
| unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Function); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateLocalVariable( | ||
| LLVMDIBuilderRef D, unsigned Tag, LLVMValueRef Scope, const char *Name, | ||
| LLVMValueRef File, unsigned Line, LLVMValueRef Ty, int AlwaysPreserve, | ||
| unsigned Flags, unsigned ArgNo); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef D, const char *Name, | ||
| uint64_t SizeInBits, | ||
| uint64_t AlignInBits, | ||
| unsigned Encoding); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef D, | ||
| LLVMValueRef PointeeType, | ||
| uint64_t SizeInBits, | ||
| uint64_t AlignInBits, | ||
| const char *Name); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef D, | ||
| LLVMValueRef File, | ||
| LLVMValueRef ParameterTypes); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateStructType( | ||
| LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name, LLVMValueRef File, | ||
| unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, | ||
| LLVMValueRef DerivedFrom, LLVMValueRef ElementTypes); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateMemberType( | ||
| LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name, LLVMValueRef File, | ||
| unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, | ||
| uint64_t OffsetInBits, unsigned Flags, LLVMValueRef Ty); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef D, | ||
| uint64_t SizeInBits, | ||
| uint64_t AlignInBits, | ||
| LLVMValueRef ElementType, | ||
| LLVMValueRef Subscripts); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef D, LLVMValueRef Ty, | ||
| const char *Name, LLVMValueRef File, | ||
| unsigned Line, LLVMValueRef Context); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef D, int64_t Lo, | ||
| int64_t Count); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef D, | ||
| LLVMValueRef *Data, size_t Length); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef D, | ||
| LLVMValueRef *Data, | ||
| size_t Length); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, int64_t *Addr, | ||
| size_t Length); | ||
|
|
||
| LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef D, | ||
| LLVMValueRef Storage, | ||
| LLVMValueRef VarInfo, | ||
| LLVMValueRef Expr, | ||
| LLVMBasicBlockRef Block); | ||
|
|
||
| #ifdef __cplusplus | ||
| } // extern "C" | ||
| #endif | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| //===- IRBindings.cpp - Additional bindings for ir ------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines additional C bindings for the ir component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "IRBindings.h" | ||
|
|
||
| #include "llvm/IR/Attributes.h" | ||
| #include "llvm/IR/Function.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| void LLVMAddFunctionAttr2(LLVMValueRef Fn, uint64_t PA) { | ||
| Function *Func = unwrap<Function>(Fn); | ||
| const AttributeSet PAL = Func->getAttributes(); | ||
| AttrBuilder B(PA); | ||
| const AttributeSet PALnew = | ||
| PAL.addAttributes(Func->getContext(), AttributeSet::FunctionIndex, | ||
| AttributeSet::get(Func->getContext(), | ||
| AttributeSet::FunctionIndex, B)); | ||
| Func->setAttributes(PALnew); | ||
| } | ||
|
|
||
| uint64_t LLVMGetFunctionAttr2(LLVMValueRef Fn) { | ||
| Function *Func = unwrap<Function>(Fn); | ||
| const AttributeSet PAL = Func->getAttributes(); | ||
| return PAL.Raw(AttributeSet::FunctionIndex); | ||
| } | ||
|
|
||
| void LLVMRemoveFunctionAttr2(LLVMValueRef Fn, uint64_t PA) { | ||
| Function *Func = unwrap<Function>(Fn); | ||
| const AttributeSet PAL = Func->getAttributes(); | ||
| AttrBuilder B(PA); | ||
| const AttributeSet PALnew = | ||
| PAL.removeAttributes(Func->getContext(), AttributeSet::FunctionIndex, | ||
| AttributeSet::get(Func->getContext(), | ||
| AttributeSet::FunctionIndex, B)); | ||
| Func->setAttributes(PALnew); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| //===- IRBindings.h - Additional bindings for IR ----------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines additional C bindings for the IR component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H | ||
| #define LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H | ||
|
|
||
| #include "llvm-c/Core.h" | ||
| #include <stdint.h> | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| // These functions duplicate the LLVM*FunctionAttr functions in the stable C | ||
| // API. We cannot use the existing functions because they take 32-bit attribute | ||
| // values, and the Go bindings expose all of the LLVM attributes, some of which | ||
| // have values >= 1<<32. | ||
|
|
||
| void LLVMAddFunctionAttr2(LLVMValueRef Fn, uint64_t PA); | ||
| uint64_t LLVMGetFunctionAttr2(LLVMValueRef Fn); | ||
| void LLVMRemoveFunctionAttr2(LLVMValueRef Fn, uint64_t PA); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| //===- InstrumentationBindings.cpp - instrumentation bindings -------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines C bindings for the instrumentation component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "InstrumentationBindings.h" | ||
|
|
||
| #include "llvm-c/Core.h" | ||
| #include "llvm/IR/Module.h" | ||
| #include "llvm/PassManager.h" | ||
| #include "llvm/Transforms/Instrumentation.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM) { | ||
| unwrap(PM)->add(createAddressSanitizerFunctionPass()); | ||
| } | ||
|
|
||
| void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM) { | ||
| unwrap(PM)->add(createAddressSanitizerModulePass()); | ||
| } | ||
|
|
||
| void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) { | ||
| unwrap(PM)->add(createThreadSanitizerPass()); | ||
| } | ||
|
|
||
| void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM) { | ||
| unwrap(PM)->add(createMemorySanitizerPass()); | ||
| } | ||
|
|
||
| void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, | ||
| const char *ABIListFile) { | ||
| unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFile)); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| //===- InstrumentationBindings.h - instrumentation bindings -----*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines C bindings for the Transforms/Instrumentation component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_BINDINGS_GO_LLVM_INSTRUMENTATIONBINDINGS_H | ||
| #define LLVM_BINDINGS_GO_LLVM_INSTRUMENTATIONBINDINGS_H | ||
|
|
||
| #include "llvm-c/Core.h" | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| // FIXME: These bindings shouldn't be Go-specific and should eventually move to | ||
| // a (somewhat) less stable collection of C APIs for use in creating bindings of | ||
| // LLVM in other languages. | ||
|
|
||
| void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM); | ||
| void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM); | ||
| void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM); | ||
| void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM); | ||
| void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, | ||
| const char *ABIListFile); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| //===- SupportBindings.cpp - Additional bindings for support --------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines additional C bindings for the support component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "SupportBindings.h" | ||
|
|
||
| #include "llvm/Support/DynamicLibrary.h" | ||
| #include <stdlib.h> | ||
| #include <string.h> | ||
|
|
||
| void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg) { | ||
| std::string ErrMsgStr; | ||
| if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename, &ErrMsgStr)) { | ||
| *ErrMsg = static_cast<char *>(malloc(ErrMsgStr.size() + 1)); | ||
| memcpy(static_cast<void *>(*ErrMsg), | ||
| static_cast<const void *>(ErrMsgStr.c_str()), ErrMsgStr.size() + 1); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| //===- SupportBindings.h - Additional bindings for Support ------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines additional C bindings for the Support component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_BINDINGS_GO_LLVM_SUPPORTBINDINGS_H | ||
| #define LLVM_BINDINGS_GO_LLVM_SUPPORTBINDINGS_H | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| // This function duplicates the LLVMLoadLibraryPermanently function in the | ||
| // stable C API and adds an extra ErrMsg parameter to retrieve the error | ||
| // message. | ||
| void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| //===- analysis.go - Bindings for analysis --------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the analysis component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/Analysis.h" // If you are getting an error here read bindings/go/README.txt | ||
| #include <stdlib.h> | ||
| */ | ||
| import "C" | ||
| import "errors" | ||
|
|
||
| type VerifierFailureAction C.LLVMVerifierFailureAction | ||
|
|
||
| const ( | ||
| // verifier will print to stderr and abort() | ||
| AbortProcessAction VerifierFailureAction = C.LLVMAbortProcessAction | ||
| // verifier will print to stderr and return 1 | ||
| PrintMessageAction VerifierFailureAction = C.LLVMPrintMessageAction | ||
| // verifier will just return 1 | ||
| ReturnStatusAction VerifierFailureAction = C.LLVMReturnStatusAction | ||
| ) | ||
|
|
||
| // Verifies that a module is valid, taking the specified action if not. | ||
| // Optionally returns a human-readable description of any invalid constructs. | ||
| func VerifyModule(m Module, a VerifierFailureAction) error { | ||
| var cmsg *C.char | ||
| broken := C.LLVMVerifyModule(m.C, C.LLVMVerifierFailureAction(a), &cmsg) | ||
|
|
||
| // C++'s verifyModule means isModuleBroken, so it returns false if | ||
| // there are no errors | ||
| if broken != 0 { | ||
| err := errors.New(C.GoString(cmsg)) | ||
| C.LLVMDisposeMessage(cmsg) | ||
| return err | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| var verifyFunctionError = errors.New("Function is broken") | ||
|
|
||
| // Verifies that a single function is valid, taking the specified action. | ||
| // Useful for debugging. | ||
| func VerifyFunction(f Value, a VerifierFailureAction) error { | ||
| broken := C.LLVMVerifyFunction(f.C, C.LLVMVerifierFailureAction(a)) | ||
|
|
||
| // C++'s verifyFunction means isFunctionBroken, so it returns false if | ||
| // there are no errors | ||
| if broken != 0 { | ||
| return verifyFunctionError | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // Open up a ghostview window that displays the CFG of the current function. | ||
| // Useful for debugging. | ||
| func ViewFunctionCFG(f Value) { C.LLVMViewFunctionCFG(f.C) } | ||
| func ViewFunctionCFGOnly(f Value) { C.LLVMViewFunctionCFGOnly(f.C) } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| //===- bitreader.go - Bindings for bitreader ------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the bitreader component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/BitReader.h" | ||
| #include <stdlib.h> | ||
| */ | ||
| import "C" | ||
|
|
||
| import ( | ||
| "errors" | ||
| "unsafe" | ||
| ) | ||
|
|
||
| // ParseBitcodeFile parses the LLVM IR (bitcode) in the file with the | ||
| // specified name, and returns a new LLVM module. | ||
| func ParseBitcodeFile(name string) (Module, error) { | ||
| var buf C.LLVMMemoryBufferRef | ||
| var errmsg *C.char | ||
| var cfilename *C.char = C.CString(name) | ||
| defer C.free(unsafe.Pointer(cfilename)) | ||
| result := C.LLVMCreateMemoryBufferWithContentsOfFile(cfilename, &buf, &errmsg) | ||
| if result != 0 { | ||
| err := errors.New(C.GoString(errmsg)) | ||
| C.free(unsafe.Pointer(errmsg)) | ||
| return Module{}, err | ||
| } | ||
| defer C.LLVMDisposeMemoryBuffer(buf) | ||
|
|
||
| var m Module | ||
| if C.LLVMParseBitcode(buf, &m.C, &errmsg) == 0 { | ||
| return m, nil | ||
| } | ||
|
|
||
| err := errors.New(C.GoString(errmsg)) | ||
| C.free(unsafe.Pointer(errmsg)) | ||
| return Module{}, err | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| //===- bitwriter.go - Bindings for bitwriter ------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the bitwriter component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/BitWriter.h" | ||
| #include <stdlib.h> | ||
| */ | ||
| import "C" | ||
| import "os" | ||
| import "errors" | ||
|
|
||
| var writeBitcodeToFileErr = errors.New("Failed to write bitcode to file") | ||
|
|
||
| func WriteBitcodeToFile(m Module, file *os.File) error { | ||
| fail := C.LLVMWriteBitcodeToFD(m.C, C.int(file.Fd()), C.int(0), C.int(0)) | ||
| if fail != 0 { | ||
| return writeBitcodeToFileErr | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func WriteBitcodeToMemoryBuffer(m Module) MemoryBuffer { | ||
| mb := C.LLVMWriteBitcodeToMemoryBuffer(m.C) | ||
| return MemoryBuffer{mb} | ||
| } | ||
|
|
||
| // TODO(nsf): Figure out way how to make it work with io.Writer |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| //===- executionengine.go - Bindings for executionengine ------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the executionengine component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/ExecutionEngine.h" | ||
| #include <stdlib.h> | ||
| */ | ||
| import "C" | ||
| import "unsafe" | ||
| import "errors" | ||
|
|
||
| func LinkInMCJIT() { C.LLVMLinkInMCJIT() } | ||
| func LinkInInterpreter() { C.LLVMLinkInInterpreter() } | ||
|
|
||
| type GenericValue struct { | ||
| C C.LLVMGenericValueRef | ||
| } | ||
| type ExecutionEngine struct { | ||
| C C.LLVMExecutionEngineRef | ||
| } | ||
| type MCJITCompilerOptions struct { | ||
| OptLevel uint | ||
| CodeModel CodeModel | ||
| NoFramePointerElim bool | ||
| EnableFastISel bool | ||
| } | ||
|
|
||
| // helpers | ||
| func llvmGenericValueRefPtr(t *GenericValue) *C.LLVMGenericValueRef { | ||
| return (*C.LLVMGenericValueRef)(unsafe.Pointer(t)) | ||
| } | ||
|
|
||
| //------------------------------------------------------------------------- | ||
| // llvm.GenericValue | ||
| //------------------------------------------------------------------------- | ||
|
|
||
| func NewGenericValueFromInt(t Type, n uint64, signed bool) (g GenericValue) { | ||
| g.C = C.LLVMCreateGenericValueOfInt(t.C, C.ulonglong(n), boolToLLVMBool(signed)) | ||
| return | ||
| } | ||
| func NewGenericValueFromPointer(p unsafe.Pointer) (g GenericValue) { | ||
| g.C = C.LLVMCreateGenericValueOfPointer(p) | ||
| return | ||
| } | ||
| func NewGenericValueFromFloat(t Type, n float64) (g GenericValue) { | ||
| g.C = C.LLVMCreateGenericValueOfFloat(t.C, C.double(n)) | ||
| return | ||
| } | ||
| func (g GenericValue) IntWidth() int { return int(C.LLVMGenericValueIntWidth(g.C)) } | ||
| func (g GenericValue) Int(signed bool) uint64 { | ||
| return uint64(C.LLVMGenericValueToInt(g.C, boolToLLVMBool(signed))) | ||
| } | ||
| func (g GenericValue) Float(t Type) float64 { | ||
| return float64(C.LLVMGenericValueToFloat(t.C, g.C)) | ||
| } | ||
| func (g GenericValue) Pointer() unsafe.Pointer { | ||
| return C.LLVMGenericValueToPointer(g.C) | ||
| } | ||
| func (g GenericValue) Dispose() { C.LLVMDisposeGenericValue(g.C) } | ||
|
|
||
| //------------------------------------------------------------------------- | ||
| // llvm.ExecutionEngine | ||
| //------------------------------------------------------------------------- | ||
|
|
||
| func NewExecutionEngine(m Module) (ee ExecutionEngine, err error) { | ||
| var cmsg *C.char | ||
| fail := C.LLVMCreateExecutionEngineForModule(&ee.C, m.C, &cmsg) | ||
| if fail != 0 { | ||
| ee.C = nil | ||
| err = errors.New(C.GoString(cmsg)) | ||
| C.LLVMDisposeMessage(cmsg) | ||
| } | ||
| return | ||
| } | ||
|
|
||
| func NewInterpreter(m Module) (ee ExecutionEngine, err error) { | ||
| var cmsg *C.char | ||
| fail := C.LLVMCreateInterpreterForModule(&ee.C, m.C, &cmsg) | ||
| if fail != 0 { | ||
| ee.C = nil | ||
| err = errors.New(C.GoString(cmsg)) | ||
| C.LLVMDisposeMessage(cmsg) | ||
| } | ||
| return | ||
| } | ||
|
|
||
| func NewMCJITCompiler(m Module, options MCJITCompilerOptions) (ee ExecutionEngine, err error) { | ||
| var cmsg *C.char | ||
| copts := C.struct_LLVMMCJITCompilerOptions{ | ||
| OptLevel: C.unsigned(options.OptLevel), | ||
| CodeModel: C.LLVMCodeModel(options.CodeModel), | ||
| NoFramePointerElim: boolToLLVMBool(options.NoFramePointerElim), | ||
| EnableFastISel: boolToLLVMBool(options.EnableFastISel), | ||
| } | ||
| fail := C.LLVMCreateMCJITCompilerForModule(&ee.C, m.C, &copts, C.size_t(unsafe.Sizeof(copts)), &cmsg) | ||
| if fail != 0 { | ||
| ee.C = nil | ||
| err = errors.New(C.GoString(cmsg)) | ||
| C.LLVMDisposeMessage(cmsg) | ||
| } | ||
| return | ||
| } | ||
|
|
||
| func (ee ExecutionEngine) Dispose() { C.LLVMDisposeExecutionEngine(ee.C) } | ||
| func (ee ExecutionEngine) RunStaticConstructors() { C.LLVMRunStaticConstructors(ee.C) } | ||
| func (ee ExecutionEngine) RunStaticDestructors() { C.LLVMRunStaticDestructors(ee.C) } | ||
|
|
||
| func (ee ExecutionEngine) RunFunction(f Value, args []GenericValue) (g GenericValue) { | ||
| nargs := len(args) | ||
| var argptr *GenericValue | ||
| if nargs > 0 { | ||
| argptr = &args[0] | ||
| } | ||
| g.C = C.LLVMRunFunction(ee.C, f.C, | ||
| C.unsigned(nargs), llvmGenericValueRefPtr(argptr)) | ||
| return | ||
| } | ||
|
|
||
| func (ee ExecutionEngine) FreeMachineCodeForFunction(f Value) { | ||
| C.LLVMFreeMachineCodeForFunction(ee.C, f.C) | ||
| } | ||
| func (ee ExecutionEngine) AddModule(m Module) { C.LLVMAddModule(ee.C, m.C) } | ||
|
|
||
| func (ee ExecutionEngine) RemoveModule(m Module) { | ||
| var modtmp C.LLVMModuleRef | ||
| C.LLVMRemoveModule(ee.C, m.C, &modtmp, nil) | ||
| } | ||
|
|
||
| func (ee ExecutionEngine) FindFunction(name string) (f Value) { | ||
| cname := C.CString(name) | ||
| defer C.free(unsafe.Pointer(cname)) | ||
| C.LLVMFindFunction(ee.C, cname, &f.C) | ||
| return | ||
| } | ||
|
|
||
| func (ee ExecutionEngine) RecompileAndRelinkFunction(f Value) unsafe.Pointer { | ||
| return C.LLVMRecompileAndRelinkFunction(ee.C, f.C) | ||
| } | ||
|
|
||
| func (ee ExecutionEngine) TargetData() (td TargetData) { | ||
| td.C = C.LLVMGetExecutionEngineTargetData(ee.C) | ||
| return | ||
| } | ||
|
|
||
| func (ee ExecutionEngine) AddGlobalMapping(global Value, addr unsafe.Pointer) { | ||
| C.LLVMAddGlobalMapping(ee.C, global.C, addr) | ||
| } | ||
|
|
||
| func (ee ExecutionEngine) PointerToGlobal(global Value) unsafe.Pointer { | ||
| return C.LLVMGetPointerToGlobal(ee.C, global.C) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| //===- executionengine_test.go - Tests for executionengine ----------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file tests bindings for the executionengine component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| import ( | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestFactorial(t *testing.T) { | ||
| LinkInMCJIT() | ||
| InitializeNativeTarget() | ||
| InitializeNativeAsmPrinter() | ||
|
|
||
| mod := NewModule("fac_module") | ||
|
|
||
| fac_args := []Type{Int32Type()} | ||
| fac_type := FunctionType(Int32Type(), fac_args, false) | ||
| fac := AddFunction(mod, "fac", fac_type) | ||
| fac.SetFunctionCallConv(CCallConv) | ||
| n := fac.Param(0) | ||
|
|
||
| entry := AddBasicBlock(fac, "entry") | ||
| iftrue := AddBasicBlock(fac, "iftrue") | ||
| iffalse := AddBasicBlock(fac, "iffalse") | ||
| end := AddBasicBlock(fac, "end") | ||
|
|
||
| builder := NewBuilder() | ||
| defer builder.Dispose() | ||
|
|
||
| builder.SetInsertPointAtEnd(entry) | ||
| If := builder.CreateICmp(IntEQ, n, ConstInt(Int32Type(), 0, false), "cmptmp") | ||
| builder.CreateCondBr(If, iftrue, iffalse) | ||
|
|
||
| builder.SetInsertPointAtEnd(iftrue) | ||
| res_iftrue := ConstInt(Int32Type(), 1, false) | ||
| builder.CreateBr(end) | ||
|
|
||
| builder.SetInsertPointAtEnd(iffalse) | ||
| n_minus := builder.CreateSub(n, ConstInt(Int32Type(), 1, false), "subtmp") | ||
| call_fac_args := []Value{n_minus} | ||
| call_fac := builder.CreateCall(fac, call_fac_args, "calltmp") | ||
| res_iffalse := builder.CreateMul(n, call_fac, "multmp") | ||
| builder.CreateBr(end) | ||
|
|
||
| builder.SetInsertPointAtEnd(end) | ||
| res := builder.CreatePHI(Int32Type(), "result") | ||
| phi_vals := []Value{res_iftrue, res_iffalse} | ||
| phi_blocks := []BasicBlock{iftrue, iffalse} | ||
| res.AddIncoming(phi_vals, phi_blocks) | ||
| builder.CreateRet(res) | ||
|
|
||
| err := VerifyModule(mod, ReturnStatusAction) | ||
| if err != nil { | ||
| t.Errorf("Error verifying module: %s", err) | ||
| return | ||
| } | ||
|
|
||
| engine, err := NewMCJITCompiler(mod, MCJITCompilerOptions{OptLevel: 2}) | ||
| if err != nil { | ||
| t.Errorf("Error creating JIT: %s", err) | ||
| return | ||
| } | ||
| defer engine.Dispose() | ||
|
|
||
| pass := NewPassManager() | ||
| defer pass.Dispose() | ||
|
|
||
| pass.Add(engine.TargetData()) | ||
| pass.AddConstantPropagationPass() | ||
| pass.AddInstructionCombiningPass() | ||
| pass.AddPromoteMemoryToRegisterPass() | ||
| pass.AddGVNPass() | ||
| pass.AddCFGSimplificationPass() | ||
| pass.Run(mod) | ||
|
|
||
| exec_args := []GenericValue{NewGenericValueFromInt(Int32Type(), 10, false)} | ||
| exec_res := engine.RunFunction(fac, exec_args) | ||
| var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 | ||
| if exec_res.Int(false) != fac10 { | ||
| t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false)) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| //===- ir_test.go - Tests for ir ------------------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file tests bindings for the ir component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| import ( | ||
| "strings" | ||
| "testing" | ||
| ) | ||
|
|
||
| func testAttribute(t *testing.T, attr Attribute, name string) { | ||
| mod := NewModule("") | ||
| defer mod.Dispose() | ||
|
|
||
| ftyp := FunctionType(VoidType(), nil, false) | ||
| fn := AddFunction(mod, "foo", ftyp) | ||
|
|
||
| fn.AddFunctionAttr(attr) | ||
| newattr := fn.FunctionAttr() | ||
| if attr != newattr { | ||
| t.Errorf("got attribute mask %d, want %d", newattr, attr) | ||
| } | ||
|
|
||
| text := mod.String() | ||
| if !strings.Contains(text, " "+name+" ") { | ||
| t.Errorf("expected attribute '%s', got:\n%s", name, text) | ||
| } | ||
|
|
||
| fn.RemoveFunctionAttr(attr) | ||
| newattr = fn.FunctionAttr() | ||
| if newattr != 0 { | ||
| t.Errorf("got attribute mask %d, want 0", newattr) | ||
| } | ||
| } | ||
|
|
||
| func TestAttributes(t *testing.T) { | ||
| // Tests that our attribute constants haven't drifted from LLVM's. | ||
| attrTests := []struct { | ||
| attr Attribute | ||
| name string | ||
| }{ | ||
| {SanitizeAddressAttribute, "sanitize_address"}, | ||
| {AlwaysInlineAttribute, "alwaysinline"}, | ||
| {BuiltinAttribute, "builtin"}, | ||
| {ByValAttribute, "byval"}, | ||
| {InAllocaAttribute, "inalloca"}, | ||
| {InlineHintAttribute, "inlinehint"}, | ||
| {InRegAttribute, "inreg"}, | ||
| {JumpTableAttribute, "jumptable"}, | ||
| {MinSizeAttribute, "minsize"}, | ||
| {NakedAttribute, "naked"}, | ||
| {NestAttribute, "nest"}, | ||
| {NoAliasAttribute, "noalias"}, | ||
| {NoBuiltinAttribute, "nobuiltin"}, | ||
| {NoCaptureAttribute, "nocapture"}, | ||
| {NoDuplicateAttribute, "noduplicate"}, | ||
| {NoImplicitFloatAttribute, "noimplicitfloat"}, | ||
| {NoInlineAttribute, "noinline"}, | ||
| {NonLazyBindAttribute, "nonlazybind"}, | ||
| {NonNullAttribute, "nonnull"}, | ||
| {NoRedZoneAttribute, "noredzone"}, | ||
| {NoReturnAttribute, "noreturn"}, | ||
| {NoUnwindAttribute, "nounwind"}, | ||
| {OptimizeNoneAttribute, "optnone"}, | ||
| {OptimizeForSizeAttribute, "optsize"}, | ||
| {ReadNoneAttribute, "readnone"}, | ||
| {ReadOnlyAttribute, "readonly"}, | ||
| {ReturnedAttribute, "returned"}, | ||
| {ReturnsTwiceAttribute, "returns_twice"}, | ||
| {SExtAttribute, "signext"}, | ||
| {StackProtectAttribute, "ssp"}, | ||
| {StackProtectReqAttribute, "sspreq"}, | ||
| {StackProtectStrongAttribute, "sspstrong"}, | ||
| {StructRetAttribute, "sret"}, | ||
| {SanitizeThreadAttribute, "sanitize_thread"}, | ||
| {SanitizeMemoryAttribute, "sanitize_memory"}, | ||
| {UWTableAttribute, "uwtable"}, | ||
| {ZExtAttribute, "zeroext"}, | ||
| {ColdAttribute, "cold"}, | ||
| } | ||
|
|
||
| for _, a := range attrTests { | ||
| testAttribute(t, a.attr, a.name) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| //===- linker.go - Bindings for linker ------------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the linker component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/Linker.h" | ||
| #include <stdlib.h> | ||
| */ | ||
| import "C" | ||
| import "errors" | ||
|
|
||
| type LinkerMode C.LLVMLinkerMode | ||
|
|
||
| const ( | ||
| LinkerDestroySource = C.LLVMLinkerDestroySource | ||
| LinkerPreserveSource = C.LLVMLinkerPreserveSource | ||
| ) | ||
|
|
||
| func LinkModules(Dest, Src Module, Mode LinkerMode) error { | ||
| var cmsg *C.char | ||
| failed := C.LLVMLinkModules(Dest.C, Src.C, C.LLVMLinkerMode(Mode), &cmsg) | ||
| if failed != 0 { | ||
| err := errors.New(C.GoString(cmsg)) | ||
| C.LLVMDisposeMessage(cmsg) | ||
| return err | ||
| } | ||
| return nil | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // +build !byollvm | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #cgo CXXFLAGS: -std=c++11 | ||
| #cgo CPPFLAGS: @LLVM_CFLAGS@ | ||
| #cgo LDFLAGS: @LLVM_LDFLAGS@ | ||
| */ | ||
| import "C" | ||
|
|
||
| type (run_build_sh int) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| //===- llvm_dep.go - creates LLVM dependency ------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file ensures that the LLVM libraries are built before using the | ||
| // bindings. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| // +build !byollvm | ||
|
|
||
| package llvm | ||
|
|
||
| var _ run_build_sh |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| //===- string.go - Stringer implementation for Type -----------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements the Stringer interface for the Type type. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| import "fmt" | ||
|
|
||
| func (t TypeKind) String() string { | ||
| switch t { | ||
| case VoidTypeKind: | ||
| return "VoidTypeKind" | ||
| case FloatTypeKind: | ||
| return "FloatTypeKind" | ||
| case DoubleTypeKind: | ||
| return "DoubleTypeKind" | ||
| case X86_FP80TypeKind: | ||
| return "X86_FP80TypeKind" | ||
| case FP128TypeKind: | ||
| return "FP128TypeKind" | ||
| case PPC_FP128TypeKind: | ||
| return "PPC_FP128TypeKind" | ||
| case LabelTypeKind: | ||
| return "LabelTypeKind" | ||
| case IntegerTypeKind: | ||
| return "IntegerTypeKind" | ||
| case FunctionTypeKind: | ||
| return "FunctionTypeKind" | ||
| case StructTypeKind: | ||
| return "StructTypeKind" | ||
| case ArrayTypeKind: | ||
| return "ArrayTypeKind" | ||
| case PointerTypeKind: | ||
| return "PointerTypeKind" | ||
| case VectorTypeKind: | ||
| return "VectorTypeKind" | ||
| case MetadataTypeKind: | ||
| return "MetadataTypeKind" | ||
| } | ||
| panic("unreachable") | ||
| } | ||
|
|
||
| func (t Type) String() string { | ||
| ts := typeStringer{s: make(map[Type]string)} | ||
| return ts.typeString(t) | ||
| } | ||
|
|
||
| type typeStringer struct { | ||
| s map[Type]string | ||
| } | ||
|
|
||
| func (ts *typeStringer) typeString(t Type) string { | ||
| if s, ok := ts.s[t]; ok { | ||
| return s | ||
| } | ||
|
|
||
| k := t.TypeKind() | ||
| s := k.String() | ||
| s = s[:len(s)-len("Kind")] | ||
|
|
||
| switch k { | ||
| case ArrayTypeKind: | ||
| s += fmt.Sprintf("(%v[%v])", ts.typeString(t.ElementType()), t.ArrayLength()) | ||
| case PointerTypeKind: | ||
| s += fmt.Sprintf("(%v)", ts.typeString(t.ElementType())) | ||
| case FunctionTypeKind: | ||
| params := t.ParamTypes() | ||
| s += "(" | ||
| if len(params) > 0 { | ||
| s += fmt.Sprintf("%v", ts.typeString(params[0])) | ||
| for i := 1; i < len(params); i++ { | ||
| s += fmt.Sprintf(", %v", ts.typeString(params[i])) | ||
| } | ||
| } | ||
| s += fmt.Sprintf("):%v", ts.typeString(t.ReturnType())) | ||
| case StructTypeKind: | ||
| if name := t.StructName(); name != "" { | ||
| ts.s[t] = "%" + name | ||
| s = fmt.Sprintf("%%%s: %s", name, s) | ||
| } | ||
| etypes := t.StructElementTypes() | ||
| s += "(" | ||
| if n := len(etypes); n > 0 { | ||
| s += ts.typeString(etypes[0]) | ||
| for i := 1; i < n; i++ { | ||
| s += fmt.Sprintf(", %v", ts.typeString(etypes[i])) | ||
| } | ||
| } | ||
| s += ")" | ||
| case IntegerTypeKind: | ||
| s += fmt.Sprintf("(%d bits)", t.IntTypeWidth()) | ||
| } | ||
|
|
||
| ts.s[t] = s | ||
| return s | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //===- string_test.go - test Stringer implementation for Type -------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file tests the Stringer interface for the Type type. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| import ( | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestStringRecursiveType(t *testing.T) { | ||
| ctx := NewContext() | ||
| defer ctx.Dispose() | ||
| s := ctx.StructCreateNamed("recursive") | ||
| s.StructSetBody([]Type{s, s}, false) | ||
| if str := s.String(); str != "%recursive: StructType(%recursive, %recursive)" { | ||
| t.Errorf("incorrect string result %q", str) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| //===- support.go - Bindings for support ----------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the support component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/Support.h" | ||
| #include "SupportBindings.h" | ||
| #include <stdlib.h> | ||
| */ | ||
| import "C" | ||
|
|
||
| import ( | ||
| "errors" | ||
| "unsafe" | ||
| ) | ||
|
|
||
| // Loads a dynamic library such that it may be used as an LLVM plugin. | ||
| // See llvm::sys::DynamicLibrary::LoadLibraryPermanently. | ||
| func LoadLibraryPermanently(lib string) error { | ||
| var errstr *C.char | ||
| libstr := C.CString(lib) | ||
| defer C.free(unsafe.Pointer(libstr)) | ||
| C.LLVMLoadLibraryPermanently2(libstr, &errstr) | ||
| if errstr != nil { | ||
| err := errors.New(C.GoString(errstr)) | ||
| C.free(unsafe.Pointer(errstr)) | ||
| return err | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // Parse the given arguments using the LLVM command line parser. | ||
| // See llvm::cl::ParseCommandLineOptions. | ||
| func ParseCommandLineOptions(args []string, overview string) { | ||
| argstrs := make([]*C.char, len(args)) | ||
| for i, arg := range args { | ||
| argstrs[i] = C.CString(arg) | ||
| defer C.free(unsafe.Pointer(argstrs[i])) | ||
| } | ||
| overviewstr := C.CString(overview) | ||
| defer C.free(unsafe.Pointer(overviewstr)) | ||
| C.LLVMParseCommandLineOptions(C.int(len(args)), &argstrs[0], overviewstr) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,300 @@ | ||
| //===- target.go - Bindings for target ------------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the target component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/Target.h" | ||
| #include "llvm-c/TargetMachine.h" | ||
| #include <stdlib.h> | ||
| */ | ||
| import "C" | ||
| import "unsafe" | ||
| import "errors" | ||
|
|
||
| type ( | ||
| TargetData struct { | ||
| C C.LLVMTargetDataRef | ||
| } | ||
| Target struct { | ||
| C C.LLVMTargetRef | ||
| } | ||
| TargetMachine struct { | ||
| C C.LLVMTargetMachineRef | ||
| } | ||
| ByteOrdering C.enum_LLVMByteOrdering | ||
| RelocMode C.LLVMRelocMode | ||
| CodeGenOptLevel C.LLVMCodeGenOptLevel | ||
| CodeGenFileType C.LLVMCodeGenFileType | ||
| CodeModel C.LLVMCodeModel | ||
| ) | ||
|
|
||
| const ( | ||
| BigEndian ByteOrdering = C.LLVMBigEndian | ||
| LittleEndian ByteOrdering = C.LLVMLittleEndian | ||
| ) | ||
|
|
||
| const ( | ||
| RelocDefault RelocMode = C.LLVMRelocDefault | ||
| RelocStatic RelocMode = C.LLVMRelocStatic | ||
| RelocPIC RelocMode = C.LLVMRelocPIC | ||
| RelocDynamicNoPic RelocMode = C.LLVMRelocDynamicNoPic | ||
| ) | ||
|
|
||
| const ( | ||
| CodeGenLevelNone CodeGenOptLevel = C.LLVMCodeGenLevelNone | ||
| CodeGenLevelLess CodeGenOptLevel = C.LLVMCodeGenLevelLess | ||
| CodeGenLevelDefault CodeGenOptLevel = C.LLVMCodeGenLevelDefault | ||
| CodeGenLevelAggressive CodeGenOptLevel = C.LLVMCodeGenLevelAggressive | ||
| ) | ||
|
|
||
| const ( | ||
| CodeModelDefault CodeModel = C.LLVMCodeModelDefault | ||
| CodeModelJITDefault CodeModel = C.LLVMCodeModelJITDefault | ||
| CodeModelSmall CodeModel = C.LLVMCodeModelSmall | ||
| CodeModelKernel CodeModel = C.LLVMCodeModelKernel | ||
| CodeModelMedium CodeModel = C.LLVMCodeModelMedium | ||
| CodeModelLarge CodeModel = C.LLVMCodeModelLarge | ||
| ) | ||
|
|
||
| const ( | ||
| AssemblyFile CodeGenFileType = C.LLVMAssemblyFile | ||
| ObjectFile CodeGenFileType = C.LLVMObjectFile | ||
| ) | ||
|
|
||
| // InitializeAllTargetInfos - The main program should call this function if it | ||
| // wants access to all available targets that LLVM is configured to support. | ||
| func InitializeAllTargetInfos() { C.LLVMInitializeAllTargetInfos() } | ||
|
|
||
| // InitializeAllTargets - The main program should call this function if it wants | ||
| // to link in all available targets that LLVM is configured to support. | ||
| func InitializeAllTargets() { C.LLVMInitializeAllTargets() } | ||
|
|
||
| func InitializeAllTargetMCs() { C.LLVMInitializeAllTargetMCs() } | ||
|
|
||
| func InitializeAllAsmParsers() { C.LLVMInitializeAllAsmParsers() } | ||
|
|
||
| func InitializeAllAsmPrinters() { C.LLVMInitializeAllAsmPrinters() } | ||
|
|
||
| var initializeNativeTargetError = errors.New("Failed to initialize native target") | ||
|
|
||
| // InitializeNativeTarget - The main program should call this function to | ||
| // initialize the native target corresponding to the host. This is useful | ||
| // for JIT applications to ensure that the target gets linked in correctly. | ||
| func InitializeNativeTarget() error { | ||
| fail := C.LLVMInitializeNativeTarget() | ||
| if fail != 0 { | ||
| return initializeNativeTargetError | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func InitializeNativeAsmPrinter() error { | ||
| fail := C.LLVMInitializeNativeAsmPrinter() | ||
| if fail != 0 { | ||
| return initializeNativeTargetError | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| //------------------------------------------------------------------------- | ||
| // llvm.TargetData | ||
| //------------------------------------------------------------------------- | ||
|
|
||
| // Creates target data from a target layout string. | ||
| // See the constructor llvm::TargetData::TargetData. | ||
| func NewTargetData(rep string) (td TargetData) { | ||
| crep := C.CString(rep) | ||
| defer C.free(unsafe.Pointer(crep)) | ||
| td.C = C.LLVMCreateTargetData(crep) | ||
| return | ||
| } | ||
|
|
||
| // Adds target data information to a pass manager. This does not take ownership | ||
| // of the target data. | ||
| // See the method llvm::PassManagerBase::add. | ||
| func (pm PassManager) Add(td TargetData) { | ||
| C.LLVMAddTargetData(td.C, pm.C) | ||
| } | ||
|
|
||
| // Converts target data to a target layout string. The string must be disposed | ||
| // with LLVMDisposeMessage. | ||
| // See the constructor llvm::TargetData::TargetData. | ||
| func (td TargetData) String() (s string) { | ||
| cmsg := C.LLVMCopyStringRepOfTargetData(td.C) | ||
| s = C.GoString(cmsg) | ||
| C.LLVMDisposeMessage(cmsg) | ||
| return | ||
| } | ||
|
|
||
| // Returns the byte order of a target, either BigEndian or LittleEndian. | ||
| // See the method llvm::TargetData::isLittleEndian. | ||
| func (td TargetData) ByteOrder() ByteOrdering { return ByteOrdering(C.LLVMByteOrder(td.C)) } | ||
|
|
||
| // Returns the pointer size in bytes for a target. | ||
| // See the method llvm::TargetData::getPointerSize. | ||
| func (td TargetData) PointerSize() int { return int(C.LLVMPointerSize(td.C)) } | ||
|
|
||
| // Returns the integer type that is the same size as a pointer on a target. | ||
| // See the method llvm::TargetData::getIntPtrType. | ||
| func (td TargetData) IntPtrType() (t Type) { t.C = C.LLVMIntPtrType(td.C); return } | ||
|
|
||
| // Computes the size of a type in bytes for a target. | ||
| // See the method llvm::TargetData::getTypeSizeInBits. | ||
| func (td TargetData) TypeSizeInBits(t Type) uint64 { | ||
| return uint64(C.LLVMSizeOfTypeInBits(td.C, t.C)) | ||
| } | ||
|
|
||
| // Computes the storage size of a type in bytes for a target. | ||
| // See the method llvm::TargetData::getTypeStoreSize. | ||
| func (td TargetData) TypeStoreSize(t Type) uint64 { | ||
| return uint64(C.LLVMStoreSizeOfType(td.C, t.C)) | ||
| } | ||
|
|
||
| // Computes the ABI size of a type in bytes for a target. | ||
| // See the method llvm::TargetData::getTypeAllocSize. | ||
| func (td TargetData) TypeAllocSize(t Type) uint64 { | ||
| return uint64(C.LLVMABISizeOfType(td.C, t.C)) | ||
| } | ||
|
|
||
| // Computes the ABI alignment of a type in bytes for a target. | ||
| // See the method llvm::TargetData::getABITypeAlignment. | ||
| func (td TargetData) ABITypeAlignment(t Type) int { | ||
| return int(C.LLVMABIAlignmentOfType(td.C, t.C)) | ||
| } | ||
|
|
||
| // Computes the call frame alignment of a type in bytes for a target. | ||
| // See the method llvm::TargetData::getCallFrameTypeAlignment. | ||
| func (td TargetData) CallFrameTypeAlignment(t Type) int { | ||
| return int(C.LLVMCallFrameAlignmentOfType(td.C, t.C)) | ||
| } | ||
|
|
||
| // Computes the preferred alignment of a type in bytes for a target. | ||
| // See the method llvm::TargetData::getPrefTypeAlignment. | ||
| func (td TargetData) PrefTypeAlignment(t Type) int { | ||
| return int(C.LLVMPreferredAlignmentOfType(td.C, t.C)) | ||
| } | ||
|
|
||
| // Computes the preferred alignment of a global variable in bytes for a target. | ||
| // See the method llvm::TargetData::getPreferredAlignment. | ||
| func (td TargetData) PreferredAlignment(g Value) int { | ||
| return int(C.LLVMPreferredAlignmentOfGlobal(td.C, g.C)) | ||
| } | ||
|
|
||
| // Computes the structure element that contains the byte offset for a target. | ||
| // See the method llvm::StructLayout::getElementContainingOffset. | ||
| func (td TargetData) ElementContainingOffset(t Type, offset uint64) int { | ||
| return int(C.LLVMElementAtOffset(td.C, t.C, C.ulonglong(offset))) | ||
| } | ||
|
|
||
| // Computes the byte offset of the indexed struct element for a target. | ||
| // See the method llvm::StructLayout::getElementOffset. | ||
| func (td TargetData) ElementOffset(t Type, element int) uint64 { | ||
| return uint64(C.LLVMOffsetOfElement(td.C, t.C, C.unsigned(element))) | ||
| } | ||
|
|
||
| // Deallocates a TargetData. | ||
| // See the destructor llvm::TargetData::~TargetData. | ||
| func (td TargetData) Dispose() { C.LLVMDisposeTargetData(td.C) } | ||
|
|
||
| //------------------------------------------------------------------------- | ||
| // llvm.Target | ||
| //------------------------------------------------------------------------- | ||
|
|
||
| func FirstTarget() Target { | ||
| return Target{C.LLVMGetFirstTarget()} | ||
| } | ||
|
|
||
| func (t Target) NextTarget() Target { | ||
| return Target{C.LLVMGetNextTarget(t.C)} | ||
| } | ||
|
|
||
| func GetTargetFromTriple(triple string) (t Target, err error) { | ||
| var errstr *C.char | ||
| ctriple := C.CString(triple) | ||
| defer C.free(unsafe.Pointer(ctriple)) | ||
| fail := C.LLVMGetTargetFromTriple(ctriple, &t.C, &errstr) | ||
| if fail != 0 { | ||
| err = errors.New(C.GoString(errstr)) | ||
| C.free(unsafe.Pointer(errstr)) | ||
| } | ||
| return | ||
| } | ||
|
|
||
| func (t Target) Name() string { | ||
| return C.GoString(C.LLVMGetTargetName(t.C)) | ||
| } | ||
|
|
||
| func (t Target) Description() string { | ||
| return C.GoString(C.LLVMGetTargetDescription(t.C)) | ||
| } | ||
|
|
||
| //------------------------------------------------------------------------- | ||
| // llvm.TargetMachine | ||
| //------------------------------------------------------------------------- | ||
|
|
||
| // CreateTargetMachine creates a new TargetMachine. | ||
| func (t Target) CreateTargetMachine(Triple string, CPU string, Features string, | ||
| Level CodeGenOptLevel, Reloc RelocMode, | ||
| CodeModel CodeModel) (tm TargetMachine) { | ||
| cTriple := C.CString(Triple) | ||
| defer C.free(unsafe.Pointer(cTriple)) | ||
| cCPU := C.CString(CPU) | ||
| defer C.free(unsafe.Pointer(cCPU)) | ||
| cFeatures := C.CString(Features) | ||
| defer C.free(unsafe.Pointer(cFeatures)) | ||
| tm.C = C.LLVMCreateTargetMachine(t.C, cTriple, cCPU, cFeatures, | ||
| C.LLVMCodeGenOptLevel(Level), | ||
| C.LLVMRelocMode(Reloc), | ||
| C.LLVMCodeModel(CodeModel)) | ||
| return | ||
| } | ||
|
|
||
| // Triple returns the triple describing the machine (arch-vendor-os). | ||
| func (tm TargetMachine) Triple() string { | ||
| cstr := C.LLVMGetTargetMachineTriple(tm.C) | ||
| return C.GoString(cstr) | ||
| } | ||
|
|
||
| // TargetData returns the TargetData for the machine. | ||
| func (tm TargetMachine) TargetData() TargetData { | ||
| return TargetData{C.LLVMGetTargetMachineData(tm.C)} | ||
| } | ||
|
|
||
| func (tm TargetMachine) EmitToMemoryBuffer(m Module, ft CodeGenFileType) (MemoryBuffer, error) { | ||
| var errstr *C.char | ||
| var mb MemoryBuffer | ||
| fail := C.LLVMTargetMachineEmitToMemoryBuffer(tm.C, m.C, C.LLVMCodeGenFileType(ft), &errstr, &mb.C) | ||
| if fail != 0 { | ||
| err := errors.New(C.GoString(errstr)) | ||
| C.free(unsafe.Pointer(errstr)) | ||
| return MemoryBuffer{}, err | ||
| } | ||
| return mb, nil | ||
| } | ||
|
|
||
| func (tm TargetMachine) AddAnalysisPasses(pm PassManager) { | ||
| C.LLVMAddAnalysisPasses(tm.C, pm.C) | ||
| } | ||
|
|
||
| // Dispose releases resources related to the TargetMachine. | ||
| func (tm TargetMachine) Dispose() { | ||
| C.LLVMDisposeTargetMachine(tm.C) | ||
| } | ||
|
|
||
| func DefaultTargetTriple() (triple string) { | ||
| cTriple := C.LLVMGetDefaultTargetTriple() | ||
| defer C.free(unsafe.Pointer(cTriple)) | ||
| triple = C.GoString(cTriple) | ||
| return | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| //===- transforms_instrumentation.go - Bindings for instrumentation -------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the instrumentation component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "InstrumentationBindings.h" | ||
| #include <stdlib.h> | ||
| */ | ||
| import "C" | ||
| import "unsafe" | ||
|
|
||
| func (pm PassManager) AddAddressSanitizerFunctionPass() { | ||
| C.LLVMAddAddressSanitizerFunctionPass(pm.C) | ||
| } | ||
|
|
||
| func (pm PassManager) AddAddressSanitizerModulePass() { | ||
| C.LLVMAddAddressSanitizerModulePass(pm.C) | ||
| } | ||
|
|
||
| func (pm PassManager) AddThreadSanitizerPass() { | ||
| C.LLVMAddThreadSanitizerPass(pm.C) | ||
| } | ||
|
|
||
| func (pm PassManager) AddMemorySanitizerPass() { | ||
| C.LLVMAddMemorySanitizerPass(pm.C) | ||
| } | ||
|
|
||
| func (pm PassManager) AddDataFlowSanitizerPass(abilist string) { | ||
| cabilist := C.CString(abilist) | ||
| defer C.free(unsafe.Pointer(cabilist)) | ||
| C.LLVMAddDataFlowSanitizerPass(pm.C, cabilist) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| //===- transforms_ipo.go - Bindings for ipo -------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the ipo component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/Transforms/IPO.h" | ||
| */ | ||
| import "C" | ||
|
|
||
| // helpers | ||
| func boolToUnsigned(b bool) C.unsigned { | ||
| if b { | ||
| return 1 | ||
| } | ||
| return 0 | ||
| } | ||
|
|
||
| func (pm PassManager) AddArgumentPromotionPass() { C.LLVMAddArgumentPromotionPass(pm.C) } | ||
| func (pm PassManager) AddConstantMergePass() { C.LLVMAddConstantMergePass(pm.C) } | ||
| func (pm PassManager) AddDeadArgEliminationPass() { C.LLVMAddDeadArgEliminationPass(pm.C) } | ||
| func (pm PassManager) AddFunctionAttrsPass() { C.LLVMAddFunctionAttrsPass(pm.C) } | ||
| func (pm PassManager) AddFunctionInliningPass() { C.LLVMAddFunctionInliningPass(pm.C) } | ||
| func (pm PassManager) AddGlobalDCEPass() { C.LLVMAddGlobalDCEPass(pm.C) } | ||
| func (pm PassManager) AddGlobalOptimizerPass() { C.LLVMAddGlobalOptimizerPass(pm.C) } | ||
| func (pm PassManager) AddIPConstantPropagationPass() { C.LLVMAddIPConstantPropagationPass(pm.C) } | ||
| func (pm PassManager) AddPruneEHPass() { C.LLVMAddPruneEHPass(pm.C) } | ||
| func (pm PassManager) AddIPSCCPPass() { C.LLVMAddIPSCCPPass(pm.C) } | ||
| func (pm PassManager) AddInternalizePass(allButMain bool) { | ||
| C.LLVMAddInternalizePass(pm.C, boolToUnsigned(allButMain)) | ||
| } | ||
| func (pm PassManager) AddStripDeadPrototypesPass() { C.LLVMAddStripDeadPrototypesPass(pm.C) } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| //===- transforms_pmbuilder.go - Bindings for PassManagerBuilder ----------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the PassManagerBuilder class. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/Transforms/PassManagerBuilder.h" | ||
| */ | ||
| import "C" | ||
|
|
||
| type PassManagerBuilder struct { | ||
| C C.LLVMPassManagerBuilderRef | ||
| } | ||
|
|
||
| func NewPassManagerBuilder() (pmb PassManagerBuilder) { | ||
| pmb.C = C.LLVMPassManagerBuilderCreate() | ||
| return | ||
| } | ||
|
|
||
| func (pmb PassManagerBuilder) SetOptLevel(level int) { | ||
| C.LLVMPassManagerBuilderSetOptLevel(pmb.C, C.uint(level)) | ||
| } | ||
|
|
||
| func (pmb PassManagerBuilder) SetSizeLevel(level int) { | ||
| C.LLVMPassManagerBuilderSetSizeLevel(pmb.C, C.uint(level)) | ||
| } | ||
|
|
||
| func (pmb PassManagerBuilder) Populate(pm PassManager) { | ||
| C.LLVMPassManagerBuilderPopulateModulePassManager(pmb.C, pm.C) | ||
| } | ||
|
|
||
| func (pmb PassManagerBuilder) PopulateFunc(pm PassManager) { | ||
| C.LLVMPassManagerBuilderPopulateFunctionPassManager(pmb.C, pm.C) | ||
| } | ||
|
|
||
| func (pmb PassManagerBuilder) Dispose() { | ||
| C.LLVMPassManagerBuilderDispose(pmb.C) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| //===- transforms_scalar.go - Bindings for scalaropts ---------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines bindings for the scalaropts component. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| package llvm | ||
|
|
||
| /* | ||
| #include "llvm-c/Transforms/Scalar.h" | ||
| */ | ||
| import "C" | ||
|
|
||
| func (pm PassManager) AddAggressiveDCEPass() { C.LLVMAddAggressiveDCEPass(pm.C) } | ||
| func (pm PassManager) AddCFGSimplificationPass() { C.LLVMAddCFGSimplificationPass(pm.C) } | ||
| func (pm PassManager) AddDeadStoreEliminationPass() { C.LLVMAddDeadStoreEliminationPass(pm.C) } | ||
| func (pm PassManager) AddGVNPass() { C.LLVMAddGVNPass(pm.C) } | ||
| func (pm PassManager) AddIndVarSimplifyPass() { C.LLVMAddIndVarSimplifyPass(pm.C) } | ||
| func (pm PassManager) AddInstructionCombiningPass() { C.LLVMAddInstructionCombiningPass(pm.C) } | ||
| func (pm PassManager) AddJumpThreadingPass() { C.LLVMAddJumpThreadingPass(pm.C) } | ||
| func (pm PassManager) AddLICMPass() { C.LLVMAddLICMPass(pm.C) } | ||
| func (pm PassManager) AddLoopDeletionPass() { C.LLVMAddLoopDeletionPass(pm.C) } | ||
| func (pm PassManager) AddLoopRotatePass() { C.LLVMAddLoopRotatePass(pm.C) } | ||
| func (pm PassManager) AddLoopUnrollPass() { C.LLVMAddLoopUnrollPass(pm.C) } | ||
| func (pm PassManager) AddLoopUnswitchPass() { C.LLVMAddLoopUnswitchPass(pm.C) } | ||
| func (pm PassManager) AddMemCpyOptPass() { C.LLVMAddMemCpyOptPass(pm.C) } | ||
| func (pm PassManager) AddPromoteMemoryToRegisterPass() { C.LLVMAddPromoteMemoryToRegisterPass(pm.C) } | ||
| func (pm PassManager) AddReassociatePass() { C.LLVMAddReassociatePass(pm.C) } | ||
| func (pm PassManager) AddSCCPPass() { C.LLVMAddSCCPPass(pm.C) } | ||
| func (pm PassManager) AddScalarReplAggregatesPass() { C.LLVMAddScalarReplAggregatesPass(pm.C) } | ||
| func (pm PassManager) AddScalarReplAggregatesPassWithThreshold(threshold int) { | ||
| C.LLVMAddScalarReplAggregatesPassWithThreshold(pm.C, C.int(threshold)) | ||
| } | ||
| func (pm PassManager) AddSimplifyLibCallsPass() { C.LLVMAddSimplifyLibCallsPass(pm.C) } | ||
| func (pm PassManager) AddTailCallEliminationPass() { C.LLVMAddTailCallEliminationPass(pm.C) } | ||
| func (pm PassManager) AddConstantPropagationPass() { C.LLVMAddConstantPropagationPass(pm.C) } | ||
| func (pm PassManager) AddDemoteMemoryToRegisterPass() { C.LLVMAddDemoteMemoryToRegisterPass(pm.C) } | ||
| func (pm PassManager) AddVerifierPass() { C.LLVMAddVerifierPass(pm.C) } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package llvm | ||
|
|
||
| const Version = "3.6.0svn" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| ; RUN: cd %S/../../../bindings/go/llvm && \ | ||
| ; RUN: env CGO_CPPFLAGS="$(llvm-config --cppflags)" \ | ||
| ; RUN: CGO_CXXFLAGS=-std=c++11 \ | ||
| ; RUN: CGO_LDFLAGS="$(llvm-config --ldflags --libs --system-libs \ | ||
| ; RUN: $(../build.sh --print-components))" \ | ||
| ; RUN: %go test -tags byollvm . | ||
|
|
||
| ; REQUIRES: shell |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import distutils.spawn | ||
| import os | ||
| import pipes | ||
| import shlex | ||
|
|
||
| if not 'go' in config.root.llvm_bindings: | ||
| config.unsupported = True | ||
|
|
||
| # Resolve certain symlinks in the first word of compiler. | ||
| # | ||
| # This is a Go-specific hack. cgo and other Go tools check $CC and $CXX for the | ||
| # substring 'clang' to determine if the compiler is Clang. This won't work if | ||
| # $CC is cc and cc is a symlink pointing to clang, as it is on Darwin. | ||
| def fixup_compiler_path(compiler): | ||
| args = shlex.split(compiler) | ||
| path = distutils.spawn.find_executable(args[0]) | ||
|
|
||
| try: | ||
| if path.endswith('/cc') and os.readlink(path) == 'clang': | ||
| args[0] = path[:len(path)-2] + 'clang' | ||
| except OSError: | ||
| skip | ||
|
|
||
| try: | ||
| if path.endswith('/c++') and os.readlink(path) == 'clang++': | ||
| args[0] = path[:len(path)-3] + 'clang++' | ||
| except OSError: | ||
| skip | ||
|
|
||
| return ' '.join([pipes.quote(arg) for arg in args]) | ||
|
|
||
| config.environment['CC'] = fixup_compiler_path(config.host_cc) | ||
| config.environment['CXX'] = fixup_compiler_path(config.host_cxx) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| config.suffixes = ['.ml'] | ||
|
|
||
| if not 'ocaml' in config.root.llvm_bindings: | ||
| config.unsupported = True |