├── .github └── workflows │ └── test.yml ├── .gitignore ├── IRBindings.cpp ├── IRBindings.h ├── LICENSE.txt ├── README.markdown ├── SupportBindings.cpp ├── SupportBindings.h ├── analysis.go ├── backports.cpp ├── backports.h ├── bitreader.go ├── bitwriter.go ├── dibuilder.go ├── executionengine.go ├── executionengine_test.go ├── go.mod ├── ir.go ├── ir_test.go ├── irreader.go ├── linker.go ├── llvm_config_darwin_llvm14.go ├── llvm_config_darwin_llvm15.go ├── llvm_config_darwin_llvm16.go ├── llvm_config_darwin_llvm17.go ├── llvm_config_darwin_llvm18.go ├── llvm_config_darwin_llvm19.go ├── llvm_config_darwin_llvm20.go ├── llvm_config_linux_llvm14.go ├── llvm_config_linux_llvm15.go ├── llvm_config_linux_llvm16.go ├── llvm_config_linux_llvm17.go ├── llvm_config_linux_llvm18.go ├── llvm_config_linux_llvm19.go ├── llvm_config_linux_llvm20.go ├── llvm_dep.go ├── llvm_test.go ├── passes.go ├── passes_test.go ├── string.go ├── support.go ├── target.go └── version.go /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # Test whether we can link to LLVM installed from apt.llvm.org or Homebrew. 2 | --- 3 | 4 | name: Test 5 | 6 | on: [push, pull_request] 7 | 8 | jobs: 9 | test-macos: 10 | runs-on: macos-latest 11 | strategy: 12 | matrix: 13 | llvm: [14, 15, 16, 17, 18, 19, 20] 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | - name: Set up Go 18 | uses: actions/setup-go@v5 19 | with: 20 | go-version: '1.22' 21 | # Optional step when a LLVM version is very new. 22 | - name: Update Homebrew 23 | if: matrix.llvm == 20 24 | run: brew update 25 | - name: Install LLVM 26 | run: HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }} 27 | - name: Test LLVM ${{ matrix.llvm }} 28 | run: 29 | go test -v -tags=llvm${{ matrix.llvm }} 30 | - name: Test default LLVM 31 | if: matrix.llvm == 20 32 | run: 33 | go test -v 34 | test-linux: 35 | runs-on: ubuntu-22.04 36 | strategy: 37 | matrix: 38 | llvm: [14, 15, 16, 17, 18, 19, 20] 39 | steps: 40 | - name: Checkout 41 | uses: actions/checkout@v4 42 | - name: Set up Go 43 | uses: actions/setup-go@v5 44 | with: 45 | go-version: '1.22' 46 | - name: Install LLVM 47 | run: | 48 | echo 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${{ matrix.llvm }} main' | sudo tee /etc/apt/sources.list.d/llvm.list 49 | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - 50 | sudo apt-get update 51 | sudo apt-get install --no-install-recommends llvm-${{ matrix.llvm }}-dev 52 | - name: Test LLVM ${{ matrix.llvm }} 53 | run: 54 | go test -v -tags=llvm${{ matrix.llvm }} 55 | - name: Test default LLVM 56 | if: matrix.llvm == 20 57 | run: 58 | go test -v 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | llvm-*.src.tar.xz 2 | llvm-*/ 3 | -------------------------------------------------------------------------------- /IRBindings.cpp: -------------------------------------------------------------------------------- 1 | //===- IRBindings.cpp - Additional bindings for ir ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines additional C bindings for the ir component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "IRBindings.h" 14 | #include "llvm/IR/Attributes.h" 15 | #include "llvm/IR/DebugLoc.h" 16 | #include "llvm/IR/DebugInfoMetadata.h" 17 | #include "llvm/IR/Function.h" 18 | #include "llvm/IR/IRBuilder.h" 19 | #include "llvm/IR/LLVMContext.h" 20 | #include "llvm/IR/Module.h" 21 | 22 | using namespace llvm; 23 | 24 | LLVMMetadataRef LLVMConstantAsMetadata(LLVMValueRef C) { 25 | return wrap(ConstantAsMetadata::get(unwrap(C))); 26 | } 27 | 28 | LLVMMetadataRef LLVMMDString2(LLVMContextRef C, const char *Str, unsigned SLen) { 29 | return wrap(MDString::get(*unwrap(C), StringRef(Str, SLen))); 30 | } 31 | 32 | LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs, 33 | unsigned Count) { 34 | return wrap( 35 | MDNode::get(*unwrap(C), ArrayRef(unwrap(MDs), Count))); 36 | } 37 | 38 | void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name, 39 | LLVMMetadataRef Val) { 40 | NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name); 41 | if (!N) 42 | return; 43 | if (!Val) 44 | return; 45 | N->addOperand(unwrap(Val)); 46 | } 47 | 48 | void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) { 49 | MDNode *N = MD ? unwrap(MD) : nullptr; 50 | unwrap(Inst)->setMetadata(KindID, N); 51 | } 52 | 53 | void LLVMGoSetCurrentDebugLocation(LLVMBuilderRef Bref, unsigned Line, 54 | unsigned Col, LLVMMetadataRef Scope, 55 | LLVMMetadataRef InlinedAt) { 56 | if (!Scope) 57 | unwrap(Bref)->SetCurrentDebugLocation(DebugLoc()); 58 | else 59 | unwrap(Bref)->SetCurrentDebugLocation(DILocation::get( 60 | unwrap(Scope)->getContext(), Line, Col, unwrap(Scope), 61 | InlinedAt ? unwrap(InlinedAt) : nullptr)); 62 | } 63 | 64 | LLVMDebugLocMetadata LLVMGoGetCurrentDebugLocation(LLVMBuilderRef Bref) { 65 | const auto& Loc = unwrap(Bref)->getCurrentDebugLocation(); 66 | const auto* InlinedAt = Loc.getInlinedAt(); 67 | const LLVMDebugLocMetadata md{ 68 | Loc.getLine(), 69 | Loc.getCol(), 70 | wrap(Loc.getScope()), 71 | InlinedAt == nullptr ? nullptr : wrap(InlinedAt->getRawInlinedAt()), 72 | }; 73 | return md; 74 | } 75 | 76 | LLVMValueRef LLVMGoGetInlineAsm(LLVMTypeRef Ty, char *AsmString, 77 | size_t AsmStringSize, char *Constraints, 78 | size_t ConstraintsSize, LLVMBool HasSideEffects, 79 | LLVMBool IsAlignStack, 80 | LLVMInlineAsmDialect Dialect, LLVMBool CanThrow) 81 | { 82 | return LLVMGetInlineAsm(Ty, AsmString, 83 | AsmStringSize, Constraints, 84 | ConstraintsSize, HasSideEffects, 85 | IsAlignStack, 86 | Dialect, CanThrow); 87 | } 88 | -------------------------------------------------------------------------------- /IRBindings.h: -------------------------------------------------------------------------------- 1 | //===- IRBindings.h - Additional bindings for IR ----------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines additional C bindings for the IR component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H 14 | #define LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H 15 | 16 | #include "llvm-c/Core.h" 17 | #include "llvm-c/DebugInfo.h" 18 | #ifdef __cplusplus 19 | #include "llvm/IR/Metadata.h" 20 | #include "llvm/Support/CBindingWrapping.h" 21 | #endif 22 | 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | struct LLVMDebugLocMetadata{ 30 | unsigned Line; 31 | unsigned Col; 32 | LLVMMetadataRef Scope; 33 | LLVMMetadataRef InlinedAt; 34 | }; 35 | 36 | LLVMMetadataRef LLVMConstantAsMetadata(LLVMValueRef Val); 37 | 38 | LLVMMetadataRef LLVMMDString2(LLVMContextRef C, const char *Str, unsigned SLen); 39 | LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs, 40 | unsigned Count); 41 | 42 | void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name, 43 | LLVMMetadataRef Val); 44 | void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD); 45 | 46 | void LLVMGoSetCurrentDebugLocation(LLVMBuilderRef Bref, unsigned Line, 47 | unsigned Col, LLVMMetadataRef Scope, 48 | LLVMMetadataRef InlinedAt); 49 | 50 | struct LLVMDebugLocMetadata LLVMGoGetCurrentDebugLocation(LLVMBuilderRef Bref); 51 | 52 | LLVMValueRef LLVMGoGetInlineAsm(LLVMTypeRef Ty, char *AsmString, 53 | size_t AsmStringSize, char *Constraints, 54 | size_t ConstraintsSize, LLVMBool HasSideEffects, 55 | LLVMBool IsAlignStack, 56 | LLVMInlineAsmDialect Dialect, LLVMBool CanThrow); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: 3 | ============================================================================== 4 | 5 | Apache License 6 | Version 2.0, January 2004 7 | http://www.apache.org/licenses/ 8 | 9 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 10 | 11 | 1. Definitions. 12 | 13 | "License" shall mean the terms and conditions for use, reproduction, 14 | and distribution as defined by Sections 1 through 9 of this document. 15 | 16 | "Licensor" shall mean the copyright owner or entity authorized by 17 | the copyright owner that is granting the License. 18 | 19 | "Legal Entity" shall mean the union of the acting entity and all 20 | other entities that control, are controlled by, or are under common 21 | control with that entity. For the purposes of this definition, 22 | "control" means (i) the power, direct or indirect, to cause the 23 | direction or management of such entity, whether by contract or 24 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 25 | outstanding shares, or (iii) beneficial ownership of such entity. 26 | 27 | "You" (or "Your") shall mean an individual or Legal Entity 28 | exercising permissions granted by this License. 29 | 30 | "Source" form shall mean the preferred form for making modifications, 31 | including but not limited to software source code, documentation 32 | source, and configuration files. 33 | 34 | "Object" form shall mean any form resulting from mechanical 35 | transformation or translation of a Source form, including but 36 | not limited to compiled object code, generated documentation, 37 | and conversions to other media types. 38 | 39 | "Work" shall mean the work of authorship, whether in Source or 40 | Object form, made available under the License, as indicated by a 41 | copyright notice that is included in or attached to the work 42 | (an example is provided in the Appendix below). 43 | 44 | "Derivative Works" shall mean any work, whether in Source or Object 45 | form, that is based on (or derived from) the Work and for which the 46 | editorial revisions, annotations, elaborations, or other modifications 47 | represent, as a whole, an original work of authorship. For the purposes 48 | of this License, Derivative Works shall not include works that remain 49 | separable from, or merely link (or bind by name) to the interfaces of, 50 | the Work and Derivative Works thereof. 51 | 52 | "Contribution" shall mean any work of authorship, including 53 | the original version of the Work and any modifications or additions 54 | to that Work or Derivative Works thereof, that is intentionally 55 | submitted to Licensor for inclusion in the Work by the copyright owner 56 | or by an individual or Legal Entity authorized to submit on behalf of 57 | the copyright owner. For the purposes of this definition, "submitted" 58 | means any form of electronic, verbal, or written communication sent 59 | to the Licensor or its representatives, including but not limited to 60 | communication on electronic mailing lists, source code control systems, 61 | and issue tracking systems that are managed by, or on behalf of, the 62 | Licensor for the purpose of discussing and improving the Work, but 63 | excluding communication that is conspicuously marked or otherwise 64 | designated in writing by the copyright owner as "Not a Contribution." 65 | 66 | "Contributor" shall mean Licensor and any individual or Legal Entity 67 | on behalf of whom a Contribution has been received by Licensor and 68 | subsequently incorporated within the Work. 69 | 70 | 2. Grant of Copyright License. Subject to the terms and conditions of 71 | this License, each Contributor hereby grants to You a perpetual, 72 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 73 | copyright license to reproduce, prepare Derivative Works of, 74 | publicly display, publicly perform, sublicense, and distribute the 75 | Work and such Derivative Works in Source or Object form. 76 | 77 | 3. Grant of Patent License. Subject to the terms and conditions of 78 | this License, each Contributor hereby grants to You a perpetual, 79 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 80 | (except as stated in this section) patent license to make, have made, 81 | use, offer to sell, sell, import, and otherwise transfer the Work, 82 | where such license applies only to those patent claims licensable 83 | by such Contributor that are necessarily infringed by their 84 | Contribution(s) alone or by combination of their Contribution(s) 85 | with the Work to which such Contribution(s) was submitted. If You 86 | institute patent litigation against any entity (including a 87 | cross-claim or counterclaim in a lawsuit) alleging that the Work 88 | or a Contribution incorporated within the Work constitutes direct 89 | or contributory patent infringement, then any patent licenses 90 | granted to You under this License for that Work shall terminate 91 | as of the date such litigation is filed. 92 | 93 | 4. Redistribution. You may reproduce and distribute copies of the 94 | Work or Derivative Works thereof in any medium, with or without 95 | modifications, and in Source or Object form, provided that You 96 | meet the following conditions: 97 | 98 | (a) You must give any other recipients of the Work or 99 | Derivative Works a copy of this License; and 100 | 101 | (b) You must cause any modified files to carry prominent notices 102 | stating that You changed the files; and 103 | 104 | (c) You must retain, in the Source form of any Derivative Works 105 | that You distribute, all copyright, patent, trademark, and 106 | attribution notices from the Source form of the Work, 107 | excluding those notices that do not pertain to any part of 108 | the Derivative Works; and 109 | 110 | (d) If the Work includes a "NOTICE" text file as part of its 111 | distribution, then any Derivative Works that You distribute must 112 | include a readable copy of the attribution notices contained 113 | within such NOTICE file, excluding those notices that do not 114 | pertain to any part of the Derivative Works, in at least one 115 | of the following places: within a NOTICE text file distributed 116 | as part of the Derivative Works; within the Source form or 117 | documentation, if provided along with the Derivative Works; or, 118 | within a display generated by the Derivative Works, if and 119 | wherever such third-party notices normally appear. The contents 120 | of the NOTICE file are for informational purposes only and 121 | do not modify the License. You may add Your own attribution 122 | notices within Derivative Works that You distribute, alongside 123 | or as an addendum to the NOTICE text from the Work, provided 124 | that such additional attribution notices cannot be construed 125 | as modifying the License. 126 | 127 | You may add Your own copyright statement to Your modifications and 128 | may provide additional or different license terms and conditions 129 | for use, reproduction, or distribution of Your modifications, or 130 | for any such Derivative Works as a whole, provided Your use, 131 | reproduction, and distribution of the Work otherwise complies with 132 | the conditions stated in this License. 133 | 134 | 5. Submission of Contributions. Unless You explicitly state otherwise, 135 | any Contribution intentionally submitted for inclusion in the Work 136 | by You to the Licensor shall be under the terms and conditions of 137 | this License, without any additional terms or conditions. 138 | Notwithstanding the above, nothing herein shall supersede or modify 139 | the terms of any separate license agreement you may have executed 140 | with Licensor regarding such Contributions. 141 | 142 | 6. Trademarks. This License does not grant permission to use the trade 143 | names, trademarks, service marks, or product names of the Licensor, 144 | except as required for reasonable and customary use in describing the 145 | origin of the Work and reproducing the content of the NOTICE file. 146 | 147 | 7. Disclaimer of Warranty. Unless required by applicable law or 148 | agreed to in writing, Licensor provides the Work (and each 149 | Contributor provides its Contributions) on an "AS IS" BASIS, 150 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 151 | implied, including, without limitation, any warranties or conditions 152 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 153 | PARTICULAR PURPOSE. You are solely responsible for determining the 154 | appropriateness of using or redistributing the Work and assume any 155 | risks associated with Your exercise of permissions under this License. 156 | 157 | 8. Limitation of Liability. In no event and under no legal theory, 158 | whether in tort (including negligence), contract, or otherwise, 159 | unless required by applicable law (such as deliberate and grossly 160 | negligent acts) or agreed to in writing, shall any Contributor be 161 | liable to You for damages, including any direct, indirect, special, 162 | incidental, or consequential damages of any character arising as a 163 | result of this License or out of the use or inability to use the 164 | Work (including but not limited to damages for loss of goodwill, 165 | work stoppage, computer failure or malfunction, or any and all 166 | other commercial damages or losses), even if such Contributor 167 | has been advised of the possibility of such damages. 168 | 169 | 9. Accepting Warranty or Additional Liability. While redistributing 170 | the Work or Derivative Works thereof, You may choose to offer, 171 | and charge a fee for, acceptance of support, warranty, indemnity, 172 | or other liability obligations and/or rights consistent with this 173 | License. However, in accepting such obligations, You may act only 174 | on Your own behalf and on Your sole responsibility, not on behalf 175 | of any other Contributor, and only if You agree to indemnify, 176 | defend, and hold each Contributor harmless for any liability 177 | incurred by, or claims asserted against, such Contributor by reason 178 | of your accepting any such warranty or additional liability. 179 | 180 | END OF TERMS AND CONDITIONS 181 | 182 | APPENDIX: How to apply the Apache License to your work. 183 | 184 | To apply the Apache License to your work, attach the following 185 | boilerplate notice, with the fields enclosed by brackets "[]" 186 | replaced with your own identifying information. (Don't include 187 | the brackets!) The text should be enclosed in the appropriate 188 | comment syntax for the file format. We also recommend that a 189 | file or class name and description of purpose be included on the 190 | same "printed page" as the copyright notice for easier 191 | identification within third-party archives. 192 | 193 | Copyright [yyyy] [name of copyright owner] 194 | 195 | Licensed under the Apache License, Version 2.0 (the "License"); 196 | you may not use this file except in compliance with the License. 197 | You may obtain a copy of the License at 198 | 199 | http://www.apache.org/licenses/LICENSE-2.0 200 | 201 | Unless required by applicable law or agreed to in writing, software 202 | distributed under the License is distributed on an "AS IS" BASIS, 203 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 204 | See the License for the specific language governing permissions and 205 | limitations under the License. 206 | 207 | 208 | ---- LLVM Exceptions to the Apache 2.0 License ---- 209 | 210 | As an exception, if, as a result of your compiling your source code, portions 211 | of this Software are embedded into an Object form of such source code, you 212 | may redistribute such embedded portions in such Object form without complying 213 | with the conditions of Sections 4(a), 4(b) and 4(d) of the License. 214 | 215 | In addition, if you combine or link compiled forms of this Software with 216 | software that is licensed under the GPLv2 ("Combined Software") and if a 217 | court of competent jurisdiction determines that the patent provision (Section 218 | 3), the indemnity provision (Section 9) or other Section of the License 219 | conflicts with the conditions of the GPLv2, you may retroactively and 220 | prospectively choose to deem waived or otherwise exclude such Section(s) of 221 | the License, but only in their entirety and only with respect to the Combined 222 | Software. 223 | 224 | ============================================================================== 225 | Software from third parties included in the LLVM Project: 226 | ============================================================================== 227 | The LLVM Project contains third party software which is under different license 228 | terms. All such code will be identified clearly using at least one of two 229 | mechanisms: 230 | 1) It will be in a separate directory tree with its own `LICENSE.txt` or 231 | `LICENSE` file at the top containing the specific license and restrictions 232 | which apply to that software, or 233 | 2) It will contain specific license and restriction terms at the top of every 234 | file. 235 | 236 | ============================================================================== 237 | Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): 238 | ============================================================================== 239 | University of Illinois/NCSA 240 | Open Source License 241 | 242 | Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign. 243 | All rights reserved. 244 | 245 | Developed by: 246 | 247 | LLVM Team 248 | 249 | University of Illinois at Urbana-Champaign 250 | 251 | http://llvm.org 252 | 253 | Permission is hereby granted, free of charge, to any person obtaining a copy of 254 | this software and associated documentation files (the "Software"), to deal with 255 | the Software without restriction, including without limitation the rights to 256 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 257 | of the Software, and to permit persons to whom the Software is furnished to do 258 | so, subject to the following conditions: 259 | 260 | * Redistributions of source code must retain the above copyright notice, 261 | this list of conditions and the following disclaimers. 262 | 263 | * Redistributions in binary form must reproduce the above copyright notice, 264 | this list of conditions and the following disclaimers in the 265 | documentation and/or other materials provided with the distribution. 266 | 267 | * Neither the names of the LLVM Team, University of Illinois at 268 | Urbana-Champaign, nor the names of its contributors may be used to 269 | endorse or promote products derived from this Software without specific 270 | prior written permission. 271 | 272 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 273 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 274 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 275 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 276 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 277 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 278 | SOFTWARE. 279 | 280 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Go bindings to system LLVM 2 | 3 | This library provides bindings to a system-installed LLVM. 4 | 5 | Currently supported: 6 | 7 | * LLVM 20, 19, 18, 17, 16, 15 and 14 from [apt.llvm.org](http://apt.llvm.org/) on Debian/Ubuntu. 8 | * LLVM 20, 19, 18, 17, 16, 15 and 14 from Homebrew on macOS. 9 | * Any of the above versions with a manually built LLVM through the `byollvm` build tag. You need to set up `CFLAGS`/`LDFLAGS` etc yourself in this case. 10 | 11 | You can select the LLVM version using a build tag, for example `-tags=llvm17` 12 | to use LLVM 17. 13 | 14 | ## Usage 15 | 16 | If you have a supported LLVM installation, you should be able to do a simple `go get`: 17 | 18 | go get tinygo.org/x/go-llvm 19 | 20 | You can use build tags to select a LLVM version. For example, use `-tags=llvm15` to select LLVM 15. Setting a build tag for a LLVM version that is not supported will be ignored. 21 | 22 | ## License 23 | 24 | These LLVM bindings for Go originally come from LLVM, but they have since been [removed](https://discourse.llvm.org/t/rfc-remove-the-go-bindings/65725). Still, they remain under the same license as they were originally, which is the [Apache License 2.0 (with LLVM exceptions)](http://releases.llvm.org/9.0.0/LICENSE.TXT). Check upstream LLVM for detailed copyright information. 25 | 26 | This README, the backports\* files, and the Makefile are separate from LLVM but are licensed under the same license. 27 | -------------------------------------------------------------------------------- /SupportBindings.cpp: -------------------------------------------------------------------------------- 1 | //===- SupportBindings.cpp - Additional bindings for support --------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines additional C bindings for the support component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "SupportBindings.h" 14 | #include "llvm/Support/DynamicLibrary.h" 15 | #include 16 | #include 17 | 18 | void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg) { 19 | std::string ErrMsgStr; 20 | if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename, &ErrMsgStr)) { 21 | *ErrMsg = static_cast(malloc(ErrMsgStr.size() + 1)); 22 | memcpy(static_cast(*ErrMsg), 23 | static_cast(ErrMsgStr.c_str()), ErrMsgStr.size() + 1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SupportBindings.h: -------------------------------------------------------------------------------- 1 | //===- SupportBindings.h - Additional bindings for Support ------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines additional C bindings for the Support component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef LLVM_BINDINGS_GO_LLVM_SUPPORTBINDINGS_H 14 | #define LLVM_BINDINGS_GO_LLVM_SUPPORTBINDINGS_H 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | // This function duplicates the LLVMLoadLibraryPermanently function in the 21 | // stable C API and adds an extra ErrMsg parameter to retrieve the error 22 | // message. 23 | void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /analysis.go: -------------------------------------------------------------------------------- 1 | //===- analysis.go - Bindings for analysis --------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the analysis component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/Analysis.h" // If you are getting an error here you need to build or install LLVM, see https://tinygo.org/docs/guides/build/ 17 | #include "llvm-c/Core.h" 18 | #include 19 | */ 20 | import "C" 21 | import "errors" 22 | 23 | type VerifierFailureAction C.LLVMVerifierFailureAction 24 | 25 | const ( 26 | // verifier will print to stderr and abort() 27 | AbortProcessAction VerifierFailureAction = C.LLVMAbortProcessAction 28 | // verifier will print to stderr and return 1 29 | PrintMessageAction VerifierFailureAction = C.LLVMPrintMessageAction 30 | // verifier will just return 1 31 | ReturnStatusAction VerifierFailureAction = C.LLVMReturnStatusAction 32 | ) 33 | 34 | // Verifies that a module is valid, taking the specified action if not. 35 | // Optionally returns a human-readable description of any invalid constructs. 36 | func VerifyModule(m Module, a VerifierFailureAction) error { 37 | var cmsg *C.char 38 | broken := C.LLVMVerifyModule(m.C, C.LLVMVerifierFailureAction(a), &cmsg) 39 | 40 | // C++'s verifyModule means isModuleBroken, so it returns false if 41 | // there are no errors 42 | if broken != 0 { 43 | err := errors.New(C.GoString(cmsg)) 44 | C.LLVMDisposeMessage(cmsg) 45 | return err 46 | } 47 | return nil 48 | } 49 | 50 | var verifyFunctionError = errors.New("Function is broken") 51 | 52 | // Verifies that a single function is valid, taking the specified action. 53 | // Useful for debugging. 54 | func VerifyFunction(f Value, a VerifierFailureAction) error { 55 | broken := C.LLVMVerifyFunction(f.C, C.LLVMVerifierFailureAction(a)) 56 | 57 | // C++'s verifyFunction means isFunctionBroken, so it returns false if 58 | // there are no errors 59 | if broken != 0 { 60 | return verifyFunctionError 61 | } 62 | return nil 63 | } 64 | 65 | // Open up a ghostview window that displays the CFG of the current function. 66 | // Useful for debugging. 67 | func ViewFunctionCFG(f Value) { C.LLVMViewFunctionCFG(f.C) } 68 | func ViewFunctionCFGOnly(f Value) { C.LLVMViewFunctionCFGOnly(f.C) } 69 | -------------------------------------------------------------------------------- /backports.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "backports.h" 3 | #include "llvm/IR/Instructions.h" 4 | #if LLVM_VERSION_MAJOR >= 16 5 | #include "llvm/IR/PassManager.h" 6 | #include "llvm/Analysis/LoopAnalysisManager.h" 7 | #include "llvm/Analysis/CGSCCPassManager.h" 8 | #include "llvm/Passes/PassBuilder.h" 9 | #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" 10 | #else 11 | #include "llvm/IR/LegacyPassManager.h" 12 | #include "llvm/Transforms/IPO/PassManagerBuilder.h" 13 | #endif 14 | #include "llvm/IR/Module.h" 15 | #include "llvm/Pass.h" 16 | #include "llvm/Support/MemoryBuffer.h" 17 | #include "llvm/Transforms/IPO.h" 18 | #include "llvm-c/DebugInfo.h" 19 | 20 | void LLVMGlobalObjectAddMetadata(LLVMValueRef Global, unsigned KindID, LLVMMetadataRef MD) { 21 | llvm::MDNode *N = MD ? llvm::unwrap(MD) : nullptr; 22 | llvm::GlobalObject *O = llvm::unwrap(Global); 23 | O->addMetadata(KindID, *N); 24 | } 25 | 26 | // See https://reviews.llvm.org/D119431 27 | LLVMMemoryBufferRef LLVMGoWriteThinLTOBitcodeToMemoryBuffer(LLVMModuleRef M) { 28 | std::string Data; 29 | llvm::raw_string_ostream OS(Data); 30 | #if LLVM_VERSION_MAJOR >= 16 31 | llvm::LoopAnalysisManager LAM; 32 | llvm::FunctionAnalysisManager FAM; 33 | llvm::CGSCCAnalysisManager CGAM; 34 | llvm::ModuleAnalysisManager MAM; 35 | llvm::PassBuilder PB; 36 | PB.registerModuleAnalyses(MAM); 37 | PB.registerCGSCCAnalyses(CGAM); 38 | PB.registerFunctionAnalyses(FAM); 39 | PB.registerLoopAnalyses(LAM); 40 | PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 41 | llvm::ModulePassManager MPM; 42 | MPM.addPass(llvm::ThinLTOBitcodeWriterPass(OS, nullptr)); 43 | MPM.run(*llvm::unwrap(M), MAM); 44 | #else 45 | llvm::legacy::PassManager PM; 46 | PM.add(createWriteThinLTOBitcodePass(OS)); 47 | PM.run(*llvm::unwrap(M)); 48 | #endif 49 | return llvm::wrap(llvm::MemoryBuffer::getMemBufferCopy(OS.str()).release()); 50 | } 51 | 52 | void LLVMGoDIBuilderInsertDbgValueRecordAtEnd( 53 | LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, 54 | LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block) { 55 | #if LLVM_VERSION_MAJOR >= 19 56 | // Note: this returns a LLVMDbgRecordRef. Previously, InsertValueAtEnd would 57 | // return a Value. But since the type changed, and I'd like to keep the API 58 | // consistent across LLVM versions, I decided to drop the return value. 59 | LLVMDIBuilderInsertDbgValueRecordAtEnd(Builder, Val, VarInfo, Expr, DebugLoc, Block); 60 | #else 61 | // Old llvm.dbg.* API. 62 | LLVMDIBuilderInsertDbgValueAtEnd(Builder, Val, VarInfo, Expr, DebugLoc, Block); 63 | #endif 64 | } 65 | -------------------------------------------------------------------------------- /backports.h: -------------------------------------------------------------------------------- 1 | 2 | #include "llvm-c/DebugInfo.h" 3 | #include "llvm-c/Types.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | void LLVMGlobalObjectAddMetadata(LLVMValueRef objValue, unsigned KindID, LLVMMetadataRef md); 10 | 11 | LLVMMemoryBufferRef LLVMGoWriteThinLTOBitcodeToMemoryBuffer(LLVMModuleRef M); 12 | 13 | void LLVMGoDIBuilderInsertDbgValueRecordAtEnd( 14 | LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, 15 | LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif /* defined(__cplusplus) */ 20 | -------------------------------------------------------------------------------- /bitreader.go: -------------------------------------------------------------------------------- 1 | //===- bitreader.go - Bindings for bitreader ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the bitreader component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/BitReader.h" 17 | #include "llvm-c/Core.h" 18 | #include 19 | */ 20 | import "C" 21 | 22 | import ( 23 | "errors" 24 | "unsafe" 25 | ) 26 | 27 | // ParseBitcodeFile parses the LLVM IR (bitcode) in the file with the specified 28 | // name, and returns a new LLVM module. 29 | func (c Context) ParseBitcodeFile(name string) (Module, error) { 30 | var buf C.LLVMMemoryBufferRef 31 | var errmsg *C.char 32 | var cfilename *C.char = C.CString(name) 33 | defer C.free(unsafe.Pointer(cfilename)) 34 | result := C.LLVMCreateMemoryBufferWithContentsOfFile(cfilename, &buf, &errmsg) 35 | if result != 0 { 36 | err := errors.New(C.GoString(errmsg)) 37 | C.free(unsafe.Pointer(errmsg)) 38 | return Module{}, err 39 | } 40 | defer C.LLVMDisposeMemoryBuffer(buf) 41 | 42 | var m Module 43 | if C.LLVMParseBitcodeInContext2(c.C, buf, &m.C) == 0 { 44 | return m, nil 45 | } 46 | 47 | err := errors.New(C.GoString(errmsg)) 48 | C.free(unsafe.Pointer(errmsg)) 49 | return Module{}, err 50 | } 51 | -------------------------------------------------------------------------------- /bitwriter.go: -------------------------------------------------------------------------------- 1 | //===- bitwriter.go - Bindings for bitwriter ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the bitwriter component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/BitWriter.h" 17 | #include "backports.h" 18 | #include 19 | */ 20 | import "C" 21 | import "os" 22 | import "errors" 23 | 24 | var writeBitcodeToFileErr = errors.New("Failed to write bitcode to file") 25 | 26 | func WriteBitcodeToFile(m Module, file *os.File) error { 27 | fail := C.LLVMWriteBitcodeToFD(m.C, C.int(file.Fd()), C.int(0), C.int(0)) 28 | if fail != 0 { 29 | return writeBitcodeToFileErr 30 | } 31 | return nil 32 | } 33 | 34 | func WriteBitcodeToMemoryBuffer(m Module) MemoryBuffer { 35 | mb := C.LLVMWriteBitcodeToMemoryBuffer(m.C) 36 | return MemoryBuffer{mb} 37 | } 38 | 39 | func WriteThinLTOBitcodeToMemoryBuffer(m Module) MemoryBuffer { 40 | mb := C.LLVMGoWriteThinLTOBitcodeToMemoryBuffer(m.C) 41 | return MemoryBuffer{mb} 42 | } 43 | 44 | // TODO(nsf): Figure out way how to make it work with io.Writer 45 | -------------------------------------------------------------------------------- /dibuilder.go: -------------------------------------------------------------------------------- 1 | //===- dibuilder.go - Bindings for DIBuilder ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the DIBuilder class. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "IRBindings.h" 17 | #include "backports.h" 18 | #include 19 | */ 20 | import "C" 21 | 22 | import ( 23 | "debug/dwarf" 24 | "unsafe" 25 | ) 26 | 27 | type DwarfTag uint32 28 | 29 | const ( 30 | DW_TAG_lexical_block DwarfTag = 0x0b 31 | DW_TAG_compile_unit DwarfTag = 0x11 32 | DW_TAG_variable DwarfTag = 0x34 33 | DW_TAG_base_type DwarfTag = 0x24 34 | DW_TAG_pointer_type DwarfTag = 0x0F 35 | DW_TAG_structure_type DwarfTag = 0x13 36 | DW_TAG_subroutine_type DwarfTag = 0x15 37 | DW_TAG_file_type DwarfTag = 0x29 38 | DW_TAG_subprogram DwarfTag = 0x2E 39 | DW_TAG_auto_variable DwarfTag = 0x100 40 | DW_TAG_arg_variable DwarfTag = 0x101 41 | ) 42 | 43 | const ( 44 | FlagPrivate = 1 << iota 45 | FlagProtected 46 | FlagFwdDecl 47 | FlagAppleBlock 48 | FlagReserved 49 | FlagVirtual 50 | FlagArtificial 51 | FlagExplicit 52 | FlagPrototyped 53 | FlagObjcClassComplete 54 | FlagObjectPointer 55 | FlagVector 56 | FlagStaticMember 57 | FlagIndirectVariable 58 | ) 59 | 60 | type DwarfLang uint32 61 | 62 | const ( 63 | // http://dwarfstd.org/ShowIssue.php?issue=101014.1&type=open 64 | DW_LANG_Go DwarfLang = 0x0016 65 | ) 66 | 67 | type DwarfTypeEncoding uint32 68 | 69 | const ( 70 | DW_ATE_address DwarfTypeEncoding = 0x01 71 | DW_ATE_boolean DwarfTypeEncoding = 0x02 72 | DW_ATE_complex_float DwarfTypeEncoding = 0x03 73 | DW_ATE_float DwarfTypeEncoding = 0x04 74 | DW_ATE_signed DwarfTypeEncoding = 0x05 75 | DW_ATE_signed_char DwarfTypeEncoding = 0x06 76 | DW_ATE_unsigned DwarfTypeEncoding = 0x07 77 | DW_ATE_unsigned_char DwarfTypeEncoding = 0x08 78 | DW_ATE_imaginary_float DwarfTypeEncoding = 0x09 79 | DW_ATE_packed_decimal DwarfTypeEncoding = 0x0a 80 | DW_ATE_numeric_string DwarfTypeEncoding = 0x0b 81 | DW_ATE_edited DwarfTypeEncoding = 0x0c 82 | DW_ATE_signed_fixed DwarfTypeEncoding = 0x0d 83 | DW_ATE_unsigned_fixed DwarfTypeEncoding = 0x0e 84 | DW_ATE_decimal_float DwarfTypeEncoding = 0x0f 85 | DW_ATE_UTF DwarfTypeEncoding = 0x10 86 | DW_ATE_lo_user DwarfTypeEncoding = 0x80 87 | DW_ATE_hi_user DwarfTypeEncoding = 0xff 88 | ) 89 | 90 | // DIBuilder is a wrapper for the LLVM DIBuilder class. 91 | type DIBuilder struct { 92 | ref C.LLVMDIBuilderRef 93 | m Module 94 | } 95 | 96 | // NewDIBuilder creates a new DIBuilder, associated with the given module. 97 | func NewDIBuilder(m Module) *DIBuilder { 98 | d := C.LLVMCreateDIBuilder(m.C) 99 | return &DIBuilder{ref: d, m: m} 100 | } 101 | 102 | // Destroy destroys the DIBuilder. 103 | func (d *DIBuilder) Destroy() { 104 | C.LLVMDisposeDIBuilder(d.ref) 105 | } 106 | 107 | // FInalize finalizes the debug information generated by the DIBuilder. 108 | func (d *DIBuilder) Finalize() { 109 | C.LLVMDIBuilderFinalize(d.ref) 110 | } 111 | 112 | // DICompileUnit holds the values for creating compile unit debug metadata. 113 | type DICompileUnit struct { 114 | Language DwarfLang 115 | File string 116 | Dir string 117 | Producer string 118 | Optimized bool 119 | Flags string 120 | RuntimeVersion int 121 | SysRoot string 122 | SDK string 123 | } 124 | 125 | // CreateCompileUnit creates compile unit debug metadata. 126 | func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Metadata { 127 | file := C.CString(cu.File) 128 | defer C.free(unsafe.Pointer(file)) 129 | dir := C.CString(cu.Dir) 130 | defer C.free(unsafe.Pointer(dir)) 131 | producer := C.CString(cu.Producer) 132 | defer C.free(unsafe.Pointer(producer)) 133 | flags := C.CString(cu.Flags) 134 | defer C.free(unsafe.Pointer(flags)) 135 | sysroot := C.CString(cu.SysRoot) 136 | defer C.free(unsafe.Pointer(sysroot)) 137 | sdk := C.CString(cu.SDK) 138 | defer C.free(unsafe.Pointer(sdk)) 139 | result := C.LLVMDIBuilderCreateCompileUnit( 140 | d.ref, 141 | C.LLVMDWARFSourceLanguage(cu.Language), 142 | C.LLVMDIBuilderCreateFile(d.ref, file, C.size_t(len(cu.File)), dir, C.size_t(len(cu.Dir))), 143 | producer, C.size_t(len(cu.Producer)), 144 | C.LLVMBool(boolToCInt(cu.Optimized)), 145 | flags, C.size_t(len(cu.Flags)), 146 | C.unsigned(cu.RuntimeVersion), 147 | /*SplitName=*/ nil, 0, 148 | C.LLVMDWARFEmissionFull, 149 | /*DWOId=*/ 0, 150 | /*SplitDebugInlining*/ C.LLVMBool(boolToCInt(true)), 151 | /*DebugInfoForProfiling*/ C.LLVMBool(boolToCInt(false)), 152 | sysroot, C.size_t(len(cu.SysRoot)), 153 | sdk, C.size_t(len(cu.SDK)), 154 | ) 155 | return Metadata{C: result} 156 | } 157 | 158 | // CreateFile creates file debug metadata. 159 | func (d *DIBuilder) CreateFile(filename, dir string) Metadata { 160 | cfilename := C.CString(filename) 161 | defer C.free(unsafe.Pointer(cfilename)) 162 | cdir := C.CString(dir) 163 | defer C.free(unsafe.Pointer(cdir)) 164 | result := C.LLVMDIBuilderCreateFile(d.ref, 165 | cfilename, C.size_t(len(filename)), 166 | cdir, C.size_t(len(dir))) 167 | return Metadata{C: result} 168 | } 169 | 170 | // DILexicalBlock holds the values for creating lexical block debug metadata. 171 | type DILexicalBlock struct { 172 | File Metadata 173 | Line int 174 | Column int 175 | } 176 | 177 | // CreateLexicalBlock creates lexical block debug metadata. 178 | func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata { 179 | result := C.LLVMDIBuilderCreateLexicalBlock( 180 | d.ref, 181 | diScope.C, 182 | b.File.C, 183 | C.unsigned(b.Line), 184 | C.unsigned(b.Column), 185 | ) 186 | return Metadata{C: result} 187 | } 188 | 189 | func (d *DIBuilder) CreateLexicalBlockFile(diScope Metadata, diFile Metadata, discriminator int) Metadata { 190 | result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C, 191 | C.unsigned(discriminator)) 192 | return Metadata{C: result} 193 | } 194 | 195 | // DIFunction holds the values for creating function debug metadata. 196 | type DIFunction struct { 197 | Name string 198 | LinkageName string 199 | File Metadata 200 | Line int 201 | Type Metadata 202 | LocalToUnit bool 203 | IsDefinition bool 204 | ScopeLine int 205 | Flags int 206 | Optimized bool 207 | } 208 | 209 | // CreateFunction creates function debug metadata. 210 | func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata { 211 | name := C.CString(f.Name) 212 | defer C.free(unsafe.Pointer(name)) 213 | linkageName := C.CString(f.LinkageName) 214 | defer C.free(unsafe.Pointer(linkageName)) 215 | result := C.LLVMDIBuilderCreateFunction( 216 | d.ref, 217 | diScope.C, 218 | name, C.size_t(len(f.Name)), 219 | linkageName, C.size_t(len(f.LinkageName)), 220 | f.File.C, 221 | C.unsigned(f.Line), 222 | f.Type.C, 223 | C.LLVMBool(boolToCInt(f.LocalToUnit)), 224 | C.LLVMBool(boolToCInt(f.IsDefinition)), 225 | C.unsigned(f.ScopeLine), 226 | C.LLVMDIFlags(f.Flags), 227 | C.LLVMBool(boolToCInt(f.Optimized)), 228 | ) 229 | return Metadata{C: result} 230 | } 231 | 232 | // DIGlobalVariableExpression holds the values for creating global variable 233 | // debug metadata. 234 | type DIGlobalVariableExpression struct { 235 | Name string // Name of the variable. 236 | LinkageName string // Mangled name of the variable 237 | File Metadata // File where this variable is defined. 238 | Line int // Line number. 239 | Type Metadata // Variable Type. 240 | LocalToUnit bool // Flag indicating whether this variable is externally visible or not. 241 | Expr Metadata // The location of the global relative to the attached GlobalVariable. 242 | Decl Metadata // Reference to the corresponding declaration. 243 | AlignInBits uint32 // Variable alignment(or 0 if no alignment attr was specified). 244 | } 245 | 246 | // CreateGlobalVariableExpression creates a new descriptor for the specified 247 | // global variable. 248 | func (d *DIBuilder) CreateGlobalVariableExpression(diScope Metadata, g DIGlobalVariableExpression) Metadata { 249 | name := C.CString(g.Name) 250 | defer C.free(unsafe.Pointer(name)) 251 | linkageName := C.CString(g.LinkageName) 252 | defer C.free(unsafe.Pointer(linkageName)) 253 | result := C.LLVMDIBuilderCreateGlobalVariableExpression( 254 | d.ref, // Builder 255 | diScope.C, // Scope 256 | name, C.size_t(len(g.Name)), // Name, NameLen 257 | linkageName, C.size_t(len(g.LinkageName)), // Linkage, LinkLen 258 | g.File.C, // File 259 | C.unsigned(g.Line), // LineNo 260 | g.Type.C, // Ty 261 | C.LLVMBool(boolToCInt(g.LocalToUnit)), // LocalToUnit 262 | g.Expr.C, // Expr 263 | g.Decl.C, // Decl 264 | C.uint32_t(g.AlignInBits), // AlignInBits 265 | ) 266 | return Metadata{C: result} 267 | } 268 | 269 | // DIAutoVariable holds the values for creating auto variable debug metadata. 270 | type DIAutoVariable struct { 271 | Name string 272 | File Metadata 273 | Line int 274 | Type Metadata 275 | AlwaysPreserve bool 276 | Flags int 277 | AlignInBits uint32 278 | } 279 | 280 | // CreateAutoVariable creates local variable debug metadata. 281 | func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata { 282 | name := C.CString(v.Name) 283 | defer C.free(unsafe.Pointer(name)) 284 | result := C.LLVMDIBuilderCreateAutoVariable( 285 | d.ref, 286 | scope.C, 287 | name, C.size_t(len(v.Name)), 288 | v.File.C, 289 | C.unsigned(v.Line), 290 | v.Type.C, 291 | C.LLVMBool(boolToCInt(v.AlwaysPreserve)), 292 | C.LLVMDIFlags(v.Flags), 293 | C.uint32_t(v.AlignInBits), 294 | ) 295 | return Metadata{C: result} 296 | } 297 | 298 | // DIParameterVariable holds the values for creating parameter variable debug metadata. 299 | type DIParameterVariable struct { 300 | Name string 301 | File Metadata 302 | Line int 303 | Type Metadata 304 | AlwaysPreserve bool 305 | Flags int 306 | 307 | // ArgNo is the 1-based index of the argument in the function's 308 | // parameter list. 309 | ArgNo int 310 | } 311 | 312 | // CreateParameterVariable creates parameter variable debug metadata. 313 | func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata { 314 | name := C.CString(v.Name) 315 | defer C.free(unsafe.Pointer(name)) 316 | result := C.LLVMDIBuilderCreateParameterVariable( 317 | d.ref, 318 | scope.C, 319 | name, C.size_t(len(v.Name)), 320 | C.unsigned(v.ArgNo), 321 | v.File.C, 322 | C.unsigned(v.Line), 323 | v.Type.C, 324 | C.LLVMBool(boolToCInt(v.AlwaysPreserve)), 325 | C.LLVMDIFlags(v.Flags), 326 | ) 327 | return Metadata{C: result} 328 | } 329 | 330 | // DIBasicType holds the values for creating basic type debug metadata. 331 | type DIBasicType struct { 332 | Name string 333 | SizeInBits uint64 334 | Encoding DwarfTypeEncoding 335 | } 336 | 337 | // CreateBasicType creates basic type debug metadata. 338 | func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata { 339 | name := C.CString(t.Name) 340 | defer C.free(unsafe.Pointer(name)) 341 | result := C.LLVMDIBuilderCreateBasicType( 342 | d.ref, 343 | name, 344 | C.size_t(len(t.Name)), 345 | C.uint64_t(t.SizeInBits), 346 | C.LLVMDWARFTypeEncoding(t.Encoding), 347 | C.LLVMDIFlags(0), 348 | ) 349 | return Metadata{C: result} 350 | } 351 | 352 | // DIPointerType holds the values for creating pointer type debug metadata. 353 | type DIPointerType struct { 354 | Pointee Metadata 355 | SizeInBits uint64 356 | AlignInBits uint32 // optional 357 | AddressSpace uint32 358 | Name string // optional 359 | } 360 | 361 | // CreatePointerType creates a type that represents a pointer to another type. 362 | func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata { 363 | name := C.CString(t.Name) 364 | defer C.free(unsafe.Pointer(name)) 365 | result := C.LLVMDIBuilderCreatePointerType( 366 | d.ref, 367 | t.Pointee.C, 368 | C.uint64_t(t.SizeInBits), 369 | C.uint32_t(t.AlignInBits), 370 | C.unsigned(t.AddressSpace), 371 | name, 372 | C.size_t(len(t.Name)), 373 | ) 374 | return Metadata{C: result} 375 | } 376 | 377 | // DISubroutineType holds the values for creating subroutine type debug metadata. 378 | type DISubroutineType struct { 379 | // File is the file in which the subroutine type is defined. 380 | File Metadata 381 | 382 | // Parameters contains the subroutine parameter types, 383 | // including the return type at the 0th index. 384 | Parameters []Metadata 385 | 386 | Flags int 387 | } 388 | 389 | // CreateSubroutineType creates subroutine type debug metadata. 390 | func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata { 391 | params, length := llvmMetadataRefs(t.Parameters) 392 | result := C.LLVMDIBuilderCreateSubroutineType( 393 | d.ref, 394 | t.File.C, 395 | params, 396 | length, 397 | C.LLVMDIFlags(t.Flags), 398 | ) 399 | return Metadata{C: result} 400 | } 401 | 402 | // DIStructType holds the values for creating struct type debug metadata. 403 | type DIStructType struct { 404 | Name string 405 | File Metadata 406 | Line int 407 | SizeInBits uint64 408 | AlignInBits uint32 409 | Flags int 410 | DerivedFrom Metadata 411 | Elements []Metadata 412 | VTableHolder Metadata // optional 413 | UniqueID string 414 | } 415 | 416 | // CreateStructType creates struct type debug metadata. 417 | func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata { 418 | elements, length := llvmMetadataRefs(t.Elements) 419 | name := C.CString(t.Name) 420 | uniqueID := C.CString(t.UniqueID) 421 | defer C.free(unsafe.Pointer(name)) 422 | defer C.free(unsafe.Pointer(uniqueID)) 423 | result := C.LLVMDIBuilderCreateStructType( 424 | d.ref, 425 | scope.C, 426 | name, 427 | C.size_t(len(t.Name)), 428 | t.File.C, 429 | C.unsigned(t.Line), 430 | C.uint64_t(t.SizeInBits), 431 | C.uint32_t(t.AlignInBits), 432 | C.LLVMDIFlags(t.Flags), 433 | t.DerivedFrom.C, 434 | elements, 435 | length, 436 | C.unsigned(0), // Optional Objective-C runtime version. 437 | t.VTableHolder.C, 438 | uniqueID, 439 | C.size_t(len(t.UniqueID)), 440 | ) 441 | return Metadata{C: result} 442 | } 443 | 444 | // DIReplaceableCompositeType holds the values for creating replaceable 445 | // composite type debug metadata. 446 | type DIReplaceableCompositeType struct { 447 | Tag dwarf.Tag 448 | Name string 449 | File Metadata 450 | Line int 451 | RuntimeLang int 452 | SizeInBits uint64 453 | AlignInBits uint32 454 | Flags int 455 | UniqueID string 456 | } 457 | 458 | // CreateReplaceableCompositeType creates replaceable composite type debug metadata. 459 | func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata { 460 | name := C.CString(t.Name) 461 | uniqueID := C.CString(t.UniqueID) 462 | defer C.free(unsafe.Pointer(name)) 463 | defer C.free(unsafe.Pointer(uniqueID)) 464 | result := C.LLVMDIBuilderCreateReplaceableCompositeType( 465 | d.ref, 466 | C.unsigned(t.Tag), 467 | name, 468 | C.size_t(len(t.Name)), 469 | scope.C, 470 | t.File.C, 471 | C.unsigned(t.Line), 472 | C.unsigned(t.RuntimeLang), 473 | C.uint64_t(t.SizeInBits), 474 | C.uint32_t(t.AlignInBits), 475 | C.LLVMDIFlags(t.Flags), 476 | uniqueID, 477 | C.size_t(len(t.UniqueID)), 478 | ) 479 | return Metadata{C: result} 480 | } 481 | 482 | // DIMemberType holds the values for creating member type debug metadata. 483 | type DIMemberType struct { 484 | Name string 485 | File Metadata 486 | Line int 487 | SizeInBits uint64 488 | AlignInBits uint32 489 | OffsetInBits uint64 490 | Flags int 491 | Type Metadata 492 | } 493 | 494 | // CreateMemberType creates struct type debug metadata. 495 | func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata { 496 | name := C.CString(t.Name) 497 | defer C.free(unsafe.Pointer(name)) 498 | result := C.LLVMDIBuilderCreateMemberType( 499 | d.ref, 500 | scope.C, 501 | name, 502 | C.size_t(len(t.Name)), 503 | t.File.C, 504 | C.unsigned(t.Line), 505 | C.uint64_t(t.SizeInBits), 506 | C.uint32_t(t.AlignInBits), 507 | C.uint64_t(t.OffsetInBits), 508 | C.LLVMDIFlags(t.Flags), 509 | t.Type.C, 510 | ) 511 | return Metadata{C: result} 512 | } 513 | 514 | // DISubrange describes an integer value range. 515 | type DISubrange struct { 516 | Lo int64 517 | Count int64 518 | } 519 | 520 | // DIArrayType holds the values for creating array type debug metadata. 521 | type DIArrayType struct { 522 | SizeInBits uint64 523 | AlignInBits uint32 524 | ElementType Metadata 525 | Subscripts []DISubrange 526 | } 527 | 528 | // CreateArrayType creates struct type debug metadata. 529 | func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata { 530 | subscriptsSlice := make([]Metadata, len(t.Subscripts)) 531 | for i, s := range t.Subscripts { 532 | subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count) 533 | } 534 | subscripts, length := llvmMetadataRefs(subscriptsSlice) 535 | result := C.LLVMDIBuilderCreateArrayType( 536 | d.ref, 537 | C.uint64_t(t.SizeInBits), 538 | C.uint32_t(t.AlignInBits), 539 | t.ElementType.C, 540 | subscripts, 541 | length, 542 | ) 543 | return Metadata{C: result} 544 | } 545 | 546 | // DITypedef holds the values for creating typedef type debug metadata. 547 | type DITypedef struct { 548 | Type Metadata 549 | Name string 550 | File Metadata 551 | Line int 552 | Context Metadata 553 | AlignInBits uint32 554 | } 555 | 556 | // CreateTypedef creates typedef type debug metadata. 557 | func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata { 558 | name := C.CString(t.Name) 559 | defer C.free(unsafe.Pointer(name)) 560 | result := C.LLVMDIBuilderCreateTypedef( 561 | d.ref, 562 | t.Type.C, 563 | name, 564 | C.size_t(len(t.Name)), 565 | t.File.C, 566 | C.unsigned(t.Line), 567 | t.Context.C, 568 | C.uint32_t(t.AlignInBits), 569 | ) 570 | return Metadata{C: result} 571 | } 572 | 573 | // getOrCreateSubrange gets a metadata node for the specified subrange, 574 | // creating if required. 575 | func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata { 576 | result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count)) 577 | return Metadata{C: result} 578 | } 579 | 580 | // getOrCreateArray gets a metadata node containing the specified values, 581 | // creating if required. 582 | func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata { 583 | if len(values) == 0 { 584 | return Metadata{} 585 | } 586 | data, length := llvmMetadataRefs(values) 587 | result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length)) 588 | return Metadata{C: result} 589 | } 590 | 591 | // getOrCreateTypeArray gets a metadata node for a type array containing the 592 | // specified values, creating if required. 593 | func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata { 594 | if len(values) == 0 { 595 | return Metadata{} 596 | } 597 | data, length := llvmMetadataRefs(values) 598 | result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length)) 599 | return Metadata{C: result} 600 | } 601 | 602 | // CreateExpression creates a new descriptor for the specified 603 | // variable which has a complex address expression for its address. 604 | func (d *DIBuilder) CreateExpression(addr []uint64) Metadata { 605 | var data *C.uint64_t 606 | if len(addr) > 0 { 607 | data = (*C.uint64_t)(unsafe.Pointer(&addr[0])) 608 | } 609 | result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr))) 610 | return Metadata{C: result} 611 | } 612 | 613 | // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the 614 | // specified basic block for the given value and associated debug metadata. 615 | func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) { 616 | loc := C.LLVMDIBuilderCreateDebugLocation( 617 | d.m.Context().C, C.uint(l.Line), C.uint(l.Col), l.Scope.C, l.InlinedAt.C) 618 | C.LLVMGoDIBuilderInsertDbgValueRecordAtEnd(d.ref, v.C, diVarInfo.C, expr.C, loc, bb.C) 619 | } 620 | 621 | func (v Value) SetSubprogram(sp Metadata) { 622 | C.LLVMSetSubprogram(v.C, sp.C) 623 | } 624 | 625 | func (v Value) Subprogram() (md Metadata) { 626 | md.C = C.LLVMGetSubprogram(v.C) 627 | return 628 | } 629 | 630 | // AddMetadata adds a metadata entry of the given kind to a global object. 631 | func (v Value) AddMetadata(kind int, md Metadata) { 632 | C.LLVMGlobalObjectAddMetadata(v.C, C.unsigned(kind), md.C) 633 | } 634 | 635 | func boolToCInt(v bool) C.int { 636 | if v { 637 | return 1 638 | } 639 | return 0 640 | } 641 | 642 | //------------------------------------------------------------------------- 643 | // llvm.Metadata 644 | //------------------------------------------------------------------------- 645 | 646 | func (c Context) TemporaryMDNode(mds []Metadata) (md Metadata) { 647 | ptr, nvals := llvmMetadataRefs(mds) 648 | md.C = C.LLVMTemporaryMDNode(c.C, ptr, C.size_t(nvals)) 649 | return 650 | } 651 | 652 | func (md Metadata) ReplaceAllUsesWith(new Metadata) { 653 | C.LLVMMetadataReplaceAllUsesWith(md.C, new.C) 654 | } 655 | 656 | type MetadataKind C.LLVMMetadataKind 657 | 658 | const ( 659 | MDStringMetadataKind = C.LLVMMDStringMetadataKind 660 | ConstantAsMetadataMetadataKind = C.LLVMConstantAsMetadataMetadataKind 661 | LocalAsMetadataMetadataKind = C.LLVMLocalAsMetadataMetadataKind 662 | DistinctMDOperandPlaceholderMetadataKind = C.LLVMDistinctMDOperandPlaceholderMetadataKind 663 | MDTupleMetadataKind = C.LLVMMDTupleMetadataKind 664 | DILocationMetadataKind = C.LLVMDILocationMetadataKind 665 | DIExpressionMetadataKind = C.LLVMDIExpressionMetadataKind 666 | DIGlobalVariableExpressionMetadataKind = C.LLVMDIGlobalVariableExpressionMetadataKind 667 | GenericDINodeMetadataKind = C.LLVMGenericDINodeMetadataKind 668 | DISubrangeMetadataKind = C.LLVMDISubrangeMetadataKind 669 | DIEnumeratorMetadataKind = C.LLVMDIEnumeratorMetadataKind 670 | DIBasicTypeMetadataKind = C.LLVMDIBasicTypeMetadataKind 671 | DIDerivedTypeMetadataKind = C.LLVMDIDerivedTypeMetadataKind 672 | DICompositeTypeMetadataKind = C.LLVMDICompositeTypeMetadataKind 673 | DISubroutineTypeMetadataKind = C.LLVMDISubroutineTypeMetadataKind 674 | DIFileMetadataKind = C.LLVMDIFileMetadataKind 675 | DICompileUnitMetadataKind = C.LLVMDICompileUnitMetadataKind 676 | DISubprogramMetadataKind = C.LLVMDISubprogramMetadataKind 677 | DILexicalBlockMetadataKind = C.LLVMDILexicalBlockMetadataKind 678 | DILexicalBlockFileMetadataKind = C.LLVMDILexicalBlockFileMetadataKind 679 | DINamespaceMetadataKind = C.LLVMDINamespaceMetadataKind 680 | DIModuleMetadataKind = C.LLVMDIModuleMetadataKind 681 | DITemplateTypeParameterMetadataKind = C.LLVMDITemplateTypeParameterMetadataKind 682 | DITemplateValueParameterMetadataKind = C.LLVMDITemplateValueParameterMetadataKind 683 | DIGlobalVariableMetadataKind = C.LLVMDIGlobalVariableMetadataKind 684 | DILocalVariableMetadataKind = C.LLVMDILocalVariableMetadataKind 685 | DILabelMetadataKind = C.LLVMDILabelMetadataKind 686 | DIObjCPropertyMetadataKind = C.LLVMDIObjCPropertyMetadataKind 687 | DIImportedEntityMetadataKind = C.LLVMDIImportedEntityMetadataKind 688 | DIMacroMetadataKind = C.LLVMDIMacroMetadataKind 689 | DIMacroFileMetadataKind = C.LLVMDIMacroFileMetadataKind 690 | DICommonBlockMetadataKind = C.LLVMDICommonBlockMetadataKind 691 | ) 692 | 693 | // Kind returns the metadata kind. 694 | func (md Metadata) Kind() MetadataKind { 695 | return MetadataKind(C.LLVMGetMetadataKind(md.C)) 696 | } 697 | 698 | // FileDirectory returns the directory of a DIFile metadata node, or the empty 699 | // string if there is no directory information. 700 | func (md Metadata) FileDirectory() string { 701 | var length C.unsigned 702 | ptr := C.LLVMDIFileGetDirectory(md.C, &length) 703 | if ptr == nil { 704 | return "" 705 | } 706 | return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length]) 707 | } 708 | 709 | // FileFilename returns the filename of a DIFile metadata node, or the empty 710 | // string if there is no filename information. 711 | func (md Metadata) FileFilename() string { 712 | var length C.unsigned 713 | ptr := C.LLVMDIFileGetFilename(md.C, &length) 714 | if ptr == nil { 715 | return "" 716 | } 717 | return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length]) 718 | } 719 | 720 | // FileSource returns the source of a DIFile metadata node. 721 | func (md Metadata) FileSource() string { 722 | var length C.unsigned 723 | ptr := C.LLVMDIFileGetSource(md.C, &length) 724 | if ptr == nil { 725 | return "" 726 | } 727 | return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length]) 728 | } 729 | 730 | // LocationLine returns the line number of a DILocation. 731 | func (md Metadata) LocationLine() uint { 732 | return uint(C.LLVMDILocationGetLine(md.C)) 733 | } 734 | 735 | // LocationColumn returns the column (offset from the start of the line) of a 736 | // DILocation. 737 | func (md Metadata) LocationColumn() uint { 738 | return uint(C.LLVMDILocationGetColumn(md.C)) 739 | } 740 | 741 | // LocationScope returns the local scope associated with this debug location. 742 | func (md Metadata) LocationScope() Metadata { 743 | return Metadata{C.LLVMDILocationGetScope(md.C)} 744 | } 745 | 746 | // LocationInlinedAt return the "inline at" location associated with this debug 747 | // location. 748 | func (md Metadata) LocationInlinedAt() Metadata { 749 | return Metadata{C.LLVMDILocationGetInlinedAt(md.C)} 750 | } 751 | 752 | // ScopeFile returns the file (DIFile) of a given scope. 753 | func (md Metadata) ScopeFile() Metadata { 754 | return Metadata{C.LLVMDIScopeGetFile(md.C)} 755 | } 756 | 757 | // SubprogramLine returns the line number of a DISubprogram. 758 | func (md Metadata) SubprogramLine() uint { 759 | return uint(C.LLVMDISubprogramGetLine(md.C)) 760 | } 761 | -------------------------------------------------------------------------------- /executionengine.go: -------------------------------------------------------------------------------- 1 | //===- executionengine.go - Bindings for executionengine ------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the executionengine component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/Core.h" 17 | #include "llvm-c/ExecutionEngine.h" 18 | #include 19 | */ 20 | import "C" 21 | import "unsafe" 22 | import "errors" 23 | 24 | func LinkInMCJIT() { C.LLVMLinkInMCJIT() } 25 | func LinkInInterpreter() { C.LLVMLinkInInterpreter() } 26 | 27 | type GenericValue struct { 28 | C C.LLVMGenericValueRef 29 | } 30 | type ExecutionEngine struct { 31 | C C.LLVMExecutionEngineRef 32 | } 33 | 34 | type MCJITCompilerOptions struct { 35 | C C.struct_LLVMMCJITCompilerOptions 36 | } 37 | 38 | func (options *MCJITCompilerOptions) SetMCJITOptimizationLevel(level uint) { 39 | options.C.OptLevel = C.uint(level) 40 | } 41 | 42 | func (options *MCJITCompilerOptions) SetMCJITNoFramePointerElim(nfp bool) { 43 | options.C.NoFramePointerElim = boolToLLVMBool(nfp) 44 | } 45 | 46 | func (options *MCJITCompilerOptions) SetMCJITEnableFastISel(fastisel bool) { 47 | options.C.EnableFastISel = boolToLLVMBool(fastisel) 48 | } 49 | 50 | func (options *MCJITCompilerOptions) SetMCJITCodeModel(CodeModel CodeModel) { 51 | options.C.CodeModel = C.LLVMCodeModel(CodeModel) 52 | } 53 | 54 | // helpers 55 | func llvmGenericValueRefPtr(t *GenericValue) *C.LLVMGenericValueRef { 56 | return (*C.LLVMGenericValueRef)(unsafe.Pointer(t)) 57 | } 58 | 59 | //------------------------------------------------------------------------- 60 | // llvm.GenericValue 61 | //------------------------------------------------------------------------- 62 | 63 | func NewGenericValueFromInt(t Type, n uint64, signed bool) (g GenericValue) { 64 | g.C = C.LLVMCreateGenericValueOfInt(t.C, C.ulonglong(n), boolToLLVMBool(signed)) 65 | return 66 | } 67 | func NewGenericValueFromPointer(p unsafe.Pointer) (g GenericValue) { 68 | g.C = C.LLVMCreateGenericValueOfPointer(p) 69 | return 70 | } 71 | func NewGenericValueFromFloat(t Type, n float64) (g GenericValue) { 72 | g.C = C.LLVMCreateGenericValueOfFloat(t.C, C.double(n)) 73 | return 74 | } 75 | func (g GenericValue) IntWidth() int { return int(C.LLVMGenericValueIntWidth(g.C)) } 76 | func (g GenericValue) Int(signed bool) uint64 { 77 | return uint64(C.LLVMGenericValueToInt(g.C, boolToLLVMBool(signed))) 78 | } 79 | func (g GenericValue) Float(t Type) float64 { 80 | return float64(C.LLVMGenericValueToFloat(t.C, g.C)) 81 | } 82 | func (g GenericValue) Pointer() unsafe.Pointer { 83 | return C.LLVMGenericValueToPointer(g.C) 84 | } 85 | func (g GenericValue) Dispose() { C.LLVMDisposeGenericValue(g.C) } 86 | 87 | //------------------------------------------------------------------------- 88 | // llvm.ExecutionEngine 89 | //------------------------------------------------------------------------- 90 | 91 | func NewExecutionEngine(m Module) (ee ExecutionEngine, err error) { 92 | var cmsg *C.char 93 | fail := C.LLVMCreateExecutionEngineForModule(&ee.C, m.C, &cmsg) 94 | if fail != 0 { 95 | ee.C = nil 96 | err = errors.New(C.GoString(cmsg)) 97 | C.LLVMDisposeMessage(cmsg) 98 | } 99 | return 100 | } 101 | 102 | func NewInterpreter(m Module) (ee ExecutionEngine, err error) { 103 | var cmsg *C.char 104 | fail := C.LLVMCreateInterpreterForModule(&ee.C, m.C, &cmsg) 105 | if fail != 0 { 106 | ee.C = nil 107 | err = errors.New(C.GoString(cmsg)) 108 | C.LLVMDisposeMessage(cmsg) 109 | } 110 | return 111 | } 112 | 113 | func NewMCJITCompilerOptions() MCJITCompilerOptions { 114 | var options C.struct_LLVMMCJITCompilerOptions 115 | C.LLVMInitializeMCJITCompilerOptions(&options, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{}))) 116 | return MCJITCompilerOptions{options} 117 | } 118 | 119 | func NewMCJITCompiler(m Module, options MCJITCompilerOptions) (ee ExecutionEngine, err error) { 120 | var cmsg *C.char 121 | fail := C.LLVMCreateMCJITCompilerForModule(&ee.C, m.C, &options.C, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{})), &cmsg) 122 | if fail != 0 { 123 | ee.C = nil 124 | err = errors.New(C.GoString(cmsg)) 125 | C.LLVMDisposeMessage(cmsg) 126 | } 127 | return 128 | } 129 | 130 | func (ee ExecutionEngine) Dispose() { C.LLVMDisposeExecutionEngine(ee.C) } 131 | func (ee ExecutionEngine) RunStaticConstructors() { C.LLVMRunStaticConstructors(ee.C) } 132 | func (ee ExecutionEngine) RunStaticDestructors() { C.LLVMRunStaticDestructors(ee.C) } 133 | 134 | func (ee ExecutionEngine) RunFunction(f Value, args []GenericValue) (g GenericValue) { 135 | nargs := len(args) 136 | var argptr *GenericValue 137 | if nargs > 0 { 138 | argptr = &args[0] 139 | } 140 | g.C = C.LLVMRunFunction(ee.C, f.C, 141 | C.unsigned(nargs), llvmGenericValueRefPtr(argptr)) 142 | return 143 | } 144 | 145 | func (ee ExecutionEngine) FreeMachineCodeForFunction(f Value) { 146 | C.LLVMFreeMachineCodeForFunction(ee.C, f.C) 147 | } 148 | func (ee ExecutionEngine) AddModule(m Module) { C.LLVMAddModule(ee.C, m.C) } 149 | 150 | func (ee ExecutionEngine) RemoveModule(m Module) { 151 | var modtmp C.LLVMModuleRef 152 | C.LLVMRemoveModule(ee.C, m.C, &modtmp, nil) 153 | } 154 | 155 | func (ee ExecutionEngine) FindFunction(name string) (f Value) { 156 | cname := C.CString(name) 157 | defer C.free(unsafe.Pointer(cname)) 158 | C.LLVMFindFunction(ee.C, cname, &f.C) 159 | return 160 | } 161 | 162 | func (ee ExecutionEngine) RecompileAndRelinkFunction(f Value) unsafe.Pointer { 163 | return C.LLVMRecompileAndRelinkFunction(ee.C, f.C) 164 | } 165 | 166 | func (ee ExecutionEngine) TargetData() (td TargetData) { 167 | td.C = C.LLVMGetExecutionEngineTargetData(ee.C) 168 | return 169 | } 170 | 171 | func (ee ExecutionEngine) AddGlobalMapping(global Value, addr unsafe.Pointer) { 172 | C.LLVMAddGlobalMapping(ee.C, global.C, addr) 173 | } 174 | 175 | func (ee ExecutionEngine) PointerToGlobal(global Value) unsafe.Pointer { 176 | return C.LLVMGetPointerToGlobal(ee.C, global.C) 177 | } 178 | -------------------------------------------------------------------------------- /executionengine_test.go: -------------------------------------------------------------------------------- 1 | //===- executionengine_test.go - Tests for executionengine ----------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file tests bindings for the executionengine component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | import ( 16 | "testing" 17 | ) 18 | 19 | func TestFactorial(t *testing.T) { 20 | LinkInMCJIT() 21 | InitializeNativeTarget() 22 | InitializeNativeAsmPrinter() 23 | 24 | ctx := NewContext() 25 | mod := ctx.NewModule("fac_module") 26 | 27 | fac_args := []Type{ctx.Int32Type()} 28 | fac_type := FunctionType(ctx.Int32Type(), fac_args, false) 29 | fac := AddFunction(mod, "fac", fac_type) 30 | fac.SetFunctionCallConv(CCallConv) 31 | n := fac.Param(0) 32 | 33 | entry := AddBasicBlock(fac, "entry") 34 | iftrue := AddBasicBlock(fac, "iftrue") 35 | iffalse := AddBasicBlock(fac, "iffalse") 36 | end := AddBasicBlock(fac, "end") 37 | 38 | builder := ctx.NewBuilder() 39 | defer builder.Dispose() 40 | 41 | builder.SetInsertPointAtEnd(entry) 42 | If := builder.CreateICmp(IntEQ, n, ConstInt(ctx.Int32Type(), 0, false), "cmptmp") 43 | builder.CreateCondBr(If, iftrue, iffalse) 44 | 45 | builder.SetInsertPointAtEnd(iftrue) 46 | res_iftrue := ConstInt(ctx.Int32Type(), 1, false) 47 | builder.CreateBr(end) 48 | 49 | builder.SetInsertPointAtEnd(iffalse) 50 | n_minus := builder.CreateSub(n, ConstInt(ctx.Int32Type(), 1, false), "subtmp") 51 | call_fac_args := []Value{n_minus} 52 | call_fac := builder.CreateCall(fac_type, fac, call_fac_args, "calltmp") 53 | res_iffalse := builder.CreateMul(n, call_fac, "multmp") 54 | builder.CreateBr(end) 55 | 56 | builder.SetInsertPointAtEnd(end) 57 | res := builder.CreatePHI(ctx.Int32Type(), "result") 58 | phi_vals := []Value{res_iftrue, res_iffalse} 59 | phi_blocks := []BasicBlock{iftrue, iffalse} 60 | res.AddIncoming(phi_vals, phi_blocks) 61 | builder.CreateRet(res) 62 | 63 | err := VerifyModule(mod, ReturnStatusAction) 64 | if err != nil { 65 | t.Errorf("Error verifying module: %s", err) 66 | return 67 | } 68 | 69 | options := NewMCJITCompilerOptions() 70 | options.SetMCJITOptimizationLevel(2) 71 | options.SetMCJITEnableFastISel(true) 72 | options.SetMCJITNoFramePointerElim(true) 73 | options.SetMCJITCodeModel(CodeModelJITDefault) 74 | engine, err := NewMCJITCompiler(mod, options) 75 | if err != nil { 76 | t.Errorf("Error creating JIT: %s", err) 77 | return 78 | } 79 | defer engine.Dispose() 80 | 81 | exec_args := []GenericValue{NewGenericValueFromInt(ctx.Int32Type(), 10, false)} 82 | exec_res := engine.RunFunction(fac, exec_args) 83 | var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 84 | if exec_res.Int(false) != fac10 { 85 | t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false)) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module tinygo.org/x/go-llvm 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /ir.go: -------------------------------------------------------------------------------- 1 | //===- ir.go - Bindings for ir --------------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the ir component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/Core.h" 17 | #include "llvm-c/Comdat.h" 18 | #include "IRBindings.h" 19 | #include 20 | */ 21 | import "C" 22 | import ( 23 | "errors" 24 | "unsafe" 25 | ) 26 | 27 | type ( 28 | // We use these weird structs here because *Ref types are pointers and 29 | // Go's spec says that a pointer cannot be used as a receiver base type. 30 | Context struct { 31 | C C.LLVMContextRef 32 | } 33 | Module struct { 34 | C C.LLVMModuleRef 35 | } 36 | Type struct { 37 | C C.LLVMTypeRef 38 | } 39 | Value struct { 40 | C C.LLVMValueRef 41 | } 42 | Comdat struct { 43 | C C.LLVMComdatRef 44 | } 45 | BasicBlock struct { 46 | C C.LLVMBasicBlockRef 47 | } 48 | Builder struct { 49 | C C.LLVMBuilderRef 50 | } 51 | ModuleProvider struct { 52 | C C.LLVMModuleProviderRef 53 | } 54 | MemoryBuffer struct { 55 | C C.LLVMMemoryBufferRef 56 | } 57 | PassManager struct { 58 | C C.LLVMPassManagerRef 59 | } 60 | Use struct { 61 | C C.LLVMUseRef 62 | } 63 | Metadata struct { 64 | C C.LLVMMetadataRef 65 | } 66 | Attribute struct { 67 | C C.LLVMAttributeRef 68 | } 69 | Opcode C.LLVMOpcode 70 | AtomicRMWBinOp C.LLVMAtomicRMWBinOp 71 | AtomicOrdering C.LLVMAtomicOrdering 72 | TypeKind C.LLVMTypeKind 73 | Linkage C.LLVMLinkage 74 | Visibility C.LLVMVisibility 75 | CallConv C.LLVMCallConv 76 | ComdatSelectionKind C.LLVMComdatSelectionKind 77 | IntPredicate C.LLVMIntPredicate 78 | FloatPredicate C.LLVMRealPredicate 79 | LandingPadClause C.LLVMLandingPadClauseTy 80 | InlineAsmDialect C.LLVMInlineAsmDialect 81 | ) 82 | 83 | func (c Context) IsNil() bool { return c.C == nil } 84 | func (c Module) IsNil() bool { return c.C == nil } 85 | func (c Type) IsNil() bool { return c.C == nil } 86 | func (c Value) IsNil() bool { return c.C == nil } 87 | func (c BasicBlock) IsNil() bool { return c.C == nil } 88 | func (c Builder) IsNil() bool { return c.C == nil } 89 | func (c ModuleProvider) IsNil() bool { return c.C == nil } 90 | func (c MemoryBuffer) IsNil() bool { return c.C == nil } 91 | func (c PassManager) IsNil() bool { return c.C == nil } 92 | func (c Use) IsNil() bool { return c.C == nil } 93 | func (c Attribute) IsNil() bool { return c.C == nil } 94 | func (c Metadata) IsNil() bool { return c.C == nil } 95 | 96 | // helpers 97 | func llvmTypeRefPtr(t *Type) *C.LLVMTypeRef { return (*C.LLVMTypeRef)(unsafe.Pointer(t)) } 98 | func llvmValueRefPtr(t *Value) *C.LLVMValueRef { return (*C.LLVMValueRef)(unsafe.Pointer(t)) } 99 | func llvmMetadataRefPtr(t *Metadata) *C.LLVMMetadataRef { 100 | return (*C.LLVMMetadataRef)(unsafe.Pointer(t)) 101 | } 102 | func llvmBasicBlockRefPtr(t *BasicBlock) *C.LLVMBasicBlockRef { 103 | return (*C.LLVMBasicBlockRef)(unsafe.Pointer(t)) 104 | } 105 | func boolToLLVMBool(b bool) C.LLVMBool { 106 | if b { 107 | return C.LLVMBool(1) 108 | } 109 | return C.LLVMBool(0) 110 | } 111 | 112 | func llvmValueRefs(values []Value) (*C.LLVMValueRef, C.unsigned) { 113 | var pt *C.LLVMValueRef 114 | ptlen := C.unsigned(len(values)) 115 | if ptlen > 0 { 116 | pt = llvmValueRefPtr(&values[0]) 117 | } 118 | return pt, ptlen 119 | } 120 | 121 | func llvmMetadataRefs(mds []Metadata) (*C.LLVMMetadataRef, C.unsigned) { 122 | var pt *C.LLVMMetadataRef 123 | ptlen := C.unsigned(len(mds)) 124 | if ptlen > 0 { 125 | pt = llvmMetadataRefPtr(&mds[0]) 126 | } 127 | return pt, ptlen 128 | } 129 | 130 | //------------------------------------------------------------------------- 131 | // llvm.Opcode 132 | //------------------------------------------------------------------------- 133 | 134 | const ( 135 | Ret Opcode = C.LLVMRet 136 | Br Opcode = C.LLVMBr 137 | Switch Opcode = C.LLVMSwitch 138 | IndirectBr Opcode = C.LLVMIndirectBr 139 | Invoke Opcode = C.LLVMInvoke 140 | Unreachable Opcode = C.LLVMUnreachable 141 | 142 | // Standard Binary Operators 143 | Add Opcode = C.LLVMAdd 144 | FAdd Opcode = C.LLVMFAdd 145 | Sub Opcode = C.LLVMSub 146 | FSub Opcode = C.LLVMFSub 147 | Mul Opcode = C.LLVMMul 148 | FMul Opcode = C.LLVMFMul 149 | UDiv Opcode = C.LLVMUDiv 150 | SDiv Opcode = C.LLVMSDiv 151 | FDiv Opcode = C.LLVMFDiv 152 | URem Opcode = C.LLVMURem 153 | SRem Opcode = C.LLVMSRem 154 | FRem Opcode = C.LLVMFRem 155 | 156 | // Logical Operators 157 | Shl Opcode = C.LLVMShl 158 | LShr Opcode = C.LLVMLShr 159 | AShr Opcode = C.LLVMAShr 160 | And Opcode = C.LLVMAnd 161 | Or Opcode = C.LLVMOr 162 | Xor Opcode = C.LLVMXor 163 | 164 | // Memory Operators 165 | Alloca Opcode = C.LLVMAlloca 166 | Load Opcode = C.LLVMLoad 167 | Store Opcode = C.LLVMStore 168 | GetElementPtr Opcode = C.LLVMGetElementPtr 169 | 170 | // Cast Operators 171 | Trunc Opcode = C.LLVMTrunc 172 | ZExt Opcode = C.LLVMZExt 173 | SExt Opcode = C.LLVMSExt 174 | FPToUI Opcode = C.LLVMFPToUI 175 | FPToSI Opcode = C.LLVMFPToSI 176 | UIToFP Opcode = C.LLVMUIToFP 177 | SIToFP Opcode = C.LLVMSIToFP 178 | FPTrunc Opcode = C.LLVMFPTrunc 179 | FPExt Opcode = C.LLVMFPExt 180 | PtrToInt Opcode = C.LLVMPtrToInt 181 | IntToPtr Opcode = C.LLVMIntToPtr 182 | BitCast Opcode = C.LLVMBitCast 183 | 184 | // Other Operators 185 | ICmp Opcode = C.LLVMICmp 186 | FCmp Opcode = C.LLVMFCmp 187 | PHI Opcode = C.LLVMPHI 188 | Call Opcode = C.LLVMCall 189 | Select Opcode = C.LLVMSelect 190 | // UserOp1 191 | // UserOp2 192 | VAArg Opcode = C.LLVMVAArg 193 | ExtractElement Opcode = C.LLVMExtractElement 194 | InsertElement Opcode = C.LLVMInsertElement 195 | ShuffleVector Opcode = C.LLVMShuffleVector 196 | ExtractValue Opcode = C.LLVMExtractValue 197 | InsertValue Opcode = C.LLVMInsertValue 198 | 199 | // Exception Handling Operators 200 | Resume Opcode = C.LLVMResume 201 | LandingPad Opcode = C.LLVMLandingPad 202 | CleanupRet Opcode = C.LLVMCleanupRet 203 | CatchRet Opcode = C.LLVMCatchRet 204 | CatchPad Opcode = C.LLVMCatchPad 205 | CleanupPad Opcode = C.LLVMCleanupPad 206 | CatchSwitch Opcode = C.LLVMCatchSwitch 207 | ) 208 | 209 | const ( 210 | AtomicRMWBinOpXchg AtomicRMWBinOp = C.LLVMAtomicRMWBinOpXchg 211 | AtomicRMWBinOpAdd AtomicRMWBinOp = C.LLVMAtomicRMWBinOpAdd 212 | AtomicRMWBinOpSub AtomicRMWBinOp = C.LLVMAtomicRMWBinOpSub 213 | AtomicRMWBinOpAnd AtomicRMWBinOp = C.LLVMAtomicRMWBinOpAnd 214 | AtomicRMWBinOpNand AtomicRMWBinOp = C.LLVMAtomicRMWBinOpNand 215 | AtomicRMWBinOpOr AtomicRMWBinOp = C.LLVMAtomicRMWBinOpOr 216 | AtomicRMWBinOpXor AtomicRMWBinOp = C.LLVMAtomicRMWBinOpXor 217 | AtomicRMWBinOpMax AtomicRMWBinOp = C.LLVMAtomicRMWBinOpMax 218 | AtomicRMWBinOpMin AtomicRMWBinOp = C.LLVMAtomicRMWBinOpMin 219 | AtomicRMWBinOpUMax AtomicRMWBinOp = C.LLVMAtomicRMWBinOpUMax 220 | AtomicRMWBinOpUMin AtomicRMWBinOp = C.LLVMAtomicRMWBinOpUMin 221 | ) 222 | 223 | const ( 224 | AtomicOrderingNotAtomic AtomicOrdering = C.LLVMAtomicOrderingNotAtomic 225 | AtomicOrderingUnordered AtomicOrdering = C.LLVMAtomicOrderingUnordered 226 | AtomicOrderingMonotonic AtomicOrdering = C.LLVMAtomicOrderingMonotonic 227 | AtomicOrderingAcquire AtomicOrdering = C.LLVMAtomicOrderingAcquire 228 | AtomicOrderingRelease AtomicOrdering = C.LLVMAtomicOrderingRelease 229 | AtomicOrderingAcquireRelease AtomicOrdering = C.LLVMAtomicOrderingAcquireRelease 230 | AtomicOrderingSequentiallyConsistent AtomicOrdering = C.LLVMAtomicOrderingSequentiallyConsistent 231 | ) 232 | 233 | //------------------------------------------------------------------------- 234 | // llvm.TypeKind 235 | //------------------------------------------------------------------------- 236 | 237 | const ( 238 | VoidTypeKind TypeKind = C.LLVMVoidTypeKind 239 | FloatTypeKind TypeKind = C.LLVMFloatTypeKind 240 | DoubleTypeKind TypeKind = C.LLVMDoubleTypeKind 241 | X86_FP80TypeKind TypeKind = C.LLVMX86_FP80TypeKind 242 | FP128TypeKind TypeKind = C.LLVMFP128TypeKind 243 | PPC_FP128TypeKind TypeKind = C.LLVMPPC_FP128TypeKind 244 | LabelTypeKind TypeKind = C.LLVMLabelTypeKind 245 | IntegerTypeKind TypeKind = C.LLVMIntegerTypeKind 246 | FunctionTypeKind TypeKind = C.LLVMFunctionTypeKind 247 | StructTypeKind TypeKind = C.LLVMStructTypeKind 248 | ArrayTypeKind TypeKind = C.LLVMArrayTypeKind 249 | PointerTypeKind TypeKind = C.LLVMPointerTypeKind 250 | VectorTypeKind TypeKind = C.LLVMVectorTypeKind 251 | MetadataTypeKind TypeKind = C.LLVMMetadataTypeKind 252 | TokenTypeKind TypeKind = C.LLVMTokenTypeKind 253 | ) 254 | 255 | //------------------------------------------------------------------------- 256 | // llvm.Linkage 257 | //------------------------------------------------------------------------- 258 | 259 | const ( 260 | ExternalLinkage Linkage = C.LLVMExternalLinkage 261 | AvailableExternallyLinkage Linkage = C.LLVMAvailableExternallyLinkage 262 | LinkOnceAnyLinkage Linkage = C.LLVMLinkOnceAnyLinkage 263 | LinkOnceODRLinkage Linkage = C.LLVMLinkOnceODRLinkage 264 | WeakAnyLinkage Linkage = C.LLVMWeakAnyLinkage 265 | WeakODRLinkage Linkage = C.LLVMWeakODRLinkage 266 | AppendingLinkage Linkage = C.LLVMAppendingLinkage 267 | InternalLinkage Linkage = C.LLVMInternalLinkage 268 | PrivateLinkage Linkage = C.LLVMPrivateLinkage 269 | ExternalWeakLinkage Linkage = C.LLVMExternalWeakLinkage 270 | CommonLinkage Linkage = C.LLVMCommonLinkage 271 | ) 272 | 273 | //------------------------------------------------------------------------- 274 | // llvm.Visibility 275 | //------------------------------------------------------------------------- 276 | 277 | const ( 278 | DefaultVisibility Visibility = C.LLVMDefaultVisibility 279 | HiddenVisibility Visibility = C.LLVMHiddenVisibility 280 | ProtectedVisibility Visibility = C.LLVMProtectedVisibility 281 | ) 282 | 283 | //------------------------------------------------------------------------- 284 | // llvm.CallConv 285 | //------------------------------------------------------------------------- 286 | 287 | const ( 288 | CCallConv CallConv = C.LLVMCCallConv 289 | FastCallConv CallConv = C.LLVMFastCallConv 290 | ColdCallConv CallConv = C.LLVMColdCallConv 291 | X86StdcallCallConv CallConv = C.LLVMX86StdcallCallConv 292 | X86FastcallCallConv CallConv = C.LLVMX86FastcallCallConv 293 | ) 294 | 295 | //------------------------------------------------------------------------- 296 | // llvm.ComdatSelectionKind 297 | //------------------------------------------------------------------------- 298 | 299 | const ( 300 | AnyComdatSelectionKind ComdatSelectionKind = C.LLVMAnyComdatSelectionKind 301 | ExactMatchComdatSelectionKind ComdatSelectionKind = C.LLVMExactMatchComdatSelectionKind 302 | LargestComdatSelectionKind ComdatSelectionKind = C.LLVMLargestComdatSelectionKind 303 | NoDeduplicateComdatSelectionKind ComdatSelectionKind = C.LLVMNoDeduplicateComdatSelectionKind 304 | SameSizeComdatSelectionKind ComdatSelectionKind = C.LLVMSameSizeComdatSelectionKind 305 | ) 306 | 307 | //------------------------------------------------------------------------- 308 | // llvm.IntPredicate 309 | //------------------------------------------------------------------------- 310 | 311 | const ( 312 | IntEQ IntPredicate = C.LLVMIntEQ 313 | IntNE IntPredicate = C.LLVMIntNE 314 | IntUGT IntPredicate = C.LLVMIntUGT 315 | IntUGE IntPredicate = C.LLVMIntUGE 316 | IntULT IntPredicate = C.LLVMIntULT 317 | IntULE IntPredicate = C.LLVMIntULE 318 | IntSGT IntPredicate = C.LLVMIntSGT 319 | IntSGE IntPredicate = C.LLVMIntSGE 320 | IntSLT IntPredicate = C.LLVMIntSLT 321 | IntSLE IntPredicate = C.LLVMIntSLE 322 | ) 323 | 324 | //------------------------------------------------------------------------- 325 | // llvm.FloatPredicate 326 | //------------------------------------------------------------------------- 327 | 328 | const ( 329 | FloatPredicateFalse FloatPredicate = C.LLVMRealPredicateFalse 330 | FloatOEQ FloatPredicate = C.LLVMRealOEQ 331 | FloatOGT FloatPredicate = C.LLVMRealOGT 332 | FloatOGE FloatPredicate = C.LLVMRealOGE 333 | FloatOLT FloatPredicate = C.LLVMRealOLT 334 | FloatOLE FloatPredicate = C.LLVMRealOLE 335 | FloatONE FloatPredicate = C.LLVMRealONE 336 | FloatORD FloatPredicate = C.LLVMRealORD 337 | FloatUNO FloatPredicate = C.LLVMRealUNO 338 | FloatUEQ FloatPredicate = C.LLVMRealUEQ 339 | FloatUGT FloatPredicate = C.LLVMRealUGT 340 | FloatUGE FloatPredicate = C.LLVMRealUGE 341 | FloatULT FloatPredicate = C.LLVMRealULT 342 | FloatULE FloatPredicate = C.LLVMRealULE 343 | FloatUNE FloatPredicate = C.LLVMRealUNE 344 | FloatPredicateTrue FloatPredicate = C.LLVMRealPredicateTrue 345 | ) 346 | 347 | //------------------------------------------------------------------------- 348 | // llvm.LandingPadClause 349 | //------------------------------------------------------------------------- 350 | 351 | const ( 352 | LandingPadCatch LandingPadClause = C.LLVMLandingPadCatch 353 | LandingPadFilter LandingPadClause = C.LLVMLandingPadFilter 354 | ) 355 | 356 | //------------------------------------------------------------------------- 357 | // llvm.InlineAsmDialect 358 | //------------------------------------------------------------------------- 359 | 360 | const ( 361 | InlineAsmDialectATT InlineAsmDialect = C.LLVMInlineAsmDialectATT 362 | InlineAsmDialectIntel InlineAsmDialect = C.LLVMInlineAsmDialectIntel 363 | ) 364 | 365 | //------------------------------------------------------------------------- 366 | // llvm.Context 367 | //------------------------------------------------------------------------- 368 | 369 | func NewContext() Context { return Context{C.LLVMContextCreate()} } 370 | func GlobalContext() Context { return Context{C.LLVMGetGlobalContext()} } 371 | func (c Context) Dispose() { C.LLVMContextDispose(c.C) } 372 | 373 | func (c Context) MDKindID(name string) (id int) { 374 | cname := C.CString(name) 375 | defer C.free(unsafe.Pointer(cname)) 376 | id = int(C.LLVMGetMDKindIDInContext(c.C, cname, C.unsigned(len(name)))) 377 | return 378 | } 379 | 380 | func MDKindID(name string) (id int) { 381 | cname := C.CString(name) 382 | defer C.free(unsafe.Pointer(cname)) 383 | id = int(C.LLVMGetMDKindID(cname, C.unsigned(len(name)))) 384 | return 385 | } 386 | 387 | //------------------------------------------------------------------------- 388 | // llvm.Attribute 389 | //------------------------------------------------------------------------- 390 | 391 | func AttributeKindID(name string) (id uint) { 392 | cname := C.CString(name) 393 | defer C.free(unsafe.Pointer(cname)) 394 | id = uint(C.LLVMGetEnumAttributeKindForName(cname, C.size_t(len(name)))) 395 | return 396 | } 397 | 398 | func (c Context) CreateEnumAttribute(kind uint, val uint64) (a Attribute) { 399 | a.C = C.LLVMCreateEnumAttribute(c.C, C.unsigned(kind), C.uint64_t(val)) 400 | return 401 | } 402 | 403 | func (c Context) CreateTypeAttribute(kind uint, t Type) (a Attribute) { 404 | a.C = C.LLVMCreateTypeAttribute(c.C, C.unsigned(kind), t.C) 405 | return 406 | } 407 | 408 | func (a Attribute) GetTypeValue() (t Type) { 409 | t.C = C.LLVMGetTypeAttributeValue(a.C) 410 | return 411 | } 412 | 413 | func (a Attribute) GetEnumKind() (id int) { 414 | id = int(C.LLVMGetEnumAttributeKind(a.C)) 415 | return 416 | } 417 | 418 | func (a Attribute) GetEnumValue() (val uint64) { 419 | val = uint64(C.LLVMGetEnumAttributeValue(a.C)) 420 | return 421 | } 422 | 423 | func (c Context) CreateStringAttribute(kind string, val string) (a Attribute) { 424 | ckind := C.CString(kind) 425 | defer C.free(unsafe.Pointer(ckind)) 426 | cval := C.CString(val) 427 | defer C.free(unsafe.Pointer(cval)) 428 | a.C = C.LLVMCreateStringAttribute(c.C, 429 | ckind, C.unsigned(len(kind)), 430 | cval, C.unsigned(len(val))) 431 | return 432 | } 433 | 434 | func (a Attribute) GetStringKind() string { 435 | length := C.unsigned(0) 436 | ckind := C.LLVMGetStringAttributeKind(a.C, &length) 437 | return C.GoStringN(ckind, C.int(length)) 438 | } 439 | 440 | func (a Attribute) GetStringValue() string { 441 | length := C.unsigned(0) 442 | ckind := C.LLVMGetStringAttributeValue(a.C, &length) 443 | return C.GoStringN(ckind, C.int(length)) 444 | } 445 | 446 | func (a Attribute) IsEnum() bool { 447 | return C.LLVMIsEnumAttribute(a.C) != 0 448 | } 449 | 450 | func (a Attribute) IsString() bool { 451 | return C.LLVMIsStringAttribute(a.C) != 0 452 | } 453 | 454 | //------------------------------------------------------------------------- 455 | // llvm.Module 456 | //------------------------------------------------------------------------- 457 | 458 | // Create and destroy modules. 459 | // See llvm::Module::Module. 460 | func (c Context) NewModule(name string) (m Module) { 461 | cname := C.CString(name) 462 | defer C.free(unsafe.Pointer(cname)) 463 | m.C = C.LLVMModuleCreateWithNameInContext(cname, c.C) 464 | return 465 | } 466 | 467 | // See llvm::Module::~Module 468 | func (m Module) Dispose() { C.LLVMDisposeModule(m.C) } 469 | 470 | // Data layout. See Module::getDataLayout. 471 | func (m Module) DataLayout() string { 472 | clayout := C.LLVMGetDataLayout(m.C) 473 | return C.GoString(clayout) 474 | } 475 | 476 | func (m Module) SetDataLayout(layout string) { 477 | clayout := C.CString(layout) 478 | defer C.free(unsafe.Pointer(clayout)) 479 | C.LLVMSetDataLayout(m.C, clayout) 480 | } 481 | 482 | // Target triple. See Module::getTargetTriple. 483 | func (m Module) Target() string { 484 | ctarget := C.LLVMGetTarget(m.C) 485 | return C.GoString(ctarget) 486 | } 487 | func (m Module) SetTarget(target string) { 488 | ctarget := C.CString(target) 489 | defer C.free(unsafe.Pointer(ctarget)) 490 | C.LLVMSetTarget(m.C, ctarget) 491 | } 492 | 493 | func (m Module) GetTypeByName(name string) (t Type) { 494 | cname := C.CString(name) 495 | defer C.free(unsafe.Pointer(cname)) 496 | t.C = C.LLVMGetTypeByName(m.C, cname) 497 | return 498 | } 499 | 500 | // See Module::dump. 501 | func (m Module) Dump() { 502 | C.LLVMDumpModule(m.C) 503 | } 504 | 505 | func (m Module) String() string { 506 | cir := C.LLVMPrintModuleToString(m.C) 507 | defer C.LLVMDisposeMessage(cir) 508 | ir := C.GoString(cir) 509 | return ir 510 | } 511 | 512 | // See Module::setModuleInlineAsm. 513 | func (m Module) SetInlineAsm(asm string) { 514 | casm := C.CString(asm) 515 | defer C.free(unsafe.Pointer(casm)) 516 | C.LLVMSetModuleInlineAsm(m.C, casm) 517 | } 518 | 519 | func (m Module) AddNamedMetadataOperand(name string, operand Metadata) { 520 | cname := C.CString(name) 521 | defer C.free(unsafe.Pointer(cname)) 522 | C.LLVMAddNamedMetadataOperand2(m.C, cname, operand.C) 523 | } 524 | 525 | func (m Module) Context() (c Context) { 526 | c.C = C.LLVMGetModuleContext(m.C) 527 | return 528 | } 529 | 530 | //------------------------------------------------------------------------- 531 | // llvm.Type 532 | //------------------------------------------------------------------------- 533 | 534 | // LLVM types conform to the following hierarchy: 535 | // 536 | // types: 537 | // integer type 538 | // real type 539 | // function type 540 | // sequence types: 541 | // array type 542 | // pointer type 543 | // vector type 544 | // void type 545 | // label type 546 | // opaque type 547 | 548 | // See llvm::LLVMTypeKind::getTypeID. 549 | func (t Type) TypeKind() TypeKind { return TypeKind(C.LLVMGetTypeKind(t.C)) } 550 | 551 | // See llvm::LLVMType::getContext. 552 | func (t Type) Context() (c Context) { 553 | c.C = C.LLVMGetTypeContext(t.C) 554 | return 555 | } 556 | 557 | // Operations on integer types 558 | func (c Context) Int1Type() (t Type) { t.C = C.LLVMInt1TypeInContext(c.C); return } 559 | func (c Context) Int8Type() (t Type) { t.C = C.LLVMInt8TypeInContext(c.C); return } 560 | func (c Context) Int16Type() (t Type) { t.C = C.LLVMInt16TypeInContext(c.C); return } 561 | func (c Context) Int32Type() (t Type) { t.C = C.LLVMInt32TypeInContext(c.C); return } 562 | func (c Context) Int64Type() (t Type) { t.C = C.LLVMInt64TypeInContext(c.C); return } 563 | func (c Context) IntType(numbits int) (t Type) { 564 | t.C = C.LLVMIntTypeInContext(c.C, C.unsigned(numbits)) 565 | return 566 | } 567 | 568 | func (t Type) IntTypeWidth() int { 569 | return int(C.LLVMGetIntTypeWidth(t.C)) 570 | } 571 | 572 | // Operations on real types 573 | func (c Context) FloatType() (t Type) { t.C = C.LLVMFloatTypeInContext(c.C); return } 574 | func (c Context) DoubleType() (t Type) { t.C = C.LLVMDoubleTypeInContext(c.C); return } 575 | func (c Context) X86FP80Type() (t Type) { t.C = C.LLVMX86FP80TypeInContext(c.C); return } 576 | func (c Context) FP128Type() (t Type) { t.C = C.LLVMFP128TypeInContext(c.C); return } 577 | func (c Context) PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128TypeInContext(c.C); return } 578 | 579 | // Operations on function types 580 | func FunctionType(returnType Type, paramTypes []Type, isVarArg bool) (t Type) { 581 | var pt *C.LLVMTypeRef 582 | var ptlen C.unsigned 583 | if len(paramTypes) > 0 { 584 | pt = llvmTypeRefPtr(¶mTypes[0]) 585 | ptlen = C.unsigned(len(paramTypes)) 586 | } 587 | t.C = C.LLVMFunctionType(returnType.C, 588 | pt, 589 | ptlen, 590 | boolToLLVMBool(isVarArg)) 591 | return 592 | } 593 | 594 | func (t Type) IsFunctionVarArg() bool { return C.LLVMIsFunctionVarArg(t.C) != 0 } 595 | func (t Type) ReturnType() (rt Type) { rt.C = C.LLVMGetReturnType(t.C); return } 596 | func (t Type) ParamTypesCount() int { return int(C.LLVMCountParamTypes(t.C)) } 597 | func (t Type) ParamTypes() []Type { 598 | count := t.ParamTypesCount() 599 | if count > 0 { 600 | out := make([]Type, count) 601 | C.LLVMGetParamTypes(t.C, llvmTypeRefPtr(&out[0])) 602 | return out 603 | } 604 | return nil 605 | } 606 | 607 | // Operations on struct types 608 | func (c Context) StructType(elementTypes []Type, packed bool) (t Type) { 609 | var pt *C.LLVMTypeRef 610 | var ptlen C.unsigned 611 | if len(elementTypes) > 0 { 612 | pt = llvmTypeRefPtr(&elementTypes[0]) 613 | ptlen = C.unsigned(len(elementTypes)) 614 | } 615 | t.C = C.LLVMStructTypeInContext(c.C, 616 | pt, 617 | ptlen, 618 | boolToLLVMBool(packed)) 619 | return 620 | } 621 | 622 | func StructType(elementTypes []Type, packed bool) (t Type) { 623 | var pt *C.LLVMTypeRef 624 | var ptlen C.unsigned 625 | if len(elementTypes) > 0 { 626 | pt = llvmTypeRefPtr(&elementTypes[0]) 627 | ptlen = C.unsigned(len(elementTypes)) 628 | } 629 | t.C = C.LLVMStructType(pt, ptlen, boolToLLVMBool(packed)) 630 | return 631 | } 632 | 633 | func (c Context) StructCreateNamed(name string) (t Type) { 634 | cname := C.CString(name) 635 | defer C.free(unsafe.Pointer(cname)) 636 | t.C = C.LLVMStructCreateNamed(c.C, cname) 637 | return 638 | } 639 | 640 | func (t Type) StructName() string { 641 | return C.GoString(C.LLVMGetStructName(t.C)) 642 | } 643 | 644 | func (t Type) StructSetBody(elementTypes []Type, packed bool) { 645 | var pt *C.LLVMTypeRef 646 | var ptlen C.unsigned 647 | if len(elementTypes) > 0 { 648 | pt = llvmTypeRefPtr(&elementTypes[0]) 649 | ptlen = C.unsigned(len(elementTypes)) 650 | } 651 | C.LLVMStructSetBody(t.C, pt, ptlen, boolToLLVMBool(packed)) 652 | } 653 | 654 | func (t Type) IsStructPacked() bool { return C.LLVMIsPackedStruct(t.C) != 0 } 655 | func (t Type) StructElementTypesCount() int { return int(C.LLVMCountStructElementTypes(t.C)) } 656 | func (t Type) StructElementTypes() []Type { 657 | out := make([]Type, t.StructElementTypesCount()) 658 | if len(out) > 0 { 659 | C.LLVMGetStructElementTypes(t.C, llvmTypeRefPtr(&out[0])) 660 | } 661 | return out 662 | } 663 | 664 | // Operations on array, pointer, and vector types (sequence types) 665 | func (t Type) Subtypes() (ret []Type) { 666 | ret = make([]Type, C.LLVMGetNumContainedTypes(t.C)) 667 | C.LLVMGetSubtypes(t.C, llvmTypeRefPtr(&ret[0])) 668 | return 669 | } 670 | 671 | func ArrayType(elementType Type, elementCount int) (t Type) { 672 | t.C = C.LLVMArrayType(elementType.C, C.unsigned(elementCount)) 673 | return 674 | } 675 | func PointerType(elementType Type, addressSpace int) (t Type) { 676 | t.C = C.LLVMPointerType(elementType.C, C.unsigned(addressSpace)) 677 | return 678 | } 679 | func VectorType(elementType Type, elementCount int) (t Type) { 680 | t.C = C.LLVMVectorType(elementType.C, C.unsigned(elementCount)) 681 | return 682 | } 683 | 684 | func (t Type) ElementType() (rt Type) { rt.C = C.LLVMGetElementType(t.C); return } 685 | func (t Type) ArrayLength() int { return int(C.LLVMGetArrayLength(t.C)) } 686 | func (t Type) PointerAddressSpace() int { return int(C.LLVMGetPointerAddressSpace(t.C)) } 687 | func (t Type) VectorSize() int { return int(C.LLVMGetVectorSize(t.C)) } 688 | 689 | // Operations on other types 690 | func (c Context) VoidType() (t Type) { t.C = C.LLVMVoidTypeInContext(c.C); return } 691 | func (c Context) LabelType() (t Type) { t.C = C.LLVMLabelTypeInContext(c.C); return } 692 | func (c Context) TokenType() (t Type) { t.C = C.LLVMTokenTypeInContext(c.C); return } 693 | 694 | //------------------------------------------------------------------------- 695 | // llvm.Value 696 | //------------------------------------------------------------------------- 697 | 698 | // Operations on all values 699 | func (v Value) Type() (t Type) { t.C = C.LLVMTypeOf(v.C); return } 700 | func (v Value) Name() string { return C.GoString(C.LLVMGetValueName(v.C)) } 701 | func (v Value) SetName(name string) { 702 | cname := C.CString(name) 703 | defer C.free(unsafe.Pointer(cname)) 704 | C.LLVMSetValueName(v.C, cname) 705 | } 706 | func (v Value) Dump() { C.LLVMDumpValue(v.C) } 707 | func (v Value) ReplaceAllUsesWith(nv Value) { C.LLVMReplaceAllUsesWith(v.C, nv.C) } 708 | func (v Value) HasMetadata() bool { return C.LLVMHasMetadata(v.C) != 0 } 709 | func (v Value) Metadata(kind int) (rv Value) { 710 | rv.C = C.LLVMGetMetadata(v.C, C.unsigned(kind)) 711 | return 712 | } 713 | func (v Value) SetMetadata(kind int, node Metadata) { 714 | C.LLVMSetMetadata2(v.C, C.unsigned(kind), node.C) 715 | } 716 | 717 | // Obtain the string value of the instruction. Same as would be printed with 718 | // Value.Dump() (with two spaces at the start but no newline at the end). 719 | func (v Value) String() string { 720 | cstr := C.LLVMPrintValueToString(v.C) 721 | defer C.LLVMDisposeMessage(cstr) 722 | return C.GoString(cstr) 723 | } 724 | 725 | // Conversion functions. 726 | // Return the input value if it is an instance of the specified class, otherwise NULL. 727 | // See llvm::dyn_cast_or_null<>. 728 | func (v Value) IsAArgument() (rv Value) { rv.C = C.LLVMIsAArgument(v.C); return } 729 | func (v Value) IsABasicBlock() (rv Value) { rv.C = C.LLVMIsABasicBlock(v.C); return } 730 | func (v Value) IsAInlineAsm() (rv Value) { rv.C = C.LLVMIsAInlineAsm(v.C); return } 731 | func (v Value) IsAUser() (rv Value) { rv.C = C.LLVMIsAUser(v.C); return } 732 | func (v Value) IsAConstant() (rv Value) { rv.C = C.LLVMIsAConstant(v.C); return } 733 | func (v Value) IsAConstantAggregateZero() (rv Value) { 734 | rv.C = C.LLVMIsAConstantAggregateZero(v.C) 735 | return 736 | } 737 | func (v Value) IsAConstantArray() (rv Value) { rv.C = C.LLVMIsAConstantArray(v.C); return } 738 | func (v Value) IsAConstantExpr() (rv Value) { rv.C = C.LLVMIsAConstantExpr(v.C); return } 739 | func (v Value) IsAConstantFP() (rv Value) { rv.C = C.LLVMIsAConstantFP(v.C); return } 740 | func (v Value) IsAConstantInt() (rv Value) { rv.C = C.LLVMIsAConstantInt(v.C); return } 741 | func (v Value) IsAConstantPointerNull() (rv Value) { rv.C = C.LLVMIsAConstantPointerNull(v.C); return } 742 | func (v Value) IsAConstantStruct() (rv Value) { rv.C = C.LLVMIsAConstantStruct(v.C); return } 743 | func (v Value) IsAConstantVector() (rv Value) { rv.C = C.LLVMIsAConstantVector(v.C); return } 744 | func (v Value) IsAGlobalValue() (rv Value) { rv.C = C.LLVMIsAGlobalValue(v.C); return } 745 | func (v Value) IsAFunction() (rv Value) { rv.C = C.LLVMIsAFunction(v.C); return } 746 | func (v Value) IsAGlobalAlias() (rv Value) { rv.C = C.LLVMIsAGlobalAlias(v.C); return } 747 | func (v Value) IsAGlobalVariable() (rv Value) { rv.C = C.LLVMIsAGlobalVariable(v.C); return } 748 | func (v Value) IsAUndefValue() (rv Value) { rv.C = C.LLVMIsAUndefValue(v.C); return } 749 | func (v Value) IsAInstruction() (rv Value) { rv.C = C.LLVMIsAInstruction(v.C); return } 750 | func (v Value) IsABinaryOperator() (rv Value) { rv.C = C.LLVMIsABinaryOperator(v.C); return } 751 | func (v Value) IsACallInst() (rv Value) { rv.C = C.LLVMIsACallInst(v.C); return } 752 | func (v Value) IsAIntrinsicInst() (rv Value) { rv.C = C.LLVMIsAIntrinsicInst(v.C); return } 753 | func (v Value) IsADbgInfoIntrinsic() (rv Value) { rv.C = C.LLVMIsADbgInfoIntrinsic(v.C); return } 754 | func (v Value) IsADbgDeclareInst() (rv Value) { rv.C = C.LLVMIsADbgDeclareInst(v.C); return } 755 | func (v Value) IsAMemIntrinsic() (rv Value) { rv.C = C.LLVMIsAMemIntrinsic(v.C); return } 756 | func (v Value) IsAMemCpyInst() (rv Value) { rv.C = C.LLVMIsAMemCpyInst(v.C); return } 757 | func (v Value) IsAMemMoveInst() (rv Value) { rv.C = C.LLVMIsAMemMoveInst(v.C); return } 758 | func (v Value) IsAMemSetInst() (rv Value) { rv.C = C.LLVMIsAMemSetInst(v.C); return } 759 | func (v Value) IsACmpInst() (rv Value) { rv.C = C.LLVMIsACmpInst(v.C); return } 760 | func (v Value) IsAFCmpInst() (rv Value) { rv.C = C.LLVMIsAFCmpInst(v.C); return } 761 | func (v Value) IsAICmpInst() (rv Value) { rv.C = C.LLVMIsAICmpInst(v.C); return } 762 | func (v Value) IsAExtractElementInst() (rv Value) { rv.C = C.LLVMIsAExtractElementInst(v.C); return } 763 | func (v Value) IsAGetElementPtrInst() (rv Value) { rv.C = C.LLVMIsAGetElementPtrInst(v.C); return } 764 | func (v Value) IsAInsertElementInst() (rv Value) { rv.C = C.LLVMIsAInsertElementInst(v.C); return } 765 | func (v Value) IsAInsertValueInst() (rv Value) { rv.C = C.LLVMIsAInsertValueInst(v.C); return } 766 | func (v Value) IsAPHINode() (rv Value) { rv.C = C.LLVMIsAPHINode(v.C); return } 767 | func (v Value) IsASelectInst() (rv Value) { rv.C = C.LLVMIsASelectInst(v.C); return } 768 | func (v Value) IsAShuffleVectorInst() (rv Value) { rv.C = C.LLVMIsAShuffleVectorInst(v.C); return } 769 | func (v Value) IsAStoreInst() (rv Value) { rv.C = C.LLVMIsAStoreInst(v.C); return } 770 | func (v Value) IsABranchInst() (rv Value) { rv.C = C.LLVMIsABranchInst(v.C); return } 771 | func (v Value) IsAInvokeInst() (rv Value) { rv.C = C.LLVMIsAInvokeInst(v.C); return } 772 | func (v Value) IsAReturnInst() (rv Value) { rv.C = C.LLVMIsAReturnInst(v.C); return } 773 | func (v Value) IsASwitchInst() (rv Value) { rv.C = C.LLVMIsASwitchInst(v.C); return } 774 | func (v Value) IsAUnreachableInst() (rv Value) { rv.C = C.LLVMIsAUnreachableInst(v.C); return } 775 | func (v Value) IsAUnaryInstruction() (rv Value) { rv.C = C.LLVMIsAUnaryInstruction(v.C); return } 776 | func (v Value) IsAAllocaInst() (rv Value) { rv.C = C.LLVMIsAAllocaInst(v.C); return } 777 | func (v Value) IsACastInst() (rv Value) { rv.C = C.LLVMIsACastInst(v.C); return } 778 | func (v Value) IsABitCastInst() (rv Value) { rv.C = C.LLVMIsABitCastInst(v.C); return } 779 | func (v Value) IsAFPExtInst() (rv Value) { rv.C = C.LLVMIsAFPExtInst(v.C); return } 780 | func (v Value) IsAFPToSIInst() (rv Value) { rv.C = C.LLVMIsAFPToSIInst(v.C); return } 781 | func (v Value) IsAFPToUIInst() (rv Value) { rv.C = C.LLVMIsAFPToUIInst(v.C); return } 782 | func (v Value) IsAFPTruncInst() (rv Value) { rv.C = C.LLVMIsAFPTruncInst(v.C); return } 783 | func (v Value) IsAIntToPtrInst() (rv Value) { rv.C = C.LLVMIsAIntToPtrInst(v.C); return } 784 | func (v Value) IsAPtrToIntInst() (rv Value) { rv.C = C.LLVMIsAPtrToIntInst(v.C); return } 785 | func (v Value) IsASExtInst() (rv Value) { rv.C = C.LLVMIsASExtInst(v.C); return } 786 | func (v Value) IsASIToFPInst() (rv Value) { rv.C = C.LLVMIsASIToFPInst(v.C); return } 787 | func (v Value) IsATruncInst() (rv Value) { rv.C = C.LLVMIsATruncInst(v.C); return } 788 | func (v Value) IsAUIToFPInst() (rv Value) { rv.C = C.LLVMIsAUIToFPInst(v.C); return } 789 | func (v Value) IsAZExtInst() (rv Value) { rv.C = C.LLVMIsAZExtInst(v.C); return } 790 | func (v Value) IsAExtractValueInst() (rv Value) { rv.C = C.LLVMIsAExtractValueInst(v.C); return } 791 | func (v Value) IsALoadInst() (rv Value) { rv.C = C.LLVMIsALoadInst(v.C); return } 792 | func (v Value) IsAVAArgInst() (rv Value) { rv.C = C.LLVMIsAVAArgInst(v.C); return } 793 | 794 | // Operations on Uses 795 | func (v Value) FirstUse() (u Use) { u.C = C.LLVMGetFirstUse(v.C); return } 796 | func (u Use) NextUse() (ru Use) { ru.C = C.LLVMGetNextUse(u.C); return } 797 | func (u Use) User() (v Value) { v.C = C.LLVMGetUser(u.C); return } 798 | func (u Use) UsedValue() (v Value) { v.C = C.LLVMGetUsedValue(u.C); return } 799 | 800 | // Operations on Users 801 | func (v Value) Operand(i int) (rv Value) { rv.C = C.LLVMGetOperand(v.C, C.unsigned(i)); return } 802 | func (v Value) SetOperand(i int, op Value) { C.LLVMSetOperand(v.C, C.unsigned(i), op.C) } 803 | func (v Value) OperandsCount() int { return int(C.LLVMGetNumOperands(v.C)) } 804 | 805 | // Operations on constants of any type 806 | func ConstNull(t Type) (v Value) { v.C = C.LLVMConstNull(t.C); return } 807 | func ConstAllOnes(t Type) (v Value) { v.C = C.LLVMConstAllOnes(t.C); return } 808 | func Undef(t Type) (v Value) { v.C = C.LLVMGetUndef(t.C); return } 809 | func (v Value) IsConstant() bool { return C.LLVMIsConstant(v.C) != 0 } 810 | func (v Value) IsNull() bool { return C.LLVMIsNull(v.C) != 0 } 811 | func (v Value) IsUndef() bool { return C.LLVMIsUndef(v.C) != 0 } 812 | func ConstPointerNull(t Type) (v Value) { v.C = C.LLVMConstPointerNull(t.C); return } 813 | 814 | // Operations on metadata 815 | func (c Context) MDString(str string) (md Metadata) { 816 | cstr := C.CString(str) 817 | defer C.free(unsafe.Pointer(cstr)) 818 | md.C = C.LLVMMDString2(c.C, cstr, C.unsigned(len(str))) 819 | return 820 | } 821 | func (c Context) MDNode(mds []Metadata) (md Metadata) { 822 | ptr, nvals := llvmMetadataRefs(mds) 823 | md.C = C.LLVMMDNode2(c.C, ptr, nvals) 824 | return 825 | } 826 | func (v Value) ConstantAsMetadata() (md Metadata) { 827 | md.C = C.LLVMConstantAsMetadata(v.C) 828 | return 829 | } 830 | 831 | // Operations on scalar constants 832 | func ConstInt(t Type, n uint64, signExtend bool) (v Value) { 833 | v.C = C.LLVMConstInt(t.C, 834 | C.ulonglong(n), 835 | boolToLLVMBool(signExtend)) 836 | return 837 | } 838 | func ConstIntFromString(t Type, str string, radix int) (v Value) { 839 | cstr := C.CString(str) 840 | defer C.free(unsafe.Pointer(cstr)) 841 | v.C = C.LLVMConstIntOfString(t.C, cstr, C.uint8_t(radix)) 842 | return 843 | } 844 | func ConstFloat(t Type, n float64) (v Value) { 845 | v.C = C.LLVMConstReal(t.C, C.double(n)) 846 | return 847 | } 848 | func ConstFloatFromString(t Type, str string) (v Value) { 849 | cstr := C.CString(str) 850 | defer C.free(unsafe.Pointer(cstr)) 851 | v.C = C.LLVMConstRealOfString(t.C, cstr) 852 | return 853 | } 854 | 855 | func (v Value) ZExtValue() uint64 { return uint64(C.LLVMConstIntGetZExtValue(v.C)) } 856 | func (v Value) SExtValue() int64 { return int64(C.LLVMConstIntGetSExtValue(v.C)) } 857 | func (v Value) DoubleValue() (result float64, inexact bool) { 858 | var losesInfo C.LLVMBool 859 | doubleResult := C.LLVMConstRealGetDouble(v.C, &losesInfo) 860 | return float64(doubleResult), losesInfo != 0 861 | } 862 | 863 | // Operations on composite constants 864 | func (c Context) ConstString(str string, addnull bool) (v Value) { 865 | cstr := C.CString(str) 866 | defer C.free(unsafe.Pointer(cstr)) 867 | v.C = C.LLVMConstStringInContext(c.C, cstr, 868 | C.unsigned(len(str)), boolToLLVMBool(!addnull)) 869 | return 870 | } 871 | func (c Context) ConstStruct(constVals []Value, packed bool) (v Value) { 872 | ptr, nvals := llvmValueRefs(constVals) 873 | v.C = C.LLVMConstStructInContext(c.C, ptr, nvals, 874 | boolToLLVMBool(packed)) 875 | return 876 | } 877 | func ConstNamedStruct(t Type, constVals []Value) (v Value) { 878 | ptr, nvals := llvmValueRefs(constVals) 879 | v.C = C.LLVMConstNamedStruct(t.C, ptr, nvals) 880 | return 881 | } 882 | func ConstString(str string, addnull bool) (v Value) { 883 | cstr := C.CString(str) 884 | defer C.free(unsafe.Pointer(cstr)) 885 | v.C = C.LLVMConstString(cstr, 886 | C.unsigned(len(str)), boolToLLVMBool(!addnull)) 887 | return 888 | } 889 | func ConstArray(t Type, constVals []Value) (v Value) { 890 | ptr, nvals := llvmValueRefs(constVals) 891 | v.C = C.LLVMConstArray(t.C, ptr, nvals) 892 | return 893 | } 894 | func ConstStruct(constVals []Value, packed bool) (v Value) { 895 | ptr, nvals := llvmValueRefs(constVals) 896 | v.C = C.LLVMConstStruct(ptr, nvals, boolToLLVMBool(packed)) 897 | return 898 | } 899 | func ConstVector(scalarConstVals []Value, packed bool) (v Value) { 900 | ptr, nvals := llvmValueRefs(scalarConstVals) 901 | v.C = C.LLVMConstVector(ptr, nvals) 902 | return 903 | } 904 | 905 | // IsConstantString checks if the constant is an array of i8. 906 | func (v Value) IsConstantString() bool { 907 | return C.LLVMIsConstantString(v.C) != 0 908 | } 909 | 910 | // ConstGetAsString will return the string contained in a constant. 911 | func (v Value) ConstGetAsString() string { 912 | length := C.size_t(0) 913 | cstr := C.LLVMGetAsString(v.C, &length) 914 | return C.GoStringN(cstr, C.int(length)) 915 | } 916 | 917 | // Constant expressions 918 | func (v Value) Opcode() Opcode { return Opcode(C.LLVMGetConstOpcode(v.C)) } 919 | func (v Value) InstructionOpcode() Opcode { return Opcode(C.LLVMGetInstructionOpcode(v.C)) } 920 | func AlignOf(t Type) (v Value) { v.C = C.LLVMAlignOf(t.C); return } 921 | func SizeOf(t Type) (v Value) { v.C = C.LLVMSizeOf(t.C); return } 922 | func ConstNeg(v Value) (rv Value) { rv.C = C.LLVMConstNeg(v.C); return } 923 | func ConstNSWNeg(v Value) (rv Value) { rv.C = C.LLVMConstNSWNeg(v.C); return } 924 | func ConstNot(v Value) (rv Value) { rv.C = C.LLVMConstNot(v.C); return } 925 | func ConstAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAdd(lhs.C, rhs.C); return } 926 | func ConstNSWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWAdd(lhs.C, rhs.C); return } 927 | func ConstNUWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWAdd(lhs.C, rhs.C); return } 928 | func ConstSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSub(lhs.C, rhs.C); return } 929 | func ConstNSWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWSub(lhs.C, rhs.C); return } 930 | func ConstNUWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWSub(lhs.C, rhs.C); return } 931 | func ConstMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstMul(lhs.C, rhs.C); return } 932 | func ConstNSWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWMul(lhs.C, rhs.C); return } 933 | func ConstNUWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWMul(lhs.C, rhs.C); return } 934 | func ConstXor(lhs, rhs Value) (v Value) { v.C = C.LLVMConstXor(lhs.C, rhs.C); return } 935 | 936 | func ConstGEP(t Type, v Value, indices []Value) (rv Value) { 937 | ptr, nvals := llvmValueRefs(indices) 938 | rv.C = C.LLVMConstGEP2(t.C, v.C, ptr, nvals) 939 | return 940 | } 941 | func ConstInBoundsGEP(t Type, v Value, indices []Value) (rv Value) { 942 | ptr, nvals := llvmValueRefs(indices) 943 | rv.C = C.LLVMConstInBoundsGEP2(t.C, v.C, ptr, nvals) 944 | return 945 | } 946 | func ConstTrunc(v Value, t Type) (rv Value) { rv.C = C.LLVMConstTrunc(v.C, t.C); return } 947 | func ConstPtrToInt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPtrToInt(v.C, t.C); return } 948 | func ConstIntToPtr(v Value, t Type) (rv Value) { rv.C = C.LLVMConstIntToPtr(v.C, t.C); return } 949 | func ConstBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstBitCast(v.C, t.C); return } 950 | func ConstTruncOrBitCast(v Value, t Type) (rv Value) { 951 | rv.C = C.LLVMConstTruncOrBitCast(v.C, t.C) 952 | return 953 | } 954 | func ConstPointerCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPointerCast(v.C, t.C); return } 955 | func ConstExtractElement(vec, i Value) (rv Value) { 956 | rv.C = C.LLVMConstExtractElement(vec.C, i.C) 957 | return 958 | } 959 | func ConstInsertElement(vec, elem, i Value) (rv Value) { 960 | rv.C = C.LLVMConstInsertElement(vec.C, elem.C, i.C) 961 | return 962 | } 963 | func ConstShuffleVector(veca, vecb, mask Value) (rv Value) { 964 | rv.C = C.LLVMConstShuffleVector(veca.C, vecb.C, mask.C) 965 | return 966 | } 967 | 968 | func BlockAddress(f Value, bb BasicBlock) (v Value) { 969 | v.C = C.LLVMBlockAddress(f.C, bb.C) 970 | return 971 | } 972 | 973 | // Operations on global variables, functions, and aliases (globals) 974 | func (v Value) GlobalParent() (m Module) { m.C = C.LLVMGetGlobalParent(v.C); return } 975 | func (v Value) IsDeclaration() bool { return C.LLVMIsDeclaration(v.C) != 0 } 976 | func (v Value) Linkage() Linkage { return Linkage(C.LLVMGetLinkage(v.C)) } 977 | func (v Value) SetLinkage(l Linkage) { C.LLVMSetLinkage(v.C, C.LLVMLinkage(l)) } 978 | func (v Value) Section() string { return C.GoString(C.LLVMGetSection(v.C)) } 979 | func (v Value) SetSection(str string) { 980 | cstr := C.CString(str) 981 | defer C.free(unsafe.Pointer(cstr)) 982 | C.LLVMSetSection(v.C, cstr) 983 | } 984 | func (v Value) Visibility() Visibility { return Visibility(C.LLVMGetVisibility(v.C)) } 985 | func (v Value) SetVisibility(vi Visibility) { C.LLVMSetVisibility(v.C, C.LLVMVisibility(vi)) } 986 | func (v Value) Alignment() int { return int(C.LLVMGetAlignment(v.C)) } 987 | func (v Value) SetAlignment(a int) { C.LLVMSetAlignment(v.C, C.unsigned(a)) } 988 | func (v Value) SetUnnamedAddr(ua bool) { C.LLVMSetUnnamedAddr(v.C, boolToLLVMBool(ua)) } 989 | func (v Value) GlobalValueType() (t Type) { t.C = C.LLVMGlobalGetValueType(v.C); return } 990 | 991 | // Operations on global variables 992 | func AddGlobal(m Module, t Type, name string) (v Value) { 993 | cname := C.CString(name) 994 | defer C.free(unsafe.Pointer(cname)) 995 | v.C = C.LLVMAddGlobal(m.C, t.C, cname) 996 | return 997 | } 998 | func AddGlobalInAddressSpace(m Module, t Type, name string, addressSpace int) (v Value) { 999 | cname := C.CString(name) 1000 | defer C.free(unsafe.Pointer(cname)) 1001 | v.C = C.LLVMAddGlobalInAddressSpace(m.C, t.C, cname, C.unsigned(addressSpace)) 1002 | return 1003 | } 1004 | func (m Module) NamedGlobal(name string) (v Value) { 1005 | cname := C.CString(name) 1006 | defer C.free(unsafe.Pointer(cname)) 1007 | v.C = C.LLVMGetNamedGlobal(m.C, cname) 1008 | return 1009 | } 1010 | 1011 | func (m Module) FirstGlobal() (v Value) { v.C = C.LLVMGetFirstGlobal(m.C); return } 1012 | func (m Module) LastGlobal() (v Value) { v.C = C.LLVMGetLastGlobal(m.C); return } 1013 | func NextGlobal(v Value) (rv Value) { rv.C = C.LLVMGetNextGlobal(v.C); return } 1014 | func PrevGlobal(v Value) (rv Value) { rv.C = C.LLVMGetPreviousGlobal(v.C); return } 1015 | func (v Value) EraseFromParentAsGlobal() { C.LLVMDeleteGlobal(v.C) } 1016 | func (v Value) Initializer() (rv Value) { rv.C = C.LLVMGetInitializer(v.C); return } 1017 | func (v Value) SetInitializer(cv Value) { C.LLVMSetInitializer(v.C, cv.C) } 1018 | func (v Value) IsThreadLocal() bool { return C.LLVMIsThreadLocal(v.C) != 0 } 1019 | func (v Value) SetThreadLocal(tl bool) { C.LLVMSetThreadLocal(v.C, boolToLLVMBool(tl)) } 1020 | func (v Value) IsGlobalConstant() bool { return C.LLVMIsGlobalConstant(v.C) != 0 } 1021 | func (v Value) SetGlobalConstant(gc bool) { C.LLVMSetGlobalConstant(v.C, boolToLLVMBool(gc)) } 1022 | func (v Value) IsVolatile() bool { return C.LLVMGetVolatile(v.C) != 0 } 1023 | func (v Value) SetVolatile(volatile bool) { C.LLVMSetVolatile(v.C, boolToLLVMBool(volatile)) } 1024 | func (v Value) Ordering() AtomicOrdering { return AtomicOrdering(C.LLVMGetOrdering(v.C)) } 1025 | func (v Value) SetOrdering(ordering AtomicOrdering) { 1026 | C.LLVMSetOrdering(v.C, C.LLVMAtomicOrdering(ordering)) 1027 | } 1028 | func (v Value) IsAtomicSingleThread() bool { return C.LLVMIsAtomicSingleThread(v.C) != 0 } 1029 | func (v Value) SetAtomicSingleThread(singleThread bool) { 1030 | C.LLVMSetAtomicSingleThread(v.C, boolToLLVMBool(singleThread)) 1031 | } 1032 | func (v Value) CmpXchgSuccessOrdering() AtomicOrdering { 1033 | return AtomicOrdering(C.LLVMGetCmpXchgSuccessOrdering(v.C)) 1034 | } 1035 | func (v Value) SetCmpXchgSuccessOrdering(ordering AtomicOrdering) { 1036 | C.LLVMSetCmpXchgSuccessOrdering(v.C, C.LLVMAtomicOrdering(ordering)) 1037 | } 1038 | func (v Value) CmpXchgFailureOrdering() AtomicOrdering { 1039 | return AtomicOrdering(C.LLVMGetCmpXchgFailureOrdering(v.C)) 1040 | } 1041 | func (v Value) SetCmpXchgFailureOrdering(ordering AtomicOrdering) { 1042 | C.LLVMSetCmpXchgFailureOrdering(v.C, C.LLVMAtomicOrdering(ordering)) 1043 | } 1044 | 1045 | // Operations on aliases 1046 | func AddAlias(m Module, t Type, addressSpace int, aliasee Value, name string) (v Value) { 1047 | cname := C.CString(name) 1048 | defer C.free(unsafe.Pointer(cname)) 1049 | v.C = C.LLVMAddAlias2(m.C, t.C, C.unsigned(addressSpace), aliasee.C, cname) 1050 | return 1051 | } 1052 | 1053 | // Operations on comdat 1054 | func (m Module) Comdat(name string) (c Comdat) { 1055 | cname := C.CString(name) 1056 | defer C.free(unsafe.Pointer(cname)) 1057 | c.C = C.LLVMGetOrInsertComdat(m.C, cname) 1058 | return 1059 | } 1060 | 1061 | func (v Value) Comdat() (c Comdat) { c.C = C.LLVMGetComdat(v.C); return } 1062 | func (v Value) SetComdat(c Comdat) { C.LLVMSetComdat(v.C, c.C) } 1063 | 1064 | func (c Comdat) SelectionKind() ComdatSelectionKind { 1065 | return ComdatSelectionKind(C.LLVMGetComdatSelectionKind(c.C)) 1066 | } 1067 | 1068 | func (c Comdat) SetSelectionKind(k ComdatSelectionKind) { 1069 | C.LLVMSetComdatSelectionKind(c.C, (C.LLVMComdatSelectionKind)(k)) 1070 | } 1071 | 1072 | // Operations on functions 1073 | func AddFunction(m Module, name string, ft Type) (v Value) { 1074 | cname := C.CString(name) 1075 | defer C.free(unsafe.Pointer(cname)) 1076 | v.C = C.LLVMAddFunction(m.C, cname, ft.C) 1077 | return 1078 | } 1079 | 1080 | func (m Module) NamedFunction(name string) (v Value) { 1081 | cname := C.CString(name) 1082 | defer C.free(unsafe.Pointer(cname)) 1083 | v.C = C.LLVMGetNamedFunction(m.C, cname) 1084 | return 1085 | } 1086 | 1087 | func (m Module) FirstFunction() (v Value) { v.C = C.LLVMGetFirstFunction(m.C); return } 1088 | func (m Module) LastFunction() (v Value) { v.C = C.LLVMGetLastFunction(m.C); return } 1089 | func NextFunction(v Value) (rv Value) { rv.C = C.LLVMGetNextFunction(v.C); return } 1090 | func PrevFunction(v Value) (rv Value) { rv.C = C.LLVMGetPreviousFunction(v.C); return } 1091 | func (v Value) EraseFromParentAsFunction() { C.LLVMDeleteFunction(v.C) } 1092 | func (v Value) IntrinsicID() int { return int(C.LLVMGetIntrinsicID(v.C)) } 1093 | func (v Value) FunctionCallConv() CallConv { 1094 | return CallConv(C.LLVMCallConv(C.LLVMGetFunctionCallConv(v.C))) 1095 | } 1096 | func (v Value) SetFunctionCallConv(cc CallConv) { C.LLVMSetFunctionCallConv(v.C, C.unsigned(cc)) } 1097 | func (v Value) GC() string { return C.GoString(C.LLVMGetGC(v.C)) } 1098 | func (v Value) SetGC(name string) { 1099 | cname := C.CString(name) 1100 | defer C.free(unsafe.Pointer(cname)) 1101 | C.LLVMSetGC(v.C, cname) 1102 | } 1103 | func (v Value) AddAttributeAtIndex(i int, a Attribute) { 1104 | C.LLVMAddAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), a.C) 1105 | } 1106 | func (v Value) AddFunctionAttr(a Attribute) { 1107 | v.AddAttributeAtIndex(C.LLVMAttributeFunctionIndex, a) 1108 | } 1109 | func (v Value) GetEnumAttributeAtIndex(i int, kind uint) (a Attribute) { 1110 | a.C = C.LLVMGetEnumAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind)) 1111 | return 1112 | } 1113 | func (v Value) GetEnumFunctionAttribute(kind uint) Attribute { 1114 | return v.GetEnumAttributeAtIndex(C.LLVMAttributeFunctionIndex, kind) 1115 | } 1116 | func (v Value) GetStringAttributeAtIndex(i int, kind string) (a Attribute) { 1117 | ckind := C.CString(kind) 1118 | defer C.free(unsafe.Pointer(ckind)) 1119 | a.C = C.LLVMGetStringAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), 1120 | ckind, C.unsigned(len(kind))) 1121 | return 1122 | } 1123 | func (v Value) RemoveEnumAttributeAtIndex(i int, kind uint) { 1124 | C.LLVMRemoveEnumAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind)) 1125 | } 1126 | func (v Value) RemoveEnumFunctionAttribute(kind uint) { 1127 | v.RemoveEnumAttributeAtIndex(C.LLVMAttributeFunctionIndex, kind) 1128 | } 1129 | func (v Value) RemoveStringAttributeAtIndex(i int, kind string) { 1130 | ckind := C.CString(kind) 1131 | defer C.free(unsafe.Pointer(ckind)) 1132 | C.LLVMRemoveStringAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), 1133 | ckind, C.unsigned(len(kind))) 1134 | } 1135 | func (v Value) AddTargetDependentFunctionAttr(attr, value string) { 1136 | cattr := C.CString(attr) 1137 | defer C.free(unsafe.Pointer(cattr)) 1138 | cvalue := C.CString(value) 1139 | defer C.free(unsafe.Pointer(cvalue)) 1140 | C.LLVMAddTargetDependentFunctionAttr(v.C, cattr, cvalue) 1141 | } 1142 | func (v Value) SetPersonality(p Value) { 1143 | C.LLVMSetPersonalityFn(v.C, p.C) 1144 | } 1145 | 1146 | // Operations on parameters 1147 | func (v Value) ParamsCount() int { return int(C.LLVMCountParams(v.C)) } 1148 | func (v Value) Params() []Value { 1149 | out := make([]Value, v.ParamsCount()) 1150 | if len(out) > 0 { 1151 | C.LLVMGetParams(v.C, llvmValueRefPtr(&out[0])) 1152 | } 1153 | return out 1154 | } 1155 | func (v Value) Param(i int) (rv Value) { rv.C = C.LLVMGetParam(v.C, C.unsigned(i)); return } 1156 | func (v Value) ParamParent() (rv Value) { rv.C = C.LLVMGetParamParent(v.C); return } 1157 | func (v Value) FirstParam() (rv Value) { rv.C = C.LLVMGetFirstParam(v.C); return } 1158 | func (v Value) LastParam() (rv Value) { rv.C = C.LLVMGetLastParam(v.C); return } 1159 | func NextParam(v Value) (rv Value) { rv.C = C.LLVMGetNextParam(v.C); return } 1160 | func PrevParam(v Value) (rv Value) { rv.C = C.LLVMGetPreviousParam(v.C); return } 1161 | func (v Value) SetParamAlignment(align int) { C.LLVMSetParamAlignment(v.C, C.unsigned(align)) } 1162 | 1163 | // Operations on basic blocks 1164 | func (bb BasicBlock) AsValue() (v Value) { v.C = C.LLVMBasicBlockAsValue(bb.C); return } 1165 | func (v Value) IsBasicBlock() bool { return C.LLVMValueIsBasicBlock(v.C) != 0 } 1166 | func (v Value) AsBasicBlock() (bb BasicBlock) { bb.C = C.LLVMValueAsBasicBlock(v.C); return } 1167 | func (bb BasicBlock) Parent() (v Value) { v.C = C.LLVMGetBasicBlockParent(bb.C); return } 1168 | func (v Value) BasicBlocksCount() int { return int(C.LLVMCountBasicBlocks(v.C)) } 1169 | func (v Value) BasicBlocks() []BasicBlock { 1170 | out := make([]BasicBlock, v.BasicBlocksCount()) 1171 | C.LLVMGetBasicBlocks(v.C, llvmBasicBlockRefPtr(&out[0])) 1172 | return out 1173 | } 1174 | func (v Value) FirstBasicBlock() (bb BasicBlock) { 1175 | bb.C = C.LLVMGetFirstBasicBlock(v.C) 1176 | return 1177 | } 1178 | func (v Value) LastBasicBlock() (bb BasicBlock) { 1179 | bb.C = C.LLVMGetLastBasicBlock(v.C) 1180 | return 1181 | } 1182 | func NextBasicBlock(bb BasicBlock) (rbb BasicBlock) { 1183 | rbb.C = C.LLVMGetNextBasicBlock(bb.C) 1184 | return 1185 | } 1186 | func PrevBasicBlock(bb BasicBlock) (rbb BasicBlock) { 1187 | rbb.C = C.LLVMGetPreviousBasicBlock(bb.C) 1188 | return 1189 | } 1190 | func (v Value) EntryBasicBlock() (bb BasicBlock) { 1191 | bb.C = C.LLVMGetEntryBasicBlock(v.C) 1192 | return 1193 | } 1194 | func (c Context) AddBasicBlock(f Value, name string) (bb BasicBlock) { 1195 | cname := C.CString(name) 1196 | defer C.free(unsafe.Pointer(cname)) 1197 | bb.C = C.LLVMAppendBasicBlockInContext(c.C, f.C, cname) 1198 | return 1199 | } 1200 | func (c Context) InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) { 1201 | cname := C.CString(name) 1202 | defer C.free(unsafe.Pointer(cname)) 1203 | bb.C = C.LLVMInsertBasicBlockInContext(c.C, ref.C, cname) 1204 | return 1205 | } 1206 | func AddBasicBlock(f Value, name string) (bb BasicBlock) { 1207 | cname := C.CString(name) 1208 | defer C.free(unsafe.Pointer(cname)) 1209 | bb.C = C.LLVMAppendBasicBlock(f.C, cname) 1210 | return 1211 | } 1212 | func InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) { 1213 | cname := C.CString(name) 1214 | defer C.free(unsafe.Pointer(cname)) 1215 | bb.C = C.LLVMInsertBasicBlock(ref.C, cname) 1216 | return 1217 | } 1218 | func (bb BasicBlock) EraseFromParent() { C.LLVMDeleteBasicBlock(bb.C) } 1219 | func (bb BasicBlock) MoveBefore(pos BasicBlock) { C.LLVMMoveBasicBlockBefore(bb.C, pos.C) } 1220 | func (bb BasicBlock) MoveAfter(pos BasicBlock) { C.LLVMMoveBasicBlockAfter(bb.C, pos.C) } 1221 | 1222 | // Operations on instructions 1223 | func (v Value) EraseFromParentAsInstruction() { C.LLVMInstructionEraseFromParent(v.C) } 1224 | func (v Value) RemoveFromParentAsInstruction() { C.LLVMInstructionRemoveFromParent(v.C) } 1225 | func (v Value) InstructionParent() (bb BasicBlock) { bb.C = C.LLVMGetInstructionParent(v.C); return } 1226 | func (v Value) InstructionDebugLoc() (md Metadata) { md.C = C.LLVMInstructionGetDebugLoc(v.C); return } 1227 | func (v Value) InstructionSetDebugLoc(md Metadata) { C.LLVMInstructionSetDebugLoc(v.C, md.C) } 1228 | func (bb BasicBlock) FirstInstruction() (v Value) { v.C = C.LLVMGetFirstInstruction(bb.C); return } 1229 | func (bb BasicBlock) LastInstruction() (v Value) { v.C = C.LLVMGetLastInstruction(bb.C); return } 1230 | func NextInstruction(v Value) (rv Value) { rv.C = C.LLVMGetNextInstruction(v.C); return } 1231 | func PrevInstruction(v Value) (rv Value) { rv.C = C.LLVMGetPreviousInstruction(v.C); return } 1232 | 1233 | // Operations on call sites 1234 | func (v Value) SetInstructionCallConv(cc CallConv) { 1235 | C.LLVMSetInstructionCallConv(v.C, C.unsigned(cc)) 1236 | } 1237 | func (v Value) InstructionCallConv() CallConv { 1238 | return CallConv(C.LLVMCallConv(C.LLVMGetInstructionCallConv(v.C))) 1239 | } 1240 | func (v Value) AddCallSiteAttribute(i int, a Attribute) { 1241 | C.LLVMAddCallSiteAttribute(v.C, C.LLVMAttributeIndex(i), a.C) 1242 | } 1243 | func (v Value) GetCallSiteEnumAttribute(i int, kind uint) (a Attribute) { 1244 | a.C = C.LLVMGetCallSiteEnumAttribute(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind)) 1245 | return 1246 | } 1247 | func (v Value) GetCallSiteStringAttribute(i int, kind string) (a Attribute) { 1248 | ckind := C.CString(kind) 1249 | defer C.free(unsafe.Pointer(ckind)) 1250 | a.C = C.LLVMGetCallSiteStringAttribute(v.C, C.LLVMAttributeIndex(i), 1251 | ckind, C.unsigned(len(kind))) 1252 | return 1253 | } 1254 | func (v Value) SetInstrParamAlignment(i int, align int) { 1255 | C.LLVMSetInstrParamAlignment(v.C, C.unsigned(i), C.unsigned(align)) 1256 | } 1257 | func (v Value) CalledValue() (rv Value) { 1258 | rv.C = C.LLVMGetCalledValue(v.C) 1259 | return 1260 | } 1261 | func (v Value) CalledFunctionType() (t Type) { 1262 | t.C = C.LLVMGetCalledFunctionType(v.C) 1263 | return 1264 | } 1265 | 1266 | // Operations on call instructions (only) 1267 | func (v Value) IsTailCall() bool { return C.LLVMIsTailCall(v.C) != 0 } 1268 | func (v Value) SetTailCall(is bool) { C.LLVMSetTailCall(v.C, boolToLLVMBool(is)) } 1269 | 1270 | // Operations on phi nodes 1271 | func (v Value) AddIncoming(vals []Value, blocks []BasicBlock) { 1272 | ptr, nvals := llvmValueRefs(vals) 1273 | C.LLVMAddIncoming(v.C, ptr, llvmBasicBlockRefPtr(&blocks[0]), nvals) 1274 | } 1275 | func (v Value) IncomingCount() int { return int(C.LLVMCountIncoming(v.C)) } 1276 | func (v Value) IncomingValue(i int) (rv Value) { 1277 | rv.C = C.LLVMGetIncomingValue(v.C, C.unsigned(i)) 1278 | return 1279 | } 1280 | func (v Value) IncomingBlock(i int) (bb BasicBlock) { 1281 | bb.C = C.LLVMGetIncomingBlock(v.C, C.unsigned(i)) 1282 | return 1283 | } 1284 | 1285 | // Operations on inline assembly 1286 | func InlineAsm(t Type, asmString, constraints string, hasSideEffects, isAlignStack bool, dialect InlineAsmDialect, canThrow bool) (rv Value) { 1287 | casm := C.CString(asmString) 1288 | defer C.free(unsafe.Pointer(casm)) 1289 | cconstraints := C.CString(constraints) 1290 | defer C.free(unsafe.Pointer(cconstraints)) 1291 | rv.C = C.LLVMGoGetInlineAsm(t.C, casm, C.size_t(len(asmString)), cconstraints, C.size_t(len(constraints)), boolToLLVMBool(hasSideEffects), boolToLLVMBool(isAlignStack), C.LLVMInlineAsmDialect(dialect), boolToLLVMBool(canThrow)) 1292 | return 1293 | } 1294 | 1295 | // Operations on aggregates 1296 | func (v Value) Indices() []uint32 { 1297 | num := C.LLVMGetNumIndices(v.C) 1298 | indicesPtr := C.LLVMGetIndices(v.C) 1299 | // https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices 1300 | rawIndices := (*[1 << 20]C.uint)(unsafe.Pointer(indicesPtr))[:num:num] 1301 | indices := make([]uint32, num) 1302 | for i := range indices { 1303 | indices[i] = uint32(rawIndices[i]) 1304 | } 1305 | return indices 1306 | } 1307 | 1308 | // Operations on comparisons 1309 | func (v Value) IntPredicate() IntPredicate { return IntPredicate(C.LLVMGetICmpPredicate(v.C)) } 1310 | func (v Value) FloatPredicate() FloatPredicate { return FloatPredicate(C.LLVMGetFCmpPredicate(v.C)) } 1311 | 1312 | // Operations on GEPs 1313 | func (v Value) GEPSourceElementType() (t Type) { t.C = C.LLVMGetGEPSourceElementType(v.C); return } 1314 | 1315 | // Operations on allocas 1316 | func (v Value) AllocatedType() (t Type) { t.C = C.LLVMGetAllocatedType(v.C); return } 1317 | 1318 | //------------------------------------------------------------------------- 1319 | // llvm.Builder 1320 | //------------------------------------------------------------------------- 1321 | 1322 | // An instruction builder represents a point within a basic block, and is the 1323 | // exclusive means of building instructions using the C interface. 1324 | 1325 | func (c Context) NewBuilder() (b Builder) { b.C = C.LLVMCreateBuilderInContext(c.C); return } 1326 | func (b Builder) SetInsertPoint(block BasicBlock, instr Value) { 1327 | C.LLVMPositionBuilder(b.C, block.C, instr.C) 1328 | } 1329 | func (b Builder) SetInsertPointBefore(instr Value) { C.LLVMPositionBuilderBefore(b.C, instr.C) } 1330 | func (b Builder) SetInsertPointAtEnd(block BasicBlock) { C.LLVMPositionBuilderAtEnd(b.C, block.C) } 1331 | func (b Builder) GetInsertBlock() (bb BasicBlock) { bb.C = C.LLVMGetInsertBlock(b.C); return } 1332 | func (b Builder) ClearInsertionPoint() { C.LLVMClearInsertionPosition(b.C) } 1333 | func (b Builder) Insert(instr Value) { C.LLVMInsertIntoBuilder(b.C, instr.C) } 1334 | func (b Builder) InsertWithName(instr Value, name string) { 1335 | cname := C.CString(name) 1336 | defer C.free(unsafe.Pointer(cname)) 1337 | C.LLVMInsertIntoBuilderWithName(b.C, instr.C, cname) 1338 | } 1339 | func (b Builder) Dispose() { C.LLVMDisposeBuilder(b.C) } 1340 | 1341 | // Metadata 1342 | type DebugLoc struct { 1343 | Line, Col uint 1344 | Scope Metadata 1345 | InlinedAt Metadata 1346 | } 1347 | 1348 | func (b Builder) SetCurrentDebugLocation(line, col uint, scope, inlinedAt Metadata) { 1349 | C.LLVMGoSetCurrentDebugLocation(b.C, C.unsigned(line), C.unsigned(col), scope.C, inlinedAt.C) 1350 | } 1351 | 1352 | // Get current debug location. Please do not call this function until setting debug location with SetCurrentDebugLocation() 1353 | func (b Builder) GetCurrentDebugLocation() (loc DebugLoc) { 1354 | md := C.LLVMGoGetCurrentDebugLocation(b.C) 1355 | loc.Line = uint(md.Line) 1356 | loc.Col = uint(md.Col) 1357 | loc.Scope = Metadata{C: md.Scope} 1358 | loc.InlinedAt = Metadata{C: md.InlinedAt} 1359 | return 1360 | } 1361 | func (b Builder) SetInstDebugLocation(v Value) { C.LLVMSetInstDebugLocation(b.C, v.C) } 1362 | func (b Builder) InsertDeclare(module Module, storage Value, md Value) Value { 1363 | f := module.NamedFunction("llvm.dbg.declare") 1364 | ftyp := FunctionType(module.Context().VoidType(), []Type{storage.Type(), md.Type()}, false) 1365 | if f.IsNil() { 1366 | f = AddFunction(module, "llvm.dbg.declare", ftyp) 1367 | } 1368 | return b.CreateCall(ftyp, f, []Value{storage, md}, "") 1369 | } 1370 | 1371 | // Terminators 1372 | func (b Builder) CreateRetVoid() (rv Value) { rv.C = C.LLVMBuildRetVoid(b.C); return } 1373 | func (b Builder) CreateRet(v Value) (rv Value) { rv.C = C.LLVMBuildRet(b.C, v.C); return } 1374 | func (b Builder) CreateAggregateRet(vs []Value) (rv Value) { 1375 | ptr, nvals := llvmValueRefs(vs) 1376 | rv.C = C.LLVMBuildAggregateRet(b.C, ptr, nvals) 1377 | return 1378 | } 1379 | func (b Builder) CreateBr(bb BasicBlock) (rv Value) { rv.C = C.LLVMBuildBr(b.C, bb.C); return } 1380 | func (b Builder) CreateCondBr(ifv Value, thenb, elseb BasicBlock) (rv Value) { 1381 | rv.C = C.LLVMBuildCondBr(b.C, ifv.C, thenb.C, elseb.C) 1382 | return 1383 | } 1384 | func (b Builder) CreateSwitch(v Value, elseb BasicBlock, numCases int) (rv Value) { 1385 | rv.C = C.LLVMBuildSwitch(b.C, v.C, elseb.C, C.unsigned(numCases)) 1386 | return 1387 | } 1388 | func (b Builder) CreateIndirectBr(addr Value, numDests int) (rv Value) { 1389 | rv.C = C.LLVMBuildIndirectBr(b.C, addr.C, C.unsigned(numDests)) 1390 | return 1391 | } 1392 | func (b Builder) CreateInvoke(t Type, fn Value, args []Value, then, catch BasicBlock, name string) (rv Value) { 1393 | cname := C.CString(name) 1394 | defer C.free(unsafe.Pointer(cname)) 1395 | ptr, nvals := llvmValueRefs(args) 1396 | rv.C = C.LLVMBuildInvoke2(b.C, t.C, fn.C, ptr, nvals, then.C, catch.C, cname) 1397 | return 1398 | } 1399 | func (b Builder) CreateUnreachable() (rv Value) { rv.C = C.LLVMBuildUnreachable(b.C); return } 1400 | 1401 | // Exception Handling 1402 | 1403 | func (b Builder) CreateResume(ex Value) (v Value) { 1404 | v.C = C.LLVMBuildResume(b.C, ex.C) 1405 | return 1406 | } 1407 | 1408 | func (b Builder) CreateLandingPad(t Type, nclauses int, name string) (l Value) { 1409 | cname := C.CString(name) 1410 | defer C.free(unsafe.Pointer(cname)) 1411 | l.C = C.LLVMBuildLandingPad(b.C, t.C, nil, C.unsigned(nclauses), cname) 1412 | return l 1413 | } 1414 | 1415 | func (b Builder) CreateCleanupRet(catchpad Value, bb BasicBlock) (v Value) { 1416 | v.C = C.LLVMBuildCleanupRet(b.C, catchpad.C, bb.C) 1417 | return 1418 | } 1419 | 1420 | func (b Builder) CreateCatchRet(catchpad Value, bb BasicBlock) (v Value) { 1421 | v.C = C.LLVMBuildCatchRet(b.C, catchpad.C, bb.C) 1422 | return 1423 | } 1424 | 1425 | func (b Builder) CreateCatchPad(parentPad Value, args []Value, name string) (v Value) { 1426 | cname := C.CString(name) 1427 | defer C.free(unsafe.Pointer(cname)) 1428 | ptr, nvals := llvmValueRefs(args) 1429 | v.C = C.LLVMBuildCatchPad(b.C, parentPad.C, ptr, nvals, cname) 1430 | return 1431 | } 1432 | 1433 | func (b Builder) CreateCleanupPad(parentPad Value, args []Value, name string) (v Value) { 1434 | cname := C.CString(name) 1435 | defer C.free(unsafe.Pointer(cname)) 1436 | ptr, nvals := llvmValueRefs(args) 1437 | v.C = C.LLVMBuildCleanupPad(b.C, parentPad.C, ptr, nvals, cname) 1438 | return 1439 | } 1440 | func (b Builder) CreateCatchSwitch(parentPad Value, unwindBB BasicBlock, numHandlers int, name string) (v Value) { 1441 | cname := C.CString(name) 1442 | defer C.free(unsafe.Pointer(cname)) 1443 | v.C = C.LLVMBuildCatchSwitch(b.C, parentPad.C, unwindBB.C, C.unsigned(numHandlers), cname) 1444 | return 1445 | } 1446 | 1447 | // Add a case to the switch instruction 1448 | func (v Value) AddCase(on Value, dest BasicBlock) { C.LLVMAddCase(v.C, on.C, dest.C) } 1449 | 1450 | // Add a destination to the indirectbr instruction 1451 | func (v Value) AddDest(dest BasicBlock) { C.LLVMAddDestination(v.C, dest.C) } 1452 | 1453 | // Add a destination to the catchswitch instruction. 1454 | func (v Value) AddHandler(bb BasicBlock) { C.LLVMAddHandler(v.C, bb.C) } 1455 | 1456 | // Obtain the basic blocks acting as handlers for a catchswitch instruction. 1457 | func (v Value) GetHandlers() []BasicBlock { 1458 | num := C.LLVMGetNumHandlers(v.C) 1459 | if num == 0 { 1460 | return nil 1461 | } 1462 | blocks := make([]BasicBlock, num) 1463 | C.LLVMGetHandlers(v.C, &blocks[0].C) 1464 | return blocks 1465 | } 1466 | 1467 | // Get the parent catchswitch instruction of a catchpad instruction. 1468 | // 1469 | // This only works on catchpad instructions. 1470 | func (v Value) GetParentCatchSwitch() (rv Value) { 1471 | rv.C = C.LLVMGetParentCatchSwitch(v.C) 1472 | return 1473 | } 1474 | 1475 | // Set the parent catchswitch instruction of a catchpad instruction. 1476 | // 1477 | // This only works on llvm::CatchPadInst instructions. 1478 | func (v Value) SetParentCatchSwitch(catchSwitch Value) { 1479 | C.LLVMSetParentCatchSwitch(v.C, catchSwitch.C) 1480 | } 1481 | 1482 | // Arithmetic 1483 | func (b Builder) CreateAdd(lhs, rhs Value, name string) (v Value) { 1484 | cname := C.CString(name) 1485 | defer C.free(unsafe.Pointer(cname)) 1486 | v.C = C.LLVMBuildAdd(b.C, lhs.C, rhs.C, cname) 1487 | return 1488 | } 1489 | func (b Builder) CreateNSWAdd(lhs, rhs Value, name string) (v Value) { 1490 | cname := C.CString(name) 1491 | defer C.free(unsafe.Pointer(cname)) 1492 | v.C = C.LLVMBuildNSWAdd(b.C, lhs.C, rhs.C, cname) 1493 | return 1494 | } 1495 | func (b Builder) CreateNUWAdd(lhs, rhs Value, name string) (v Value) { 1496 | cname := C.CString(name) 1497 | defer C.free(unsafe.Pointer(cname)) 1498 | v.C = C.LLVMBuildNUWAdd(b.C, lhs.C, rhs.C, cname) 1499 | return 1500 | } 1501 | func (b Builder) CreateFAdd(lhs, rhs Value, name string) (v Value) { 1502 | cname := C.CString(name) 1503 | defer C.free(unsafe.Pointer(cname)) 1504 | v.C = C.LLVMBuildFAdd(b.C, lhs.C, rhs.C, cname) 1505 | return 1506 | } 1507 | func (b Builder) CreateSub(lhs, rhs Value, name string) (v Value) { 1508 | cname := C.CString(name) 1509 | defer C.free(unsafe.Pointer(cname)) 1510 | v.C = C.LLVMBuildSub(b.C, lhs.C, rhs.C, cname) 1511 | return 1512 | } 1513 | func (b Builder) CreateNSWSub(lhs, rhs Value, name string) (v Value) { 1514 | cname := C.CString(name) 1515 | defer C.free(unsafe.Pointer(cname)) 1516 | v.C = C.LLVMBuildNSWSub(b.C, lhs.C, rhs.C, cname) 1517 | return 1518 | } 1519 | func (b Builder) CreateNUWSub(lhs, rhs Value, name string) (v Value) { 1520 | cname := C.CString(name) 1521 | defer C.free(unsafe.Pointer(cname)) 1522 | v.C = C.LLVMBuildNUWSub(b.C, lhs.C, rhs.C, cname) 1523 | return 1524 | } 1525 | func (b Builder) CreateFSub(lhs, rhs Value, name string) (v Value) { 1526 | cname := C.CString(name) 1527 | v.C = C.LLVMBuildFSub(b.C, lhs.C, rhs.C, cname) 1528 | C.free(unsafe.Pointer(cname)) 1529 | return 1530 | } 1531 | func (b Builder) CreateMul(lhs, rhs Value, name string) (v Value) { 1532 | cname := C.CString(name) 1533 | defer C.free(unsafe.Pointer(cname)) 1534 | v.C = C.LLVMBuildMul(b.C, lhs.C, rhs.C, cname) 1535 | return 1536 | } 1537 | func (b Builder) CreateNSWMul(lhs, rhs Value, name string) (v Value) { 1538 | cname := C.CString(name) 1539 | defer C.free(unsafe.Pointer(cname)) 1540 | v.C = C.LLVMBuildNSWMul(b.C, lhs.C, rhs.C, cname) 1541 | return 1542 | } 1543 | func (b Builder) CreateNUWMul(lhs, rhs Value, name string) (v Value) { 1544 | cname := C.CString(name) 1545 | defer C.free(unsafe.Pointer(cname)) 1546 | v.C = C.LLVMBuildNUWMul(b.C, lhs.C, rhs.C, cname) 1547 | return 1548 | } 1549 | func (b Builder) CreateFMul(lhs, rhs Value, name string) (v Value) { 1550 | cname := C.CString(name) 1551 | defer C.free(unsafe.Pointer(cname)) 1552 | v.C = C.LLVMBuildFMul(b.C, lhs.C, rhs.C, cname) 1553 | return 1554 | } 1555 | func (b Builder) CreateUDiv(lhs, rhs Value, name string) (v Value) { 1556 | cname := C.CString(name) 1557 | defer C.free(unsafe.Pointer(cname)) 1558 | v.C = C.LLVMBuildUDiv(b.C, lhs.C, rhs.C, cname) 1559 | return 1560 | } 1561 | func (b Builder) CreateSDiv(lhs, rhs Value, name string) (v Value) { 1562 | cname := C.CString(name) 1563 | defer C.free(unsafe.Pointer(cname)) 1564 | v.C = C.LLVMBuildSDiv(b.C, lhs.C, rhs.C, cname) 1565 | return 1566 | } 1567 | func (b Builder) CreateExactSDiv(lhs, rhs Value, name string) (v Value) { 1568 | cname := C.CString(name) 1569 | defer C.free(unsafe.Pointer(cname)) 1570 | v.C = C.LLVMBuildExactSDiv(b.C, lhs.C, rhs.C, cname) 1571 | return 1572 | } 1573 | func (b Builder) CreateFDiv(lhs, rhs Value, name string) (v Value) { 1574 | cname := C.CString(name) 1575 | defer C.free(unsafe.Pointer(cname)) 1576 | v.C = C.LLVMBuildFDiv(b.C, lhs.C, rhs.C, cname) 1577 | return 1578 | } 1579 | func (b Builder) CreateURem(lhs, rhs Value, name string) (v Value) { 1580 | cname := C.CString(name) 1581 | defer C.free(unsafe.Pointer(cname)) 1582 | v.C = C.LLVMBuildURem(b.C, lhs.C, rhs.C, cname) 1583 | return 1584 | } 1585 | func (b Builder) CreateSRem(lhs, rhs Value, name string) (v Value) { 1586 | cname := C.CString(name) 1587 | defer C.free(unsafe.Pointer(cname)) 1588 | v.C = C.LLVMBuildSRem(b.C, lhs.C, rhs.C, cname) 1589 | return 1590 | } 1591 | func (b Builder) CreateFRem(lhs, rhs Value, name string) (v Value) { 1592 | cname := C.CString(name) 1593 | defer C.free(unsafe.Pointer(cname)) 1594 | v.C = C.LLVMBuildFRem(b.C, lhs.C, rhs.C, cname) 1595 | return 1596 | } 1597 | func (b Builder) CreateShl(lhs, rhs Value, name string) (v Value) { 1598 | cname := C.CString(name) 1599 | defer C.free(unsafe.Pointer(cname)) 1600 | v.C = C.LLVMBuildShl(b.C, lhs.C, rhs.C, cname) 1601 | return 1602 | } 1603 | func (b Builder) CreateLShr(lhs, rhs Value, name string) (v Value) { 1604 | cname := C.CString(name) 1605 | defer C.free(unsafe.Pointer(cname)) 1606 | v.C = C.LLVMBuildLShr(b.C, lhs.C, rhs.C, cname) 1607 | return 1608 | } 1609 | func (b Builder) CreateAShr(lhs, rhs Value, name string) (v Value) { 1610 | cname := C.CString(name) 1611 | defer C.free(unsafe.Pointer(cname)) 1612 | v.C = C.LLVMBuildAShr(b.C, lhs.C, rhs.C, cname) 1613 | return 1614 | } 1615 | func (b Builder) CreateAnd(lhs, rhs Value, name string) (v Value) { 1616 | cname := C.CString(name) 1617 | defer C.free(unsafe.Pointer(cname)) 1618 | v.C = C.LLVMBuildAnd(b.C, lhs.C, rhs.C, cname) 1619 | return 1620 | } 1621 | func (b Builder) CreateOr(lhs, rhs Value, name string) (v Value) { 1622 | cname := C.CString(name) 1623 | defer C.free(unsafe.Pointer(cname)) 1624 | v.C = C.LLVMBuildOr(b.C, lhs.C, rhs.C, cname) 1625 | return 1626 | } 1627 | func (b Builder) CreateXor(lhs, rhs Value, name string) (v Value) { 1628 | cname := C.CString(name) 1629 | defer C.free(unsafe.Pointer(cname)) 1630 | v.C = C.LLVMBuildXor(b.C, lhs.C, rhs.C, cname) 1631 | return 1632 | } 1633 | func (b Builder) CreateBinOp(op Opcode, lhs, rhs Value, name string) (v Value) { 1634 | cname := C.CString(name) 1635 | defer C.free(unsafe.Pointer(cname)) 1636 | v.C = C.LLVMBuildBinOp(b.C, C.LLVMOpcode(op), lhs.C, rhs.C, cname) 1637 | return 1638 | } 1639 | func (b Builder) CreateNeg(v Value, name string) (rv Value) { 1640 | cname := C.CString(name) 1641 | defer C.free(unsafe.Pointer(cname)) 1642 | rv.C = C.LLVMBuildNeg(b.C, v.C, cname) 1643 | return 1644 | } 1645 | func (b Builder) CreateNSWNeg(v Value, name string) (rv Value) { 1646 | cname := C.CString(name) 1647 | defer C.free(unsafe.Pointer(cname)) 1648 | rv.C = C.LLVMBuildNSWNeg(b.C, v.C, cname) 1649 | return 1650 | } 1651 | func (b Builder) CreateFNeg(v Value, name string) (rv Value) { 1652 | cname := C.CString(name) 1653 | defer C.free(unsafe.Pointer(cname)) 1654 | rv.C = C.LLVMBuildFNeg(b.C, v.C, cname) 1655 | return 1656 | } 1657 | func (b Builder) CreateNot(v Value, name string) (rv Value) { 1658 | cname := C.CString(name) 1659 | defer C.free(unsafe.Pointer(cname)) 1660 | rv.C = C.LLVMBuildNot(b.C, v.C, cname) 1661 | return 1662 | } 1663 | 1664 | // Memory 1665 | 1666 | func (b Builder) CreateMalloc(t Type, name string) (v Value) { 1667 | cname := C.CString(name) 1668 | defer C.free(unsafe.Pointer(cname)) 1669 | v.C = C.LLVMBuildMalloc(b.C, t.C, cname) 1670 | return 1671 | } 1672 | func (b Builder) CreateArrayMalloc(t Type, val Value, name string) (v Value) { 1673 | cname := C.CString(name) 1674 | defer C.free(unsafe.Pointer(cname)) 1675 | v.C = C.LLVMBuildArrayMalloc(b.C, t.C, val.C, cname) 1676 | return 1677 | } 1678 | func (b Builder) CreateAlloca(t Type, name string) (v Value) { 1679 | cname := C.CString(name) 1680 | defer C.free(unsafe.Pointer(cname)) 1681 | v.C = C.LLVMBuildAlloca(b.C, t.C, cname) 1682 | return 1683 | } 1684 | func (b Builder) CreateArrayAlloca(t Type, val Value, name string) (v Value) { 1685 | cname := C.CString(name) 1686 | defer C.free(unsafe.Pointer(cname)) 1687 | v.C = C.LLVMBuildArrayAlloca(b.C, t.C, val.C, cname) 1688 | return 1689 | } 1690 | func (b Builder) CreateFree(p Value) (v Value) { 1691 | v.C = C.LLVMBuildFree(b.C, p.C) 1692 | return 1693 | } 1694 | func (b Builder) CreateLoad(t Type, p Value, name string) (v Value) { 1695 | cname := C.CString(name) 1696 | defer C.free(unsafe.Pointer(cname)) 1697 | v.C = C.LLVMBuildLoad2(b.C, t.C, p.C, cname) 1698 | return 1699 | } 1700 | func (b Builder) CreateStore(val Value, p Value) (v Value) { 1701 | v.C = C.LLVMBuildStore(b.C, val.C, p.C) 1702 | return 1703 | } 1704 | func (b Builder) CreateGEP(t Type, p Value, indices []Value, name string) (v Value) { 1705 | cname := C.CString(name) 1706 | defer C.free(unsafe.Pointer(cname)) 1707 | ptr, nvals := llvmValueRefs(indices) 1708 | v.C = C.LLVMBuildGEP2(b.C, t.C, p.C, ptr, nvals, cname) 1709 | return 1710 | } 1711 | func (b Builder) CreateInBoundsGEP(t Type, p Value, indices []Value, name string) (v Value) { 1712 | cname := C.CString(name) 1713 | defer C.free(unsafe.Pointer(cname)) 1714 | ptr, nvals := llvmValueRefs(indices) 1715 | v.C = C.LLVMBuildInBoundsGEP2(b.C, t.C, p.C, ptr, nvals, cname) 1716 | return 1717 | } 1718 | func (b Builder) CreateStructGEP(t Type, p Value, i int, name string) (v Value) { 1719 | cname := C.CString(name) 1720 | defer C.free(unsafe.Pointer(cname)) 1721 | v.C = C.LLVMBuildStructGEP2(b.C, t.C, p.C, C.unsigned(i), cname) 1722 | return 1723 | } 1724 | func (b Builder) CreateGlobalString(str, name string) (v Value) { 1725 | cstr := C.CString(str) 1726 | defer C.free(unsafe.Pointer(cstr)) 1727 | cname := C.CString(name) 1728 | defer C.free(unsafe.Pointer(cname)) 1729 | v.C = C.LLVMBuildGlobalString(b.C, cstr, cname) 1730 | return 1731 | } 1732 | func (b Builder) CreateGlobalStringPtr(str, name string) (v Value) { 1733 | cstr := C.CString(str) 1734 | defer C.free(unsafe.Pointer(cstr)) 1735 | cname := C.CString(name) 1736 | defer C.free(unsafe.Pointer(cname)) 1737 | v.C = C.LLVMBuildGlobalStringPtr(b.C, cstr, cname) 1738 | return 1739 | } 1740 | func (b Builder) CreateAtomicRMW(op AtomicRMWBinOp, ptr, val Value, ordering AtomicOrdering, singleThread bool) (v Value) { 1741 | v.C = C.LLVMBuildAtomicRMW(b.C, C.LLVMAtomicRMWBinOp(op), ptr.C, val.C, C.LLVMAtomicOrdering(ordering), boolToLLVMBool(singleThread)) 1742 | return 1743 | } 1744 | func (b Builder) CreateAtomicCmpXchg(ptr, cmp, newVal Value, successOrdering, failureOrdering AtomicOrdering, singleThread bool) (v Value) { 1745 | v.C = C.LLVMBuildAtomicCmpXchg(b.C, ptr.C, cmp.C, newVal.C, C.LLVMAtomicOrdering(successOrdering), C.LLVMAtomicOrdering(failureOrdering), boolToLLVMBool(singleThread)) 1746 | return 1747 | } 1748 | 1749 | // Casts 1750 | func (b Builder) CreateTrunc(val Value, t Type, name string) (v Value) { 1751 | cname := C.CString(name) 1752 | defer C.free(unsafe.Pointer(cname)) 1753 | v.C = C.LLVMBuildTrunc(b.C, val.C, t.C, cname) 1754 | return 1755 | } 1756 | func (b Builder) CreateZExt(val Value, t Type, name string) (v Value) { 1757 | cname := C.CString(name) 1758 | defer C.free(unsafe.Pointer(cname)) 1759 | v.C = C.LLVMBuildZExt(b.C, val.C, t.C, cname) 1760 | return 1761 | } 1762 | func (b Builder) CreateSExt(val Value, t Type, name string) (v Value) { 1763 | cname := C.CString(name) 1764 | defer C.free(unsafe.Pointer(cname)) 1765 | v.C = C.LLVMBuildSExt(b.C, val.C, t.C, cname) 1766 | return 1767 | } 1768 | func (b Builder) CreateFPToUI(val Value, t Type, name string) (v Value) { 1769 | cname := C.CString(name) 1770 | defer C.free(unsafe.Pointer(cname)) 1771 | v.C = C.LLVMBuildFPToUI(b.C, val.C, t.C, cname) 1772 | return 1773 | } 1774 | func (b Builder) CreateFPToSI(val Value, t Type, name string) (v Value) { 1775 | cname := C.CString(name) 1776 | defer C.free(unsafe.Pointer(cname)) 1777 | v.C = C.LLVMBuildFPToSI(b.C, val.C, t.C, cname) 1778 | return 1779 | } 1780 | func (b Builder) CreateUIToFP(val Value, t Type, name string) (v Value) { 1781 | cname := C.CString(name) 1782 | defer C.free(unsafe.Pointer(cname)) 1783 | v.C = C.LLVMBuildUIToFP(b.C, val.C, t.C, cname) 1784 | return 1785 | } 1786 | func (b Builder) CreateSIToFP(val Value, t Type, name string) (v Value) { 1787 | cname := C.CString(name) 1788 | defer C.free(unsafe.Pointer(cname)) 1789 | v.C = C.LLVMBuildSIToFP(b.C, val.C, t.C, cname) 1790 | return 1791 | } 1792 | func (b Builder) CreateFPTrunc(val Value, t Type, name string) (v Value) { 1793 | cname := C.CString(name) 1794 | defer C.free(unsafe.Pointer(cname)) 1795 | v.C = C.LLVMBuildFPTrunc(b.C, val.C, t.C, cname) 1796 | return 1797 | } 1798 | func (b Builder) CreateFPExt(val Value, t Type, name string) (v Value) { 1799 | cname := C.CString(name) 1800 | defer C.free(unsafe.Pointer(cname)) 1801 | v.C = C.LLVMBuildFPExt(b.C, val.C, t.C, cname) 1802 | return 1803 | } 1804 | func (b Builder) CreatePtrToInt(val Value, t Type, name string) (v Value) { 1805 | cname := C.CString(name) 1806 | defer C.free(unsafe.Pointer(cname)) 1807 | v.C = C.LLVMBuildPtrToInt(b.C, val.C, t.C, cname) 1808 | return 1809 | } 1810 | func (b Builder) CreateIntToPtr(val Value, t Type, name string) (v Value) { 1811 | cname := C.CString(name) 1812 | defer C.free(unsafe.Pointer(cname)) 1813 | v.C = C.LLVMBuildIntToPtr(b.C, val.C, t.C, cname) 1814 | return 1815 | } 1816 | func (b Builder) CreateBitCast(val Value, t Type, name string) (v Value) { 1817 | cname := C.CString(name) 1818 | defer C.free(unsafe.Pointer(cname)) 1819 | v.C = C.LLVMBuildBitCast(b.C, val.C, t.C, cname) 1820 | return 1821 | } 1822 | func (b Builder) CreateZExtOrBitCast(val Value, t Type, name string) (v Value) { 1823 | cname := C.CString(name) 1824 | defer C.free(unsafe.Pointer(cname)) 1825 | v.C = C.LLVMBuildZExtOrBitCast(b.C, val.C, t.C, cname) 1826 | return 1827 | } 1828 | func (b Builder) CreateSExtOrBitCast(val Value, t Type, name string) (v Value) { 1829 | cname := C.CString(name) 1830 | defer C.free(unsafe.Pointer(cname)) 1831 | v.C = C.LLVMBuildSExtOrBitCast(b.C, val.C, t.C, cname) 1832 | return 1833 | } 1834 | func (b Builder) CreateTruncOrBitCast(val Value, t Type, name string) (v Value) { 1835 | cname := C.CString(name) 1836 | defer C.free(unsafe.Pointer(cname)) 1837 | v.C = C.LLVMBuildTruncOrBitCast(b.C, val.C, t.C, cname) 1838 | return 1839 | } 1840 | func (b Builder) CreateCast(val Value, op Opcode, t Type, name string) (v Value) { 1841 | cname := C.CString(name) 1842 | defer C.free(unsafe.Pointer(cname)) 1843 | v.C = C.LLVMBuildCast(b.C, C.LLVMOpcode(op), val.C, t.C, cname) 1844 | return 1845 | } // 1846 | func (b Builder) CreatePointerCast(val Value, t Type, name string) (v Value) { 1847 | cname := C.CString(name) 1848 | defer C.free(unsafe.Pointer(cname)) 1849 | v.C = C.LLVMBuildPointerCast(b.C, val.C, t.C, cname) 1850 | return 1851 | } 1852 | func (b Builder) CreateIntCast(val Value, t Type, name string) (v Value) { 1853 | cname := C.CString(name) 1854 | defer C.free(unsafe.Pointer(cname)) 1855 | v.C = C.LLVMBuildIntCast(b.C, val.C, t.C, cname) 1856 | return 1857 | } 1858 | func (b Builder) CreateFPCast(val Value, t Type, name string) (v Value) { 1859 | cname := C.CString(name) 1860 | defer C.free(unsafe.Pointer(cname)) 1861 | v.C = C.LLVMBuildFPCast(b.C, val.C, t.C, cname) 1862 | return 1863 | } 1864 | 1865 | // Comparisons 1866 | func (b Builder) CreateICmp(pred IntPredicate, lhs, rhs Value, name string) (v Value) { 1867 | cname := C.CString(name) 1868 | defer C.free(unsafe.Pointer(cname)) 1869 | v.C = C.LLVMBuildICmp(b.C, C.LLVMIntPredicate(pred), lhs.C, rhs.C, cname) 1870 | return 1871 | } 1872 | func (b Builder) CreateFCmp(pred FloatPredicate, lhs, rhs Value, name string) (v Value) { 1873 | cname := C.CString(name) 1874 | defer C.free(unsafe.Pointer(cname)) 1875 | v.C = C.LLVMBuildFCmp(b.C, C.LLVMRealPredicate(pred), lhs.C, rhs.C, cname) 1876 | return 1877 | } 1878 | 1879 | // Miscellaneous instructions 1880 | func (b Builder) CreatePHI(t Type, name string) (v Value) { 1881 | cname := C.CString(name) 1882 | defer C.free(unsafe.Pointer(cname)) 1883 | v.C = C.LLVMBuildPhi(b.C, t.C, cname) 1884 | return 1885 | } 1886 | func (b Builder) CreateCall(t Type, fn Value, args []Value, name string) (v Value) { 1887 | cname := C.CString(name) 1888 | defer C.free(unsafe.Pointer(cname)) 1889 | ptr, nvals := llvmValueRefs(args) 1890 | v.C = C.LLVMBuildCall2(b.C, t.C, fn.C, ptr, nvals, cname) 1891 | return 1892 | } 1893 | 1894 | func (b Builder) CreateSelect(ifv, thenv, elsev Value, name string) (v Value) { 1895 | cname := C.CString(name) 1896 | defer C.free(unsafe.Pointer(cname)) 1897 | v.C = C.LLVMBuildSelect(b.C, ifv.C, thenv.C, elsev.C, cname) 1898 | return 1899 | } 1900 | 1901 | func (b Builder) CreateVAArg(list Value, t Type, name string) (v Value) { 1902 | cname := C.CString(name) 1903 | defer C.free(unsafe.Pointer(cname)) 1904 | v.C = C.LLVMBuildVAArg(b.C, list.C, t.C, cname) 1905 | return 1906 | } 1907 | func (b Builder) CreateExtractElement(vec, i Value, name string) (v Value) { 1908 | cname := C.CString(name) 1909 | defer C.free(unsafe.Pointer(cname)) 1910 | v.C = C.LLVMBuildExtractElement(b.C, vec.C, i.C, cname) 1911 | return 1912 | } 1913 | func (b Builder) CreateInsertElement(vec, elt, i Value, name string) (v Value) { 1914 | cname := C.CString(name) 1915 | defer C.free(unsafe.Pointer(cname)) 1916 | v.C = C.LLVMBuildInsertElement(b.C, vec.C, elt.C, i.C, cname) 1917 | return 1918 | } 1919 | func (b Builder) CreateShuffleVector(v1, v2, mask Value, name string) (v Value) { 1920 | cname := C.CString(name) 1921 | defer C.free(unsafe.Pointer(cname)) 1922 | v.C = C.LLVMBuildShuffleVector(b.C, v1.C, v2.C, mask.C, cname) 1923 | return 1924 | } 1925 | func (b Builder) CreateExtractValue(agg Value, i int, name string) (v Value) { 1926 | cname := C.CString(name) 1927 | defer C.free(unsafe.Pointer(cname)) 1928 | v.C = C.LLVMBuildExtractValue(b.C, agg.C, C.unsigned(i), cname) 1929 | return 1930 | } 1931 | func (b Builder) CreateInsertValue(agg, elt Value, i int, name string) (v Value) { 1932 | cname := C.CString(name) 1933 | defer C.free(unsafe.Pointer(cname)) 1934 | v.C = C.LLVMBuildInsertValue(b.C, agg.C, elt.C, C.unsigned(i), cname) 1935 | return 1936 | } 1937 | 1938 | func (b Builder) CreateIsNull(val Value, name string) (v Value) { 1939 | cname := C.CString(name) 1940 | defer C.free(unsafe.Pointer(cname)) 1941 | v.C = C.LLVMBuildIsNull(b.C, val.C, cname) 1942 | return 1943 | } 1944 | func (b Builder) CreateIsNotNull(val Value, name string) (v Value) { 1945 | cname := C.CString(name) 1946 | defer C.free(unsafe.Pointer(cname)) 1947 | v.C = C.LLVMBuildIsNotNull(b.C, val.C, cname) 1948 | return 1949 | } 1950 | func (b Builder) CreatePtrDiff(t Type, lhs, rhs Value, name string) (v Value) { 1951 | cname := C.CString(name) 1952 | defer C.free(unsafe.Pointer(cname)) 1953 | v.C = C.LLVMBuildPtrDiff2(b.C, t.C, lhs.C, rhs.C, cname) 1954 | return 1955 | } 1956 | 1957 | func (l Value) AddClause(v Value) { 1958 | C.LLVMAddClause(l.C, v.C) 1959 | } 1960 | 1961 | func (l Value) SetCleanup(cleanup bool) { 1962 | C.LLVMSetCleanup(l.C, boolToLLVMBool(cleanup)) 1963 | } 1964 | 1965 | //------------------------------------------------------------------------- 1966 | // llvm.ModuleProvider 1967 | //------------------------------------------------------------------------- 1968 | 1969 | // Changes the type of M so it can be passed to FunctionPassManagers and the 1970 | // JIT. They take ModuleProviders for historical reasons. 1971 | func NewModuleProviderForModule(m Module) (mp ModuleProvider) { 1972 | mp.C = C.LLVMCreateModuleProviderForExistingModule(m.C) 1973 | return 1974 | } 1975 | 1976 | // Destroys the module M. 1977 | func (mp ModuleProvider) Dispose() { C.LLVMDisposeModuleProvider(mp.C) } 1978 | 1979 | //------------------------------------------------------------------------- 1980 | // llvm.MemoryBuffer 1981 | //------------------------------------------------------------------------- 1982 | 1983 | func NewMemoryBufferFromFile(path string) (b MemoryBuffer, err error) { 1984 | var cmsg *C.char 1985 | cpath := C.CString(path) 1986 | defer C.free(unsafe.Pointer(cpath)) 1987 | fail := C.LLVMCreateMemoryBufferWithContentsOfFile(cpath, &b.C, &cmsg) 1988 | if fail != 0 { 1989 | b.C = nil 1990 | err = errors.New(C.GoString(cmsg)) 1991 | C.LLVMDisposeMessage(cmsg) 1992 | } 1993 | return 1994 | } 1995 | 1996 | func NewMemoryBufferFromStdin() (b MemoryBuffer, err error) { 1997 | var cmsg *C.char 1998 | fail := C.LLVMCreateMemoryBufferWithSTDIN(&b.C, &cmsg) 1999 | if fail != 0 { 2000 | b.C = nil 2001 | err = errors.New(C.GoString(cmsg)) 2002 | C.LLVMDisposeMessage(cmsg) 2003 | } 2004 | return 2005 | } 2006 | 2007 | func (b MemoryBuffer) Bytes() []byte { 2008 | cstart := C.LLVMGetBufferStart(b.C) 2009 | csize := C.LLVMGetBufferSize(b.C) 2010 | return C.GoBytes(unsafe.Pointer(cstart), C.int(csize)) 2011 | } 2012 | 2013 | func (b MemoryBuffer) Dispose() { C.LLVMDisposeMemoryBuffer(b.C) } 2014 | 2015 | //------------------------------------------------------------------------- 2016 | // llvm.PassManager 2017 | //------------------------------------------------------------------------- 2018 | 2019 | // Constructs a new whole-module pass pipeline. This type of pipeline is 2020 | // suitable for link-time optimization and whole-module transformations. 2021 | // See llvm::PassManager::PassManager. 2022 | func NewPassManager() (pm PassManager) { pm.C = C.LLVMCreatePassManager(); return } 2023 | 2024 | // Constructs a new function-by-function pass pipeline over the module 2025 | // provider. It does not take ownership of the module provider. This type of 2026 | // pipeline is suitable for code generation and JIT compilation tasks. 2027 | // See llvm::FunctionPassManager::FunctionPassManager. 2028 | func NewFunctionPassManagerForModule(m Module) (pm PassManager) { 2029 | pm.C = C.LLVMCreateFunctionPassManagerForModule(m.C) 2030 | return 2031 | } 2032 | 2033 | // Initializes, executes on the provided module, and finalizes all of the 2034 | // passes scheduled in the pass manager. Returns 1 if any of the passes 2035 | // modified the module, 0 otherwise. See llvm::PassManager::run(Module&). 2036 | func (pm PassManager) Run(m Module) bool { return C.LLVMRunPassManager(pm.C, m.C) != 0 } 2037 | 2038 | // Initializes all of the function passes scheduled in the function pass 2039 | // manager. Returns 1 if any of the passes modified the module, 0 otherwise. 2040 | // See llvm::FunctionPassManager::doInitialization. 2041 | func (pm PassManager) InitializeFunc() bool { return C.LLVMInitializeFunctionPassManager(pm.C) != 0 } 2042 | 2043 | // Executes all of the function passes scheduled in the function pass manager 2044 | // on the provided function. Returns 1 if any of the passes modified the 2045 | // function, false otherwise. 2046 | // See llvm::FunctionPassManager::run(Function&). 2047 | func (pm PassManager) RunFunc(f Value) bool { return C.LLVMRunFunctionPassManager(pm.C, f.C) != 0 } 2048 | 2049 | // Finalizes all of the function passes scheduled in the function pass 2050 | // manager. Returns 1 if any of the passes modified the module, 0 otherwise. 2051 | // See llvm::FunctionPassManager::doFinalization. 2052 | func (pm PassManager) FinalizeFunc() bool { return C.LLVMFinalizeFunctionPassManager(pm.C) != 0 } 2053 | 2054 | // Frees the memory of a pass pipeline. For function pipelines, does not free 2055 | // the module provider. 2056 | // See llvm::PassManagerBase::~PassManagerBase. 2057 | func (pm PassManager) Dispose() { C.LLVMDisposePassManager(pm.C) } 2058 | -------------------------------------------------------------------------------- /ir_test.go: -------------------------------------------------------------------------------- 1 | //===- ir_test.go - Tests for ir ------------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file tests bindings for the ir component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | import ( 16 | "strconv" 17 | "strings" 18 | "testing" 19 | ) 20 | 21 | func testAttribute(t *testing.T, name string) { 22 | ctx := NewContext() 23 | mod := ctx.NewModule("") 24 | defer mod.Dispose() 25 | 26 | ftyp := FunctionType(ctx.VoidType(), nil, false) 27 | fn := AddFunction(mod, "foo", ftyp) 28 | 29 | kind := AttributeKindID(name) 30 | attr := mod.Context().CreateEnumAttribute(kind, 0) 31 | 32 | fn.AddFunctionAttr(attr) 33 | newattr := fn.GetEnumFunctionAttribute(kind) 34 | if attr != newattr { 35 | t.Errorf("got attribute %p, want %p", newattr.C, attr.C) 36 | } 37 | 38 | text := mod.String() 39 | if !strings.Contains(text, " "+name+" ") { 40 | t.Errorf("expected attribute '%s', got:\n%s", name, text) 41 | } 42 | 43 | fn.RemoveEnumFunctionAttribute(kind) 44 | newattr = fn.GetEnumFunctionAttribute(kind) 45 | if !newattr.IsNil() { 46 | t.Errorf("got attribute %p, want 0", newattr.C) 47 | } 48 | } 49 | 50 | func TestAttributes(t *testing.T) { 51 | // Tests that our attribute constants haven't drifted from LLVM's. 52 | attrTests := []string{ 53 | "sanitize_address", 54 | "alwaysinline", 55 | "builtin", 56 | "convergent", 57 | "inlinehint", 58 | "inreg", 59 | "jumptable", 60 | "minsize", 61 | "naked", 62 | "nest", 63 | "noalias", 64 | "nobuiltin", 65 | "nocapture", 66 | "noduplicate", 67 | "noimplicitfloat", 68 | "noinline", 69 | "nonlazybind", 70 | "nonnull", 71 | "noredzone", 72 | "noreturn", 73 | "nounwind", 74 | "optnone", 75 | "optsize", 76 | "readnone", 77 | "readonly", 78 | "returned", 79 | "returns_twice", 80 | "signext", 81 | "safestack", 82 | "ssp", 83 | "sspreq", 84 | "sspstrong", 85 | "sanitize_thread", 86 | "sanitize_memory", 87 | "uwtable", 88 | "zeroext", 89 | "cold", 90 | "nocf_check", 91 | } 92 | 93 | for _, name := range attrTests { 94 | majorVersion, err := strconv.Atoi(strings.SplitN(Version, ".", 2)[0]) 95 | if err != nil { 96 | // sanity check, should be unreachable 97 | t.Errorf("could not parse LLVM version: %v", err) 98 | } 99 | if majorVersion >= 15 && name == "uwtable" { 100 | // This changed from an EnumAttr to an IntAttr in LLVM 15, and testAttribute doesn't work on such attributes. 101 | continue 102 | } 103 | testAttribute(t, name) 104 | } 105 | } 106 | 107 | func TestDebugLoc(t *testing.T) { 108 | ctx := NewContext() 109 | mod := ctx.NewModule("") 110 | defer mod.Dispose() 111 | 112 | b := ctx.NewBuilder() 113 | defer b.Dispose() 114 | 115 | d := NewDIBuilder(mod) 116 | defer func() { 117 | d.Destroy() 118 | }() 119 | file := d.CreateFile("dummy_file", "dummy_dir") 120 | voidInfo := d.CreateBasicType(DIBasicType{Name: "void"}) 121 | typeInfo := d.CreateSubroutineType(DISubroutineType{ 122 | File: file, 123 | Parameters: []Metadata{voidInfo}, 124 | Flags: 0, 125 | }) 126 | scope := d.CreateFunction(file, DIFunction{ 127 | Name: "foo", 128 | LinkageName: "foo", 129 | Line: 10, 130 | ScopeLine: 10, 131 | Type: typeInfo, 132 | File: file, 133 | IsDefinition: true, 134 | }) 135 | 136 | b.SetCurrentDebugLocation(10, 20, scope, Metadata{}) 137 | loc := b.GetCurrentDebugLocation() 138 | if loc.Line != 10 { 139 | t.Errorf("Got line %d, though wanted 10", loc.Line) 140 | } 141 | if loc.Col != 20 { 142 | t.Errorf("Got column %d, though wanted 20", loc.Col) 143 | } 144 | if loc.Scope.C != scope.C { 145 | t.Errorf("Got metadata %v as scope, though wanted %v", loc.Scope.C, scope.C) 146 | } 147 | } 148 | 149 | func TestSubtypes(t *testing.T) { 150 | cont := NewContext() 151 | defer cont.Dispose() 152 | 153 | st_pointer := cont.StructType([]Type{cont.Int32Type(), cont.Int8Type()}, false) 154 | st_inner := st_pointer.Subtypes() 155 | if len(st_inner) != 2 { 156 | t.Errorf("Got size %d, though wanted 2", len(st_inner)) 157 | } 158 | if st_inner[0] != cont.Int32Type() { 159 | t.Errorf("Expected first struct field to be int32") 160 | } 161 | if st_inner[1] != cont.Int8Type() { 162 | t.Errorf("Expected second struct field to be int8") 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /irreader.go: -------------------------------------------------------------------------------- 1 | //===- irreader.go - Bindings for irreader --------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the irreader component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/Core.h" 17 | #include "llvm-c/IRReader.h" 18 | #include 19 | */ 20 | import "C" 21 | 22 | import ( 23 | "errors" 24 | ) 25 | 26 | // ParseIR parses the textual IR given in the memory buffer and returns a new 27 | // LLVM module in this context. 28 | func (c *Context) ParseIR(buf MemoryBuffer) (Module, error) { 29 | var m Module 30 | var errmsg *C.char 31 | if C.LLVMParseIRInContext(c.C, buf.C, &m.C, &errmsg) != 0 { 32 | err := errors.New(C.GoString(errmsg)) 33 | C.LLVMDisposeMessage(errmsg) 34 | return Module{}, err 35 | } 36 | return m, nil 37 | } 38 | -------------------------------------------------------------------------------- /linker.go: -------------------------------------------------------------------------------- 1 | //===- linker.go - Bindings for linker ------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the linker component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/Core.h" 17 | #include "llvm-c/Linker.h" 18 | #include 19 | */ 20 | import "C" 21 | import "errors" 22 | 23 | func LinkModules(Dest, Src Module) error { 24 | failed := C.LLVMLinkModules2(Dest.C, Src.C) 25 | if failed != 0 { 26 | err := errors.New("Linking failed") 27 | return err 28 | } 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /llvm_config_darwin_llvm14.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && darwin && llvm14 2 | 3 | package llvm 4 | 5 | // Automatically generated by `make config BUILDDIR=`, do not edit. 6 | 7 | // #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@14/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 8 | // #cgo amd64 CXXFLAGS: -std=c++14 9 | // #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@14/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 10 | // #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@14/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 11 | // #cgo arm64 CXXFLAGS: -std=c++14 12 | // #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@14/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 13 | import "C" 14 | 15 | type run_build_sh int 16 | -------------------------------------------------------------------------------- /llvm_config_darwin_llvm15.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && darwin && llvm15 2 | 3 | package llvm 4 | 5 | // Automatically generated by `make config BUILDDIR=`, do not edit. 6 | 7 | // #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@15/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 8 | // #cgo amd64 CXXFLAGS: -std=c++14 9 | // #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@15/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 10 | // #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@15/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 11 | // #cgo arm64 CXXFLAGS: -std=c++14 12 | // #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@15/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 13 | import "C" 14 | 15 | type run_build_sh int 16 | -------------------------------------------------------------------------------- /llvm_config_darwin_llvm16.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && darwin && llvm16 2 | 3 | package llvm 4 | 5 | // Automatically generated by `make config BUILDDIR=`, do not edit. 6 | 7 | // #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@16/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 8 | // #cgo amd64 CXXFLAGS: -std=c++17 9 | // #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@16/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 10 | // #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@16/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 11 | // #cgo arm64 CXXFLAGS: -std=c++17 12 | // #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@16/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 13 | import "C" 14 | 15 | type run_build_sh int 16 | -------------------------------------------------------------------------------- /llvm_config_darwin_llvm17.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && darwin && llvm17 2 | 3 | package llvm 4 | 5 | // Automatically generated by `make config BUILDDIR=`, do not edit. 6 | 7 | // #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@17/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 8 | // #cgo amd64 CXXFLAGS: -std=c++17 9 | // #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@17/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 10 | // #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@17/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 11 | // #cgo arm64 CXXFLAGS: -std=c++17 12 | // #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@17/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 13 | import "C" 14 | 15 | type run_build_sh int 16 | -------------------------------------------------------------------------------- /llvm_config_darwin_llvm18.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && darwin && llvm18 2 | 3 | package llvm 4 | 5 | // Automatically generated by `make config BUILDDIR=`, do not edit. 6 | 7 | // #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 8 | // #cgo amd64 CXXFLAGS: -std=c++17 9 | // #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 10 | // #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 11 | // #cgo arm64 CXXFLAGS: -std=c++17 12 | // #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 13 | import "C" 14 | 15 | type run_build_sh int 16 | -------------------------------------------------------------------------------- /llvm_config_darwin_llvm19.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && darwin && llvm19 2 | 3 | package llvm 4 | 5 | // Automatically generated by `make config BUILDDIR=`, do not edit. 6 | 7 | // #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@19/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 8 | // #cgo amd64 CXXFLAGS: -std=c++17 9 | // #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@19/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 10 | // #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@19/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 11 | // #cgo arm64 CXXFLAGS: -std=c++17 12 | // #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@19/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 13 | import "C" 14 | 15 | type run_build_sh int 16 | -------------------------------------------------------------------------------- /llvm_config_darwin_llvm20.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && darwin && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 2 | 3 | package llvm 4 | 5 | // Automatically generated by `make config BUILDDIR=`, do not edit. 6 | 7 | // #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@20/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 8 | // #cgo amd64 CXXFLAGS: -std=c++17 9 | // #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@20/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 10 | // #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@20/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 11 | // #cgo arm64 CXXFLAGS: -std=c++17 12 | // #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@20/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm 13 | import "C" 14 | 15 | type run_build_sh int 16 | -------------------------------------------------------------------------------- /llvm_config_linux_llvm14.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && linux && llvm14 2 | 3 | package llvm 4 | 5 | // #cgo CPPFLAGS: -I/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 6 | // #cgo CXXFLAGS: -std=c++14 7 | // #cgo LDFLAGS: -L/usr/lib/llvm-14/lib -lLLVM-14 8 | import "C" 9 | 10 | type run_build_sh int 11 | -------------------------------------------------------------------------------- /llvm_config_linux_llvm15.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && linux && llvm15 2 | 3 | package llvm 4 | 5 | // #cgo CPPFLAGS: -I/usr/lib/llvm-15/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 6 | // #cgo CXXFLAGS: -std=c++14 7 | // #cgo LDFLAGS: -L/usr/lib/llvm-15/lib -lLLVM-15 8 | import "C" 9 | 10 | type run_build_sh int 11 | -------------------------------------------------------------------------------- /llvm_config_linux_llvm16.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && linux && llvm16 2 | 3 | package llvm 4 | 5 | // #cgo CPPFLAGS: -I/usr/lib/llvm-16/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 6 | // #cgo CXXFLAGS: -std=c++17 7 | // #cgo LDFLAGS: -L/usr/lib/llvm-16/lib -lLLVM-16 8 | import "C" 9 | 10 | type run_build_sh int 11 | -------------------------------------------------------------------------------- /llvm_config_linux_llvm17.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && linux && llvm17 2 | 3 | package llvm 4 | 5 | // #cgo CPPFLAGS: -I/usr/include/llvm-17 -I/usr/include/llvm-c-17 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 6 | // #cgo CXXFLAGS: -std=c++17 7 | // #cgo LDFLAGS: -L/usr/lib/llvm-17/lib -lLLVM-17 8 | import "C" 9 | 10 | type run_build_sh int 11 | -------------------------------------------------------------------------------- /llvm_config_linux_llvm18.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && linux && llvm18 2 | 3 | package llvm 4 | 5 | // #cgo CPPFLAGS: -I/usr/include/llvm-18 -I/usr/include/llvm-c-18 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 6 | // #cgo CXXFLAGS: -std=c++17 7 | // #cgo LDFLAGS: -L/usr/lib/llvm-18/lib -lLLVM-18 8 | import "C" 9 | 10 | type run_build_sh int 11 | -------------------------------------------------------------------------------- /llvm_config_linux_llvm19.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && linux && llvm19 2 | 3 | package llvm 4 | 5 | // #cgo CPPFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 6 | // #cgo CXXFLAGS: -std=c++17 7 | // #cgo LDFLAGS: -L/usr/lib/llvm-19/lib -lLLVM-19 8 | import "C" 9 | 10 | type run_build_sh int 11 | -------------------------------------------------------------------------------- /llvm_config_linux_llvm20.go: -------------------------------------------------------------------------------- 1 | //go:build !byollvm && linux && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 2 | 3 | package llvm 4 | 5 | // #cgo CPPFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 6 | // #cgo CXXFLAGS: -std=c++17 7 | // #cgo LDFLAGS: -L/usr/lib/llvm-20/lib -lLLVM-20 8 | import "C" 9 | 10 | type run_build_sh int 11 | -------------------------------------------------------------------------------- /llvm_dep.go: -------------------------------------------------------------------------------- 1 | //===- llvm_dep.go - creates LLVM dependency ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file ensures that the LLVM libraries are built before using the 10 | // bindings. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | //go:build !byollvm 15 | 16 | package llvm 17 | 18 | var _ run_build_sh 19 | -------------------------------------------------------------------------------- /llvm_test.go: -------------------------------------------------------------------------------- 1 | package llvm_test 2 | 3 | import "tinygo.org/x/go-llvm" 4 | 5 | import "testing" 6 | 7 | // Dummy test function. 8 | // All it does is test whether we can use LLVM at all. 9 | func TestLLVM(t *testing.T) { 10 | t.Log("LLVM version:", llvm.Version) 11 | } 12 | -------------------------------------------------------------------------------- /passes.go: -------------------------------------------------------------------------------- 1 | package llvm 2 | 3 | /* 4 | #include "llvm-c/Transforms/PassBuilder.h" 5 | #include "llvm-c/Error.h" 6 | #include 7 | */ 8 | import "C" 9 | import ( 10 | "errors" 11 | "unsafe" 12 | ) 13 | 14 | // PassBuilderOptions allows specifying several options for the PassBuilder. 15 | type PassBuilderOptions struct { 16 | C C.LLVMPassBuilderOptionsRef 17 | } 18 | 19 | // NewPassBuilderOptions creates a PassBuilderOptions which can be used 20 | // to specify pass options for RunPasses. 21 | func NewPassBuilderOptions() (pbo PassBuilderOptions) { 22 | pbo.C = C.LLVMCreatePassBuilderOptions() 23 | return 24 | } 25 | 26 | // RunPasses runs the specified optimization passes on the functions in the module. 27 | // `passes` is a comma separated list of pass names in the same format as llvm's 28 | // `opt -passes=...` command. Running `opt -print-passes` can list the available 29 | // passes. 30 | // 31 | // Some notable passes include: 32 | // 33 | // default -- run the default -O0 passes 34 | // default -- run the default -O1 passes 35 | // default -- run the default -O2 passes 36 | // default -- run the default -O3 passes 37 | // default -- run the default -Os passes, like -O2 but size conscious 38 | // default -- run the default -Oz passes, optimizing for size above all else 39 | func (mod Module) RunPasses(passes string, tm TargetMachine, options PassBuilderOptions) error { 40 | cpasses := C.CString(passes) 41 | defer C.free(unsafe.Pointer(cpasses)) 42 | 43 | err := C.LLVMRunPasses(mod.C, cpasses, tm.C, options.C) 44 | if err != nil { 45 | cstr := C.LLVMGetErrorMessage(err) 46 | gstr := C.GoString(cstr) 47 | C.LLVMDisposeErrorMessage(cstr) 48 | 49 | return errors.New(gstr) 50 | } 51 | return nil 52 | } 53 | 54 | // SetVerifyEach toggles adding a VerifierPass to the PassBuilder, 55 | // ensuring all functions inside the module are valid. Useful for 56 | // debugging, but adds a significant amount of overhead. 57 | func (pbo PassBuilderOptions) SetVerifyEach(verifyEach bool) { 58 | C.LLVMPassBuilderOptionsSetVerifyEach(pbo.C, boolToLLVMBool(verifyEach)) 59 | } 60 | 61 | // SetDebugLogging toggles debug logging for the PassBuilder. 62 | func (pbo PassBuilderOptions) SetDebugLogging(debugLogging bool) { 63 | C.LLVMPassBuilderOptionsSetDebugLogging(pbo.C, boolToLLVMBool(debugLogging)) 64 | } 65 | 66 | // SetLoopInterleaving toggles loop interleaving, which is part of 67 | // loop vectorization. 68 | func (pbo PassBuilderOptions) SetLoopInterleaving(loopInterleaving bool) { 69 | C.LLVMPassBuilderOptionsSetLoopInterleaving(pbo.C, boolToLLVMBool(loopInterleaving)) 70 | } 71 | 72 | // SetLoopVectorization toggles loop vectorization. 73 | func (pbo PassBuilderOptions) SetLoopVectorization(loopVectorization bool) { 74 | C.LLVMPassBuilderOptionsSetLoopVectorization(pbo.C, boolToLLVMBool(loopVectorization)) 75 | } 76 | 77 | // SetSLPVectorization toggles Super-Word Level Parallelism vectorization, 78 | // whose goal is to combine multiple similar independent instructions into 79 | // a vector instruction. 80 | func (pbo PassBuilderOptions) SetSLPVectorization(slpVectorization bool) { 81 | C.LLVMPassBuilderOptionsSetSLPVectorization(pbo.C, boolToLLVMBool(slpVectorization)) 82 | } 83 | 84 | // SetLoopUnrolling toggles loop unrolling. 85 | func (pbo PassBuilderOptions) SetLoopUnrolling(loopUnrolling bool) { 86 | C.LLVMPassBuilderOptionsSetLoopUnrolling(pbo.C, boolToLLVMBool(loopUnrolling)) 87 | } 88 | 89 | // SetForgetAllSCEVInLoopUnroll toggles forgetting all SCEV (Scalar Evolution) 90 | // information in loop unrolling. Scalar Evolution is a pass that analyses 91 | // the how scalars evolve over iterations of a loop in order to optimize 92 | // the loop better. Forgetting this information can be useful in some cases. 93 | func (pbo PassBuilderOptions) SetForgetAllSCEVInLoopUnroll(forgetSCEV bool) { 94 | C.LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(pbo.C, boolToLLVMBool(forgetSCEV)) 95 | } 96 | 97 | // SetLicmMssaOptCap sets a tuning option to cap the number of calls to 98 | // retrieve clobbering accesses in MemorySSA, in Loop Invariant Code Motion 99 | // optimization. 100 | // See [llvm::PipelineTuningOptions::LicmMssaOptCap]. 101 | func (pbo PassBuilderOptions) SetLicmMssaOptCap(optCap uint) { 102 | C.LLVMPassBuilderOptionsSetLicmMssaOptCap(pbo.C, C.unsigned(optCap)) 103 | } 104 | 105 | // SetLicmMssaNoAccForPromotionCap sets a tuning option to cap the number of 106 | // promotions to scalars in Loop Invariant Code Motion with MemorySSA, if 107 | // the number of accesses is too large. 108 | // See [llvm::PipelineTuningOptions::LicmMssaNoAccForPromotionCap]. 109 | func (pbo PassBuilderOptions) SetLicmMssaNoAccForPromotionCap(promotionCap uint) { 110 | C.LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(pbo.C, C.unsigned(promotionCap)) 111 | } 112 | 113 | // SetCallGraphProfile toggles whether call graph profiling should be used. 114 | func (pbo PassBuilderOptions) SetCallGraphProfile(cgProfile bool) { 115 | C.LLVMPassBuilderOptionsSetCallGraphProfile(pbo.C, boolToLLVMBool(cgProfile)) 116 | } 117 | 118 | // SetMergeFunctions toggles finding functions which will generate identical 119 | // machine code by considering all pointer types to be equivalent. Once 120 | // identified, they will be folded by replacing a call to one with a call to a 121 | // bitcast of the other. 122 | func (pbo PassBuilderOptions) SetMergeFunctions(mergeFuncs bool) { 123 | C.LLVMPassBuilderOptionsSetMergeFunctions(pbo.C, boolToLLVMBool(mergeFuncs)) 124 | } 125 | 126 | // Dispose of the memory allocated for the PassBuilderOptions. 127 | func (pbo PassBuilderOptions) Dispose() { 128 | C.LLVMDisposePassBuilderOptions(pbo.C) 129 | } 130 | -------------------------------------------------------------------------------- /passes_test.go: -------------------------------------------------------------------------------- 1 | package llvm 2 | 3 | import "testing" 4 | 5 | func TestPasses(t *testing.T) { 6 | InitializeNativeTarget() 7 | InitializeNativeAsmPrinter() 8 | 9 | ctx := NewContext() 10 | 11 | mod := ctx.NewModule("fac_module") 12 | 13 | fac_args := []Type{ctx.Int32Type()} 14 | fac_type := FunctionType(ctx.Int32Type(), fac_args, false) 15 | fac := AddFunction(mod, "fac", fac_type) 16 | fac.SetFunctionCallConv(CCallConv) 17 | n := fac.Param(0) 18 | 19 | entry := AddBasicBlock(fac, "entry") 20 | iftrue := AddBasicBlock(fac, "iftrue") 21 | iffalse := AddBasicBlock(fac, "iffalse") 22 | end := AddBasicBlock(fac, "end") 23 | 24 | builder := ctx.NewBuilder() 25 | defer builder.Dispose() 26 | 27 | builder.SetInsertPointAtEnd(entry) 28 | If := builder.CreateICmp(IntEQ, n, ConstInt(ctx.Int32Type(), 0, false), "cmptmp") 29 | builder.CreateCondBr(If, iftrue, iffalse) 30 | 31 | builder.SetInsertPointAtEnd(iftrue) 32 | res_iftrue := ConstInt(ctx.Int32Type(), 1, false) 33 | builder.CreateBr(end) 34 | 35 | builder.SetInsertPointAtEnd(iffalse) 36 | n_minus := builder.CreateSub(n, ConstInt(ctx.Int32Type(), 1, false), "subtmp") 37 | call_fac_args := []Value{n_minus} 38 | call_fac := builder.CreateCall(fac_type, fac, call_fac_args, "calltmp") 39 | res_iffalse := builder.CreateMul(n, call_fac, "multmp") 40 | builder.CreateBr(end) 41 | 42 | builder.SetInsertPointAtEnd(end) 43 | res := builder.CreatePHI(ctx.Int32Type(), "result") 44 | phi_vals := []Value{res_iftrue, res_iffalse} 45 | phi_blocks := []BasicBlock{iftrue, iffalse} 46 | res.AddIncoming(phi_vals, phi_blocks) 47 | builder.CreateRet(res) 48 | 49 | err := VerifyModule(mod, ReturnStatusAction) 50 | if err != nil { 51 | t.Errorf("Error verifying module: %s", err) 52 | return 53 | } 54 | 55 | targ, err := GetTargetFromTriple(DefaultTargetTriple()) 56 | if err != nil { 57 | t.Error(err) 58 | } 59 | 60 | mt := targ.CreateTargetMachine(DefaultTargetTriple(), "", "", CodeGenLevelDefault, RelocDefault, CodeModelDefault) 61 | 62 | pbo := NewPassBuilderOptions() 63 | defer pbo.Dispose() 64 | 65 | t.Run("no error running default pass", func(t *testing.T) { 66 | err := mod.RunPasses("default", mt, pbo) 67 | if err != nil { 68 | t.Error(err) 69 | } 70 | }) 71 | 72 | t.Run("errors on unknown pass name", func(t *testing.T) { 73 | err := mod.RunPasses("badpassnamedoesnotexist", mt, pbo) 74 | if err == nil { 75 | t.Error("expecting error but got none") 76 | } 77 | 78 | if err.Error() != "unknown pass name 'badpassnamedoesnotexist'" { 79 | t.Errorf("expected error about unknow pass name, instead got %s", err) 80 | } 81 | }) 82 | } 83 | -------------------------------------------------------------------------------- /string.go: -------------------------------------------------------------------------------- 1 | //===- string.go - Stringer implementation for Type -----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file implements the Stringer interface for the Type type. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | import "fmt" 16 | 17 | func (t TypeKind) String() string { 18 | switch t { 19 | case VoidTypeKind: 20 | return "VoidTypeKind" 21 | case FloatTypeKind: 22 | return "FloatTypeKind" 23 | case DoubleTypeKind: 24 | return "DoubleTypeKind" 25 | case X86_FP80TypeKind: 26 | return "X86_FP80TypeKind" 27 | case FP128TypeKind: 28 | return "FP128TypeKind" 29 | case PPC_FP128TypeKind: 30 | return "PPC_FP128TypeKind" 31 | case LabelTypeKind: 32 | return "LabelTypeKind" 33 | case IntegerTypeKind: 34 | return "IntegerTypeKind" 35 | case FunctionTypeKind: 36 | return "FunctionTypeKind" 37 | case StructTypeKind: 38 | return "StructTypeKind" 39 | case ArrayTypeKind: 40 | return "ArrayTypeKind" 41 | case PointerTypeKind: 42 | return "PointerTypeKind" 43 | case VectorTypeKind: 44 | return "VectorTypeKind" 45 | case MetadataTypeKind: 46 | return "MetadataTypeKind" 47 | } 48 | panic("unreachable") 49 | } 50 | 51 | func (t Type) String() string { 52 | ts := typeStringer{s: make(map[Type]string)} 53 | return ts.typeString(t) 54 | } 55 | 56 | type typeStringer struct { 57 | s map[Type]string 58 | } 59 | 60 | func (ts *typeStringer) typeString(t Type) string { 61 | if s, ok := ts.s[t]; ok { 62 | return s 63 | } 64 | 65 | k := t.TypeKind() 66 | s := k.String() 67 | s = s[:len(s)-len("Kind")] 68 | 69 | switch k { 70 | case ArrayTypeKind: 71 | s += fmt.Sprintf("(%v[%v])", ts.typeString(t.ElementType()), t.ArrayLength()) 72 | case PointerTypeKind: 73 | s += fmt.Sprintf("(%v)", ts.typeString(t.ElementType())) 74 | case FunctionTypeKind: 75 | params := t.ParamTypes() 76 | s += "(" 77 | if len(params) > 0 { 78 | s += fmt.Sprintf("%v", ts.typeString(params[0])) 79 | for i := 1; i < len(params); i++ { 80 | s += fmt.Sprintf(", %v", ts.typeString(params[i])) 81 | } 82 | } 83 | s += fmt.Sprintf("):%v", ts.typeString(t.ReturnType())) 84 | case StructTypeKind: 85 | if name := t.StructName(); name != "" { 86 | ts.s[t] = "%" + name 87 | s = fmt.Sprintf("%%%s: %s", name, s) 88 | } 89 | etypes := t.StructElementTypes() 90 | s += "(" 91 | if n := len(etypes); n > 0 { 92 | s += ts.typeString(etypes[0]) 93 | for i := 1; i < n; i++ { 94 | s += fmt.Sprintf(", %v", ts.typeString(etypes[i])) 95 | } 96 | } 97 | s += ")" 98 | case IntegerTypeKind: 99 | s += fmt.Sprintf("(%d bits)", t.IntTypeWidth()) 100 | } 101 | 102 | ts.s[t] = s 103 | return s 104 | } 105 | -------------------------------------------------------------------------------- /support.go: -------------------------------------------------------------------------------- 1 | //===- support.go - Bindings for support ----------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the support component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/Support.h" 17 | #include "SupportBindings.h" 18 | #include 19 | */ 20 | import "C" 21 | 22 | import ( 23 | "errors" 24 | "unsafe" 25 | ) 26 | 27 | // Loads a dynamic library such that it may be used as an LLVM plugin. 28 | // See llvm::sys::DynamicLibrary::LoadLibraryPermanently. 29 | func LoadLibraryPermanently(lib string) error { 30 | var errstr *C.char 31 | libstr := C.CString(lib) 32 | defer C.free(unsafe.Pointer(libstr)) 33 | C.LLVMLoadLibraryPermanently2(libstr, &errstr) 34 | if errstr != nil { 35 | err := errors.New(C.GoString(errstr)) 36 | C.free(unsafe.Pointer(errstr)) 37 | return err 38 | } 39 | return nil 40 | } 41 | 42 | // Parse the given arguments using the LLVM command line parser. 43 | // See llvm::cl::ParseCommandLineOptions. 44 | func ParseCommandLineOptions(args []string, overview string) { 45 | argstrs := make([]*C.char, len(args)) 46 | for i, arg := range args { 47 | argstrs[i] = C.CString(arg) 48 | defer C.free(unsafe.Pointer(argstrs[i])) 49 | } 50 | overviewstr := C.CString(overview) 51 | defer C.free(unsafe.Pointer(overviewstr)) 52 | C.LLVMParseCommandLineOptions(C.int(len(args)), &argstrs[0], overviewstr) 53 | } 54 | -------------------------------------------------------------------------------- /target.go: -------------------------------------------------------------------------------- 1 | //===- target.go - Bindings for target ------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines bindings for the target component. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm-c/Core.h" 17 | #include "llvm-c/Target.h" 18 | #include "llvm-c/TargetMachine.h" 19 | #include 20 | */ 21 | import "C" 22 | import ( 23 | "errors" 24 | "unsafe" 25 | ) 26 | 27 | type ( 28 | TargetData struct { 29 | C C.LLVMTargetDataRef 30 | } 31 | Target struct { 32 | C C.LLVMTargetRef 33 | } 34 | TargetMachine struct { 35 | C C.LLVMTargetMachineRef 36 | } 37 | ByteOrdering C.enum_LLVMByteOrdering 38 | RelocMode C.LLVMRelocMode 39 | CodeGenOptLevel C.LLVMCodeGenOptLevel 40 | CodeGenFileType C.LLVMCodeGenFileType 41 | CodeModel C.LLVMCodeModel 42 | ) 43 | 44 | const ( 45 | BigEndian ByteOrdering = C.LLVMBigEndian 46 | LittleEndian ByteOrdering = C.LLVMLittleEndian 47 | ) 48 | 49 | const ( 50 | RelocDefault RelocMode = C.LLVMRelocDefault 51 | RelocStatic RelocMode = C.LLVMRelocStatic 52 | RelocPIC RelocMode = C.LLVMRelocPIC 53 | RelocDynamicNoPic RelocMode = C.LLVMRelocDynamicNoPic 54 | ) 55 | 56 | const ( 57 | CodeGenLevelNone CodeGenOptLevel = C.LLVMCodeGenLevelNone 58 | CodeGenLevelLess CodeGenOptLevel = C.LLVMCodeGenLevelLess 59 | CodeGenLevelDefault CodeGenOptLevel = C.LLVMCodeGenLevelDefault 60 | CodeGenLevelAggressive CodeGenOptLevel = C.LLVMCodeGenLevelAggressive 61 | ) 62 | 63 | const ( 64 | CodeModelDefault CodeModel = C.LLVMCodeModelDefault 65 | CodeModelJITDefault CodeModel = C.LLVMCodeModelJITDefault 66 | CodeModelTiny CodeModel = C.LLVMCodeModelTiny 67 | CodeModelSmall CodeModel = C.LLVMCodeModelSmall 68 | CodeModelKernel CodeModel = C.LLVMCodeModelKernel 69 | CodeModelMedium CodeModel = C.LLVMCodeModelMedium 70 | CodeModelLarge CodeModel = C.LLVMCodeModelLarge 71 | ) 72 | 73 | const ( 74 | AssemblyFile CodeGenFileType = C.LLVMAssemblyFile 75 | ObjectFile CodeGenFileType = C.LLVMObjectFile 76 | ) 77 | 78 | // InitializeAllTargetInfos - The main program should call this function if it 79 | // wants access to all available targets that LLVM is configured to support. 80 | func InitializeAllTargetInfos() { C.LLVMInitializeAllTargetInfos() } 81 | 82 | // InitializeAllTargets - The main program should call this function if it wants 83 | // to link in all available targets that LLVM is configured to support. 84 | func InitializeAllTargets() { C.LLVMInitializeAllTargets() } 85 | 86 | func InitializeAllTargetMCs() { C.LLVMInitializeAllTargetMCs() } 87 | 88 | func InitializeAllAsmParsers() { C.LLVMInitializeAllAsmParsers() } 89 | 90 | func InitializeAllAsmPrinters() { C.LLVMInitializeAllAsmPrinters() } 91 | 92 | var initializeNativeTargetError = errors.New("Failed to initialize native target") 93 | 94 | // InitializeNativeTarget - The main program should call this function to 95 | // initialize the native target corresponding to the host. This is useful 96 | // for JIT applications to ensure that the target gets linked in correctly. 97 | func InitializeNativeTarget() error { 98 | fail := C.LLVMInitializeNativeTarget() 99 | if fail != 0 { 100 | return initializeNativeTargetError 101 | } 102 | return nil 103 | } 104 | 105 | func InitializeNativeAsmPrinter() error { 106 | fail := C.LLVMInitializeNativeAsmPrinter() 107 | if fail != 0 { 108 | return initializeNativeTargetError 109 | } 110 | return nil 111 | } 112 | 113 | //------------------------------------------------------------------------- 114 | // llvm.TargetData 115 | //------------------------------------------------------------------------- 116 | 117 | // Creates target data from a target layout string. 118 | // See the constructor llvm::TargetData::TargetData. 119 | func NewTargetData(rep string) (td TargetData) { 120 | crep := C.CString(rep) 121 | defer C.free(unsafe.Pointer(crep)) 122 | td.C = C.LLVMCreateTargetData(crep) 123 | return 124 | } 125 | 126 | // Converts target data to a target layout string. The string must be disposed 127 | // with LLVMDisposeMessage. 128 | // See the constructor llvm::TargetData::TargetData. 129 | func (td TargetData) String() (s string) { 130 | cmsg := C.LLVMCopyStringRepOfTargetData(td.C) 131 | s = C.GoString(cmsg) 132 | C.LLVMDisposeMessage(cmsg) 133 | return 134 | } 135 | 136 | // Returns the byte order of a target, either BigEndian or LittleEndian. 137 | // See the method llvm::TargetData::isLittleEndian. 138 | func (td TargetData) ByteOrder() ByteOrdering { return ByteOrdering(C.LLVMByteOrder(td.C)) } 139 | 140 | // Returns the pointer size in bytes for a target. 141 | // See the method llvm::TargetData::getPointerSize. 142 | func (td TargetData) PointerSize() int { return int(C.LLVMPointerSize(td.C)) } 143 | 144 | // Returns the integer type that is the same size as a pointer on a target. 145 | // See the method llvm::TargetData::getIntPtrType. 146 | func (td TargetData) IntPtrType() (t Type) { t.C = C.LLVMIntPtrType(td.C); return } 147 | 148 | // Computes the size of a type in bytes for a target. 149 | // See the method llvm::TargetData::getTypeSizeInBits. 150 | func (td TargetData) TypeSizeInBits(t Type) uint64 { 151 | return uint64(C.LLVMSizeOfTypeInBits(td.C, t.C)) 152 | } 153 | 154 | // Computes the storage size of a type in bytes for a target. 155 | // See the method llvm::TargetData::getTypeStoreSize. 156 | func (td TargetData) TypeStoreSize(t Type) uint64 { 157 | return uint64(C.LLVMStoreSizeOfType(td.C, t.C)) 158 | } 159 | 160 | // Computes the ABI size of a type in bytes for a target. 161 | // See the method llvm::TargetData::getTypeAllocSize. 162 | func (td TargetData) TypeAllocSize(t Type) uint64 { 163 | return uint64(C.LLVMABISizeOfType(td.C, t.C)) 164 | } 165 | 166 | // Computes the ABI alignment of a type in bytes for a target. 167 | // See the method llvm::TargetData::getABITypeAlignment. 168 | func (td TargetData) ABITypeAlignment(t Type) int { 169 | return int(C.LLVMABIAlignmentOfType(td.C, t.C)) 170 | } 171 | 172 | // Computes the call frame alignment of a type in bytes for a target. 173 | // See the method llvm::TargetData::getCallFrameTypeAlignment. 174 | func (td TargetData) CallFrameTypeAlignment(t Type) int { 175 | return int(C.LLVMCallFrameAlignmentOfType(td.C, t.C)) 176 | } 177 | 178 | // Computes the preferred alignment of a type in bytes for a target. 179 | // See the method llvm::TargetData::getPrefTypeAlignment. 180 | func (td TargetData) PrefTypeAlignment(t Type) int { 181 | return int(C.LLVMPreferredAlignmentOfType(td.C, t.C)) 182 | } 183 | 184 | // Computes the preferred alignment of a global variable in bytes for a target. 185 | // See the method llvm::TargetData::getPreferredAlignment. 186 | func (td TargetData) PreferredAlignment(g Value) int { 187 | return int(C.LLVMPreferredAlignmentOfGlobal(td.C, g.C)) 188 | } 189 | 190 | // Computes the structure element that contains the byte offset for a target. 191 | // See the method llvm::StructLayout::getElementContainingOffset. 192 | func (td TargetData) ElementContainingOffset(t Type, offset uint64) int { 193 | return int(C.LLVMElementAtOffset(td.C, t.C, C.ulonglong(offset))) 194 | } 195 | 196 | // Computes the byte offset of the indexed struct element for a target. 197 | // See the method llvm::StructLayout::getElementOffset. 198 | func (td TargetData) ElementOffset(t Type, element int) uint64 { 199 | return uint64(C.LLVMOffsetOfElement(td.C, t.C, C.unsigned(element))) 200 | } 201 | 202 | // Deallocates a TargetData. 203 | // See the destructor llvm::TargetData::~TargetData. 204 | func (td TargetData) Dispose() { C.LLVMDisposeTargetData(td.C) } 205 | 206 | //------------------------------------------------------------------------- 207 | // llvm.Target 208 | //------------------------------------------------------------------------- 209 | 210 | func FirstTarget() Target { 211 | return Target{C.LLVMGetFirstTarget()} 212 | } 213 | 214 | func (t Target) NextTarget() Target { 215 | return Target{C.LLVMGetNextTarget(t.C)} 216 | } 217 | 218 | func GetTargetFromTriple(triple string) (t Target, err error) { 219 | var errstr *C.char 220 | ctriple := C.CString(triple) 221 | defer C.free(unsafe.Pointer(ctriple)) 222 | fail := C.LLVMGetTargetFromTriple(ctriple, &t.C, &errstr) 223 | if fail != 0 { 224 | err = errors.New(C.GoString(errstr)) 225 | C.LLVMDisposeMessage(errstr) 226 | } 227 | return 228 | } 229 | 230 | func (t Target) Name() string { 231 | return C.GoString(C.LLVMGetTargetName(t.C)) 232 | } 233 | 234 | func (t Target) Description() string { 235 | return C.GoString(C.LLVMGetTargetDescription(t.C)) 236 | } 237 | 238 | //------------------------------------------------------------------------- 239 | // llvm.TargetMachine 240 | //------------------------------------------------------------------------- 241 | 242 | // CreateTargetMachine creates a new TargetMachine. 243 | func (t Target) CreateTargetMachine(Triple string, CPU string, Features string, 244 | Level CodeGenOptLevel, Reloc RelocMode, 245 | CodeModel CodeModel) (tm TargetMachine) { 246 | cTriple := C.CString(Triple) 247 | defer C.free(unsafe.Pointer(cTriple)) 248 | cCPU := C.CString(CPU) 249 | defer C.free(unsafe.Pointer(cCPU)) 250 | cFeatures := C.CString(Features) 251 | defer C.free(unsafe.Pointer(cFeatures)) 252 | tm.C = C.LLVMCreateTargetMachine(t.C, cTriple, cCPU, cFeatures, 253 | C.LLVMCodeGenOptLevel(Level), 254 | C.LLVMRelocMode(Reloc), 255 | C.LLVMCodeModel(CodeModel)) 256 | return 257 | } 258 | 259 | // CreateTargetData returns a new TargetData describing the TargetMachine's 260 | // data layout. The returned TargetData is owned by the caller, who is 261 | // responsible for disposing of it by calling the TargetData.Dispose method. 262 | func (tm TargetMachine) CreateTargetData() TargetData { 263 | return TargetData{C.LLVMCreateTargetDataLayout(tm.C)} 264 | } 265 | 266 | // Triple returns the triple describing the machine (arch-vendor-os). 267 | func (tm TargetMachine) Triple() string { 268 | cstr := C.LLVMGetTargetMachineTriple(tm.C) 269 | defer C.LLVMDisposeMessage(cstr) 270 | return C.GoString(cstr) 271 | } 272 | 273 | func (tm TargetMachine) EmitToMemoryBuffer(m Module, ft CodeGenFileType) (MemoryBuffer, error) { 274 | var errstr *C.char 275 | var mb MemoryBuffer 276 | fail := C.LLVMTargetMachineEmitToMemoryBuffer(tm.C, m.C, C.LLVMCodeGenFileType(ft), &errstr, &mb.C) 277 | if fail != 0 { 278 | err := errors.New(C.GoString(errstr)) 279 | C.free(unsafe.Pointer(errstr)) 280 | return MemoryBuffer{}, err 281 | } 282 | return mb, nil 283 | } 284 | 285 | func (tm TargetMachine) AddAnalysisPasses(pm PassManager) { 286 | C.LLVMAddAnalysisPasses(tm.C, pm.C) 287 | } 288 | 289 | // Dispose releases resources related to the TargetMachine. 290 | func (tm TargetMachine) Dispose() { 291 | C.LLVMDisposeTargetMachine(tm.C) 292 | } 293 | 294 | func DefaultTargetTriple() (triple string) { 295 | cTriple := C.LLVMGetDefaultTargetTriple() 296 | defer C.LLVMDisposeMessage(cTriple) 297 | triple = C.GoString(cTriple) 298 | return 299 | } 300 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | //===- version.go - LLVM version info -------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines LLVM version information. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | package llvm 14 | 15 | /* 16 | #include "llvm/Config/llvm-config.h" 17 | */ 18 | import "C" 19 | 20 | const Version = C.LLVM_VERSION_STRING 21 | --------------------------------------------------------------------------------