From 185673ef46a59528c40d0fdc220c6735606c0ebc Mon Sep 17 00:00:00 2001 From: deadprogram Date: Mon, 20 Jul 2026 15:30:47 +0200 Subject: [PATCH] go-llvm: use context-aware LLVM C APIs for functions deprecated in LLVM 22 LLVM 22 deprecated 8 global-context C API functions in favor of their context-aware counterparts. Instead of suppressing the warnings, call the non-deprecated InContext APIs directly. The non-context Go functions (MDKindID, StructType, ConstString, ConstStruct, AddBasicBlock, InsertBasicBlock) now delegate to GlobalContext().(), which already calls the InContext C APIs. IntPtrType calls LLVMIntPtrTypeInContext directly. Only LLVMGetGlobalContext still needs a warning-suppression wrapper in deprecated.c since it has no non-deprecated replacement. The context-aware C APIs have been available since well before LLVM 14, so this works across all supported LLVM versions. Signed-off-by: deadprogram --- deprecated.c | 24 ++++++++++++++++++++++++ deprecated.h | 30 ++++++++++++++++++++++++++++++ ir.go | 37 ++++++++----------------------------- target.go | 6 +++++- 4 files changed, 67 insertions(+), 30 deletions(-) create mode 100644 deprecated.c create mode 100644 deprecated.h diff --git a/deprecated.c b/deprecated.c new file mode 100644 index 0000000..b5a2c54 --- /dev/null +++ b/deprecated.c @@ -0,0 +1,24 @@ +//===- deprecated.c - Wrappers for deprecated LLVM C API --------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file wraps LLVMGetGlobalContext, which was deprecated in LLVM 22 but +// has no non-deprecated replacement. All other wrapped functions are +// handled by calling their context-aware counterparts from Go. +// +//===----------------------------------------------------------------------===// + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +#include "deprecated.h" + +LLVMContextRef LLVMGetGlobalContext_wrap(void) { + return LLVMGetGlobalContext(); +} + +#pragma GCC diagnostic pop diff --git a/deprecated.h b/deprecated.h new file mode 100644 index 0000000..f2cba8d --- /dev/null +++ b/deprecated.h @@ -0,0 +1,30 @@ +//===- deprecated.h - Wrappers for deprecated LLVM C API --------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file wraps LLVMGetGlobalContext, which was deprecated in LLVM 22 but +// has no non-deprecated replacement. All other wrapped functions are +// handled by calling their context-aware counterparts from Go. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BINDINGS_GO_LLVM_DEPRECATED_H +#define LLVM_BINDINGS_GO_LLVM_DEPRECATED_H + +#include "llvm-c/Core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +LLVMContextRef LLVMGetGlobalContext_wrap(void); + +#ifdef __cplusplus +} +#endif + +#endif // LLVM_BINDINGS_GO_LLVM_DEPRECATED_H diff --git a/ir.go b/ir.go index 47bf413..986748d 100644 --- a/ir.go +++ b/ir.go @@ -16,6 +16,7 @@ package llvm #include "llvm-c/Core.h" #include "llvm-c/Comdat.h" #include "IRBindings.h" +#include "deprecated.h" #include */ import "C" @@ -357,7 +358,7 @@ const ( //------------------------------------------------------------------------- func NewContext() Context { return Context{C.LLVMContextCreate()} } -func GlobalContext() Context { return Context{C.LLVMGetGlobalContext()} } +func GlobalContext() Context { return Context{C.LLVMGetGlobalContext_wrap()} } func (c Context) Dispose() { C.LLVMContextDispose(c.C) } func (c Context) MDKindID(name string) (id int) { @@ -368,10 +369,7 @@ func (c Context) MDKindID(name string) (id int) { } func MDKindID(name string) (id int) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - id = int(C.LLVMGetMDKindID(cname, C.unsigned(len(name)))) - return + return GlobalContext().MDKindID(name) } //------------------------------------------------------------------------- @@ -610,14 +608,7 @@ func (c Context) StructType(elementTypes []Type, packed bool) (t Type) { } func StructType(elementTypes []Type, packed bool) (t Type) { - var pt *C.LLVMTypeRef - var ptlen C.unsigned - if len(elementTypes) > 0 { - pt = llvmTypeRefPtr(&elementTypes[0]) - ptlen = C.unsigned(len(elementTypes)) - } - t.C = C.LLVMStructType(pt, ptlen, boolToLLVMBool(packed)) - return + return GlobalContext().StructType(elementTypes, packed) } func (c Context) StructCreateNamed(name string) (t Type) { @@ -882,11 +873,7 @@ func ConstNamedStruct(t Type, constVals []Value) (v Value) { return } func ConstString(str string, addnull bool) (v Value) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - v.C = C.LLVMConstString(cstr, - C.unsigned(len(str)), boolToLLVMBool(!addnull)) - return + return GlobalContext().ConstString(str, addnull) } func ConstArray(t Type, constVals []Value) (v Value) { ptr, nvals := llvmValueRefs(constVals) @@ -894,9 +881,7 @@ func ConstArray(t Type, constVals []Value) (v Value) { return } func ConstStruct(constVals []Value, packed bool) (v Value) { - ptr, nvals := llvmValueRefs(constVals) - v.C = C.LLVMConstStruct(ptr, nvals, boolToLLVMBool(packed)) - return + return GlobalContext().ConstStruct(constVals, packed) } func ConstVector(scalarConstVals []Value, packed bool) (v Value) { ptr, nvals := llvmValueRefs(scalarConstVals) @@ -1203,16 +1188,10 @@ func (c Context) InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) { return } func AddBasicBlock(f Value, name string) (bb BasicBlock) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - bb.C = C.LLVMAppendBasicBlock(f.C, cname) - return + return GlobalContext().AddBasicBlock(f, name) } func InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - bb.C = C.LLVMInsertBasicBlock(ref.C, cname) - return + return GlobalContext().InsertBasicBlock(ref, name) } func (bb BasicBlock) EraseFromParent() { C.LLVMDeleteBasicBlock(bb.C) } func (bb BasicBlock) MoveBefore(pos BasicBlock) { C.LLVMMoveBasicBlockBefore(bb.C, pos.C) } diff --git a/target.go b/target.go index 5075d14..b15827a 100644 --- a/target.go +++ b/target.go @@ -16,6 +16,7 @@ package llvm #include "llvm-c/Core.h" #include "llvm-c/Target.h" #include "llvm-c/TargetMachine.h" +#include "deprecated.h" #include */ import "C" @@ -143,7 +144,10 @@ func (td TargetData) PointerSize() int { return int(C.LLVMPointerSize(td.C)) } // Returns the integer type that is the same size as a pointer on a target. // See the method llvm::TargetData::getIntPtrType. -func (td TargetData) IntPtrType() (t Type) { t.C = C.LLVMIntPtrType(td.C); return } +func (td TargetData) IntPtrType() (t Type) { + t.C = C.LLVMIntPtrTypeInContext(C.LLVMGetGlobalContext_wrap(), td.C) + return +} // Computes the size of a type in bytes for a target. // See the method llvm::TargetData::getTypeSizeInBits.