mirror of
https://github.com/LLVMParty/llvm-nanobind
synced 2026-06-21 13:43:38 +00:00
@@ -206,11 +206,11 @@ This section captures guard preconditions for wrapper classes other than
|
||||
- `constant(str, radix)` requires `2 <= radix <= 36`.
|
||||
- Named struct creation:
|
||||
- `ctx.types.struct("Name", [field_types...])` defaults to
|
||||
`get_or_insert=True`.
|
||||
`reuse_existing=True`.
|
||||
- Reusing the same name with the same body returns the existing identified
|
||||
struct; reusing an opaque declaration completes it; conflicting bodies or
|
||||
packing raise `LLVMAssertionError`.
|
||||
- Pass `get_or_insert=False` for raw LLVM insertion behavior, which may append
|
||||
- Pass `reuse_existing=False` for raw LLVM insertion behavior, which may append
|
||||
a suffix to duplicate names.
|
||||
- Struct body mutation:
|
||||
- `set_body` requires identified opaque struct type (not literal, not already
|
||||
|
||||
@@ -44,7 +44,7 @@ Implement remaining LLVM-C API bindings to reach ~85% coverage of the C API, wit
|
||||
- `section.contains_symbol(symbol)` - Symbol membership test
|
||||
|
||||
**Comdat.h (all 5 functions):**
|
||||
- `mod.get_or_insert_comdat(name)` - Get/create COMDAT
|
||||
- `mod.add_comdat(name)` - Add/create COMDAT, or return the existing one
|
||||
- `gv.comdat` / `gv.set_comdat(comdat)` - Global COMDAT access
|
||||
- `comdat.selection_kind` - Selection kind property
|
||||
|
||||
|
||||
+1
-1
@@ -1254,7 +1254,7 @@ def declare_symbols(src: llvm.Module, m: llvm.Module) -> None:
|
||||
name = cur_md.name
|
||||
if m.get_named_metadata(name):
|
||||
raise RuntimeError("Named Metadata Node already cloned")
|
||||
m.get_or_insert_named_metadata(name)
|
||||
m.add_named_metadata(name)
|
||||
|
||||
next_md = cur_md.next
|
||||
if next_md is None:
|
||||
|
||||
+56
-49
@@ -1042,7 +1042,7 @@ struct LLVMTypeFactoryWrapper {
|
||||
LLVMTypeWrapper struct_with_name(const std::string &name,
|
||||
const Iterable<LLVMTypeWrapper> &elem_types,
|
||||
bool packed = false,
|
||||
bool get_or_insert = true) const {
|
||||
bool reuse_existing = true) const {
|
||||
check_valid();
|
||||
if (name.empty()) {
|
||||
throw LLVMAssertionError(
|
||||
@@ -1050,7 +1050,7 @@ struct LLVMTypeFactoryWrapper {
|
||||
}
|
||||
std::vector<LLVMTypeRef> elems = collect_type_refs(elem_types);
|
||||
|
||||
if (get_or_insert) {
|
||||
if (reuse_existing) {
|
||||
if (LLVMTypeRef existing = LLVMGetTypeByName2(m_ctx_ref, name.c_str())) {
|
||||
require_same_struct_body(existing, elems, packed, name);
|
||||
if (LLVMIsOpaqueStruct(existing)) {
|
||||
@@ -1080,12 +1080,12 @@ struct LLVMTypeFactoryWrapper {
|
||||
|
||||
// Opaque named struct (forward declaration)
|
||||
LLVMTypeWrapper opaque_struct(const std::string &name,
|
||||
bool get_or_insert = true) const {
|
||||
bool reuse_existing = true) const {
|
||||
check_valid();
|
||||
if (name.empty()) {
|
||||
throw LLVMAssertionError("Opaque struct type requires a non-empty name");
|
||||
}
|
||||
if (get_or_insert) {
|
||||
if (reuse_existing) {
|
||||
if (LLVMTypeRef existing = LLVMGetTypeByName2(m_ctx_ref, name.c_str()))
|
||||
return LLVMTypeWrapper(existing, m_context_token);
|
||||
}
|
||||
@@ -6055,10 +6055,10 @@ struct LLVMModuleWrapper : NoMoveCopy {
|
||||
// Functions
|
||||
LLVMFunctionWrapper add_function(const std::string &name,
|
||||
const LLVMTypeWrapper &func_ty,
|
||||
bool get_or_insert = true) {
|
||||
bool reuse_existing = true) {
|
||||
check_valid();
|
||||
func_ty.check_valid();
|
||||
if (get_or_insert) {
|
||||
if (reuse_existing) {
|
||||
if (LLVMValueRef func = LLVMGetNamedFunction(m_ref, name.c_str())) {
|
||||
require_same_type(LLVMGlobalGetValueType(func), func_ty.m_ref, name,
|
||||
"function");
|
||||
@@ -6081,17 +6081,17 @@ struct LLVMModuleWrapper : NoMoveCopy {
|
||||
// Global variables
|
||||
LLVMValueWrapper add_global(const LLVMTypeWrapper &ty,
|
||||
const std::string &name,
|
||||
bool get_or_insert = true) {
|
||||
return add_global_in_address_space(ty, name, 0, get_or_insert);
|
||||
bool reuse_existing = true) {
|
||||
return add_global_in_address_space(ty, name, 0, reuse_existing);
|
||||
}
|
||||
|
||||
LLVMValueWrapper add_global_in_address_space(const LLVMTypeWrapper &ty,
|
||||
const std::string &name,
|
||||
unsigned address_space,
|
||||
bool get_or_insert = true) {
|
||||
bool reuse_existing = true) {
|
||||
check_valid();
|
||||
ty.check_valid();
|
||||
if (get_or_insert) {
|
||||
if (reuse_existing) {
|
||||
if (LLVMValueRef global = LLVMGetNamedGlobal(m_ref, name.c_str())) {
|
||||
require_same_type(LLVMGlobalGetValueType(global), ty.m_ref, name,
|
||||
"global variable");
|
||||
@@ -6263,8 +6263,8 @@ struct LLVMModuleWrapper : NoMoveCopy {
|
||||
// COMDAT support (for Windows/COFF linking)
|
||||
// ==========================================================================
|
||||
|
||||
/// Get or insert a COMDAT section with the given name.
|
||||
LLVMComdatWrapper get_or_insert_comdat(const std::string &name) {
|
||||
/// Add a COMDAT section, or return the existing one with this name.
|
||||
LLVMComdatWrapper add_comdat(const std::string &name) {
|
||||
check_valid();
|
||||
LLVMComdatRef comdat = LLVMGetOrInsertComdat(m_ref, name.c_str());
|
||||
return LLVMComdatWrapper(comdat, m_token);
|
||||
@@ -6319,11 +6319,11 @@ struct LLVMModuleWrapper : NoMoveCopy {
|
||||
unsigned addr_space,
|
||||
const LLVMValueWrapper &aliasee,
|
||||
const std::string &name,
|
||||
bool get_or_insert = true) {
|
||||
bool reuse_existing = true) {
|
||||
check_valid();
|
||||
value_ty.check_valid();
|
||||
aliasee.check_valid();
|
||||
if (get_or_insert) {
|
||||
if (reuse_existing) {
|
||||
if (LLVMValueRef alias =
|
||||
LLVMGetNamedGlobalAlias(m_ref, name.c_str(), name.size())) {
|
||||
require_same_type(LLVMGlobalGetValueType(alias), value_ty.m_ref, name,
|
||||
@@ -6374,11 +6374,11 @@ struct LLVMModuleWrapper : NoMoveCopy {
|
||||
const LLVMTypeWrapper &ty,
|
||||
unsigned addr_space,
|
||||
const LLVMValueWrapper &resolver,
|
||||
bool get_or_insert = true) {
|
||||
bool reuse_existing = true) {
|
||||
check_valid();
|
||||
ty.check_valid();
|
||||
resolver.check_valid();
|
||||
if (get_or_insert) {
|
||||
if (reuse_existing) {
|
||||
if (LLVMValueRef ifunc =
|
||||
LLVMGetNamedGlobalIFunc(m_ref, name.c_str(), name.size())) {
|
||||
require_same_type(LLVMGlobalGetValueType(ifunc), ty.m_ref, name,
|
||||
@@ -6426,7 +6426,7 @@ struct LLVMModuleWrapper : NoMoveCopy {
|
||||
return LLVMNamedMDNodeWrapper(md, m_context_token);
|
||||
}
|
||||
|
||||
LLVMNamedMDNodeWrapper get_or_insert_named_metadata(const std::string &name) {
|
||||
LLVMNamedMDNodeWrapper add_named_metadata(const std::string &name) {
|
||||
check_valid();
|
||||
return LLVMNamedMDNodeWrapper(
|
||||
LLVMGetOrInsertNamedMetadata(m_ref, name.c_str(), name.size()),
|
||||
@@ -13959,12 +13959,12 @@ Valid when:
|
||||
|
||||
<sub>C API: LLVMGetTarget, LLVMSetTarget</sub>)")
|
||||
.def("add_function", &LLVMModuleWrapper::add_function, "name"_a,
|
||||
"func_ty"_a, nb::kw_only(), "get_or_insert"_a = true,
|
||||
"func_ty"_a, nb::kw_only(), "reuse_existing"_a = true,
|
||||
R"(Add or get a function.
|
||||
|
||||
By default, this returns an existing function with the same name when the
|
||||
function type matches, and raises if the name exists with an incompatible type
|
||||
or as another global value kind. Pass get_or_insert=False for LLVM's raw
|
||||
or as another global value kind. Pass reuse_existing=False for LLVM's raw
|
||||
inserting behavior, which may rename collisions with a suffix like `.0`.
|
||||
|
||||
<sub>C API: LLVMGetNamedFunction, LLVMAddFunction</sub>)")
|
||||
@@ -13973,23 +13973,23 @@ inserting behavior, which may rename collisions with a suffix like `.0`.
|
||||
|
||||
<sub>C API: LLVMGetNamedFunction</sub>)")
|
||||
.def("add_global", &LLVMModuleWrapper::add_global, "ty"_a, "name"_a,
|
||||
nb::kw_only(), "get_or_insert"_a = true,
|
||||
nb::kw_only(), "reuse_existing"_a = true,
|
||||
R"(Add or get a global variable in address space 0.
|
||||
|
||||
By default, this returns an existing global variable with the same name when
|
||||
the element type and address space match, and raises on incompatible existing
|
||||
symbols. Pass get_or_insert=False for LLVM's raw inserting behavior, which may
|
||||
symbols. Pass reuse_existing=False for LLVM's raw inserting behavior, which may
|
||||
rename collisions with a suffix like `.0`.
|
||||
|
||||
<sub>C API: LLVMGetNamedGlobal, LLVMAddGlobalInAddressSpace</sub>)")
|
||||
.def("add_global_in_address_space",
|
||||
&LLVMModuleWrapper::add_global_in_address_space, "ty"_a, "name"_a,
|
||||
"address_space"_a, nb::kw_only(), "get_or_insert"_a = true,
|
||||
"address_space"_a, nb::kw_only(), "reuse_existing"_a = true,
|
||||
R"(Add or get a global variable in an address space.
|
||||
|
||||
By default, this returns an existing global variable with the same name when
|
||||
the element type and address space match, and raises on incompatible existing
|
||||
symbols. Pass get_or_insert=False for LLVM's raw inserting behavior, which may
|
||||
symbols. Pass reuse_existing=False for LLVM's raw inserting behavior, which may
|
||||
rename collisions with a suffix like `.0`.
|
||||
|
||||
<sub>C API: LLVMGetNamedGlobal, LLVMAddGlobalInAddressSpace</sub>)")
|
||||
@@ -14065,11 +14065,11 @@ rename collisions with a suffix like `.0`.
|
||||
<sub>C API: LLVMGetNamedGlobalAlias</sub>)")
|
||||
.def("add_alias", &LLVMModuleWrapper::add_alias, "value_ty"_a,
|
||||
"addr_space"_a, "aliasee"_a, "name"_a, nb::kw_only(),
|
||||
"get_or_insert"_a = true,
|
||||
"reuse_existing"_a = true,
|
||||
R"(Add or get a global alias.
|
||||
|
||||
By default, this returns an existing alias with the same name when its value
|
||||
type, address space, and aliasee match. Pass get_or_insert=False for LLVM's raw
|
||||
type, address space, and aliasee match. Pass reuse_existing=False for LLVM's raw
|
||||
inserting behavior.
|
||||
|
||||
<sub>C API: LLVMGetNamedGlobalAlias, LLVMAddAlias2</sub>)")
|
||||
@@ -14088,11 +14088,11 @@ inserting behavior.
|
||||
<sub>C API: LLVMGetNamedGlobalIFunc</sub>)")
|
||||
.def("add_global_ifunc", &LLVMModuleWrapper::add_global_ifunc, "name"_a,
|
||||
"ty"_a, "addr_space"_a, "resolver"_a, nb::kw_only(),
|
||||
"get_or_insert"_a = true,
|
||||
"reuse_existing"_a = true,
|
||||
R"(Add or get an indirect function (IFunc) in the module.
|
||||
|
||||
By default, this returns an existing IFunc with the same name when its type,
|
||||
address space, and resolver match. Pass get_or_insert=False for LLVM's raw
|
||||
address space, and resolver match. Pass reuse_existing=False for LLVM's raw
|
||||
inserting behavior.
|
||||
|
||||
<sub>C API: LLVMGetNamedGlobalIFunc, LLVMAddGlobalIFunc</sub>)")
|
||||
@@ -14111,9 +14111,13 @@ inserting behavior.
|
||||
"name"_a, R"(Get named metadata.
|
||||
|
||||
<sub>C API: LLVMGetNamedMetadata</sub>)")
|
||||
.def("get_or_insert_named_metadata",
|
||||
&LLVMModuleWrapper::get_or_insert_named_metadata, "name"_a,
|
||||
R"(Get or insert named metadata.
|
||||
.def("add_named_metadata",
|
||||
&LLVMModuleWrapper::add_named_metadata, "name"_a,
|
||||
R"(Add named metadata, or return the existing node with this name.
|
||||
|
||||
This method has get-or-insert behavior: if named metadata with `name` already
|
||||
exists in the module, it is returned unchanged; otherwise a new empty named
|
||||
metadata node is created and returned.
|
||||
|
||||
<sub>C API: LLVMGetOrInsertNamedMetadata</sub>)")
|
||||
.def("get_named_metadata_num_operands",
|
||||
@@ -14164,18 +14168,21 @@ inserting behavior.
|
||||
|
||||
<sub>C API: LLVMLinkModules2</sub>)")
|
||||
// COMDAT support
|
||||
.def("get_or_insert_comdat", &LLVMModuleWrapper::get_or_insert_comdat,
|
||||
"name"_a,
|
||||
R"(Get or insert a COMDAT section with the given name.
|
||||
|
||||
COMDAT sections are used on Windows/COFF targets for symbol
|
||||
deduplication and merging.
|
||||
|
||||
Args:
|
||||
name: The COMDAT name
|
||||
|
||||
Returns:
|
||||
A Comdat object for the named section.
|
||||
.def("add_comdat", &LLVMModuleWrapper::add_comdat, "name"_a,
|
||||
R"(Add a COMDAT section, or return the existing one with this name.
|
||||
|
||||
This method has get-or-insert behavior: if a COMDAT with `name` already exists
|
||||
in the module, it is returned unchanged; otherwise a new COMDAT is created and
|
||||
returned.
|
||||
|
||||
COMDAT sections are used on Windows/COFF targets for symbol deduplication and
|
||||
merging.
|
||||
|
||||
Args:
|
||||
name: The COMDAT name
|
||||
|
||||
Returns:
|
||||
A Comdat object for the named section.
|
||||
|
||||
<sub>C API: LLVMGetOrInsertComdat</sub>)")
|
||||
// Module printing to file
|
||||
@@ -14379,21 +14386,21 @@ Use struct(name, elem_types, ...) for identified named structs.
|
||||
<sub>C API: LLVMStructTypeInContext</sub>)")
|
||||
.def("struct", &LLVMTypeFactoryWrapper::struct_with_name, "name"_a,
|
||||
"elem_types"_a, "packed"_a = false, nb::kw_only(),
|
||||
"get_or_insert"_a = true,
|
||||
"reuse_existing"_a = true,
|
||||
R"(Named struct type.
|
||||
|
||||
Named structs default to lookup-first get-or-insert semantics: an existing
|
||||
struct with the same name and body is returned, an opaque declaration is
|
||||
completed, and a different existing body raises. Pass get_or_insert=False for
|
||||
LLVM's raw inserting behavior, which may append a suffix to duplicate names.
|
||||
Named structs default to lookup-first reuse semantics: an existing struct with
|
||||
the same name and body is returned, an opaque declaration is completed, and a
|
||||
different existing body raises. Pass reuse_existing=False for LLVM's raw
|
||||
inserting behavior, which may append a suffix to duplicate names.
|
||||
|
||||
<sub>C API: LLVMStructCreateNamed</sub>)")
|
||||
.def("opaque_struct", &LLVMTypeFactoryWrapper::opaque_struct, "name"_a,
|
||||
nb::kw_only(), "get_or_insert"_a = true,
|
||||
nb::kw_only(), "reuse_existing"_a = true,
|
||||
R"(Opaque struct type.
|
||||
|
||||
Defaults to returning an existing named struct with this name. Pass
|
||||
get_or_insert=False for LLVM's raw inserting behavior, which may append a
|
||||
reuse_existing=False for LLVM's raw inserting behavior, which may append a
|
||||
suffix to duplicate names.
|
||||
|
||||
<sub>C API: LLVMStructCreateNamed</sub>)")
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
Regression coverage for API surface cleanup helpers.
|
||||
|
||||
Covers:
|
||||
- Module add_* get_or_insert=True defaults and explicit raw insertion escape hatch
|
||||
- Named struct get_or_insert=True defaults and explicit raw insertion escape hatch
|
||||
- Module add_* reuse_existing=True defaults and explicit raw insertion escape hatch
|
||||
- Named struct reuse_existing=True defaults and explicit raw insertion escape hatch
|
||||
- New member/factory APIs that replace module-level helpers
|
||||
- Builder parent navigation helpers and Module.create_builder()
|
||||
"""
|
||||
@@ -20,7 +20,7 @@ def expect_raises(fn, message_part: str) -> None:
|
||||
raise AssertionError("expected exception")
|
||||
|
||||
|
||||
def test_module_add_get_or_insert_semantics() -> None:
|
||||
def test_module_add_reuse_existing_semantics() -> None:
|
||||
with llvm.create_context() as ctx:
|
||||
i32 = ctx.types.i32
|
||||
i64 = ctx.types.i64
|
||||
@@ -29,12 +29,12 @@ def test_module_add_get_or_insert_semantics() -> None:
|
||||
other_fn_ty = ctx.types.function(i32, [])
|
||||
resolver_ty = ctx.types.function(i32, [])
|
||||
|
||||
with ctx.create_module("get_or_insert") as mod:
|
||||
with ctx.create_module("reuse_existing") as mod:
|
||||
fn = mod.add_function("f", fn_ty)
|
||||
assert mod.add_function("f", fn_ty) == fn
|
||||
assert len([f for f in mod.functions if f.name.startswith("f")]) == 1
|
||||
expect_raises(lambda: mod.add_function("f", other_fn_ty), "different type")
|
||||
raw_fn = mod.add_function("f", fn_ty, get_or_insert=False)
|
||||
raw_fn = mod.add_function("f", fn_ty, reuse_existing=False)
|
||||
assert raw_fn.name != "f"
|
||||
|
||||
g = mod.add_global(i32, "g")
|
||||
@@ -44,7 +44,7 @@ def test_module_add_get_or_insert_semantics() -> None:
|
||||
lambda: mod.add_global_in_address_space(i32, "g", 1),
|
||||
"address space",
|
||||
)
|
||||
raw_g = mod.add_global(i32, "g", get_or_insert=False)
|
||||
raw_g = mod.add_global(i32, "g", reuse_existing=False)
|
||||
assert raw_g.name != "g"
|
||||
|
||||
expect_raises(lambda: mod.add_function("g", fn_ty), "global variable")
|
||||
@@ -53,7 +53,7 @@ def test_module_add_get_or_insert_semantics() -> None:
|
||||
alias = mod.add_alias(i32, 0, g, "alias")
|
||||
assert mod.add_alias(i32, 0, g, "alias") == alias
|
||||
expect_raises(lambda: mod.add_alias(i64, 0, g, "alias"), "different type")
|
||||
raw_alias = mod.add_alias(i32, 0, g, "alias", get_or_insert=False)
|
||||
raw_alias = mod.add_alias(i32, 0, g, "alias", reuse_existing=False)
|
||||
assert raw_alias.name != "alias"
|
||||
|
||||
resolver = mod.add_function("resolver", resolver_ty)
|
||||
@@ -69,12 +69,12 @@ def test_module_add_get_or_insert_semantics() -> None:
|
||||
"different resolver",
|
||||
)
|
||||
raw_ifunc = mod.add_global_ifunc(
|
||||
"ifunc", resolver_ty, 0, resolver, get_or_insert=False
|
||||
"ifunc", resolver_ty, 0, resolver, reuse_existing=False
|
||||
)
|
||||
assert raw_ifunc.name != "ifunc"
|
||||
|
||||
|
||||
def test_named_struct_get_or_insert_semantics() -> None:
|
||||
def test_named_struct_reuse_existing_semantics() -> None:
|
||||
with llvm.create_context() as ctx:
|
||||
i32 = ctx.types.i32
|
||||
i64 = ctx.types.i64
|
||||
@@ -93,7 +93,7 @@ def test_named_struct_get_or_insert_semantics() -> None:
|
||||
)
|
||||
|
||||
raw_pair = ctx.types.struct(
|
||||
"Pair", [i32, i64], packed=False, get_or_insert=False
|
||||
"Pair", [i32, i64], packed=False, reuse_existing=False
|
||||
)
|
||||
assert raw_pair != pair
|
||||
assert raw_pair.struct_name != "Pair"
|
||||
@@ -105,7 +105,7 @@ def test_named_struct_get_or_insert_semantics() -> None:
|
||||
assert completed == forward
|
||||
assert not completed.is_opaque_struct
|
||||
|
||||
raw_forward = ctx.types.opaque_struct("Forward", get_or_insert=False)
|
||||
raw_forward = ctx.types.opaque_struct("Forward", reuse_existing=False)
|
||||
assert raw_forward != forward
|
||||
assert raw_forward.struct_name != "Forward"
|
||||
|
||||
@@ -205,6 +205,18 @@ def test_member_factories_and_builder_navigation() -> None:
|
||||
with mod.create_builder(ret) as before_ret:
|
||||
assert before_ret.insert_block == bb
|
||||
|
||||
assert not hasattr(mod, "get_or_insert_named_metadata")
|
||||
named_md = mod.add_named_metadata("llvm.nanobind.surface")
|
||||
assert mod.add_named_metadata("llvm.nanobind.surface") == named_md
|
||||
|
||||
assert not hasattr(mod, "get_or_insert_comdat")
|
||||
comdat = mod.add_comdat("surface_comdat")
|
||||
comdat.selection_kind = llvm.ComdatSelectionKind.ExactMatch
|
||||
assert (
|
||||
mod.add_comdat("surface_comdat").selection_kind
|
||||
== llvm.ComdatSelectionKind.ExactMatch
|
||||
)
|
||||
|
||||
opts = llvm.PassBuilderOptions()
|
||||
mod.run_passes("default<O0>", options=opts)
|
||||
|
||||
@@ -223,7 +235,7 @@ def test_member_factories_and_builder_navigation() -> None:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_module_add_get_or_insert_semantics()
|
||||
test_named_struct_get_or_insert_semantics()
|
||||
test_module_add_reuse_existing_semantics()
|
||||
test_named_struct_reuse_existing_semantics()
|
||||
test_member_factories_and_builder_navigation()
|
||||
print("test_api_surface_cleanup: PASSED")
|
||||
|
||||
@@ -282,8 +282,8 @@ def test_lifetime_guards_for_remaining_wrappers():
|
||||
i32 = ctx.types.i32
|
||||
escaped["types"] = ctx.types
|
||||
escaped["attr"] = ctx.create_string_attribute("k", "v")
|
||||
escaped["comdat"] = mod.get_or_insert_comdat("C")
|
||||
escaped["named_md"] = mod.get_or_insert_named_metadata("llvm.nanobind.named")
|
||||
escaped["comdat"] = mod.add_comdat("C")
|
||||
escaped["named_md"] = mod.add_named_metadata("llvm.nanobind.named")
|
||||
|
||||
fn_ty = ctx.types.function(i32, [i32], False)
|
||||
fn = mod.add_function("f", fn_ty)
|
||||
|
||||
@@ -827,7 +827,7 @@ def test_value_accessor_guard_matrix_negative():
|
||||
"global value",
|
||||
),
|
||||
("comdat", lambda: bad.comdat, "global object"),
|
||||
("set_comdat", lambda: bad.set_comdat(mod.get_or_insert_comdat("x")), "global object"),
|
||||
("set_comdat", lambda: bad.set_comdat(mod.add_comdat("x")), "global object"),
|
||||
("section", lambda: bad.section, "global object"),
|
||||
("section", lambda: setattr(bad, "section", ".foo"), "global object"),
|
||||
("set_thread_local", lambda: bad.set_thread_local(True), "global variable"),
|
||||
@@ -1155,7 +1155,7 @@ def test_value_accessor_guard_matrix_positive():
|
||||
assert g0.is_thread_local
|
||||
g0.set_externally_initialized(True)
|
||||
assert g0.is_externally_initialized
|
||||
c = mod.get_or_insert_comdat("value_guard_positive_comdat")
|
||||
c = mod.add_comdat("value_guard_positive_comdat")
|
||||
g0.set_comdat(c)
|
||||
assert g0.comdat is not None
|
||||
g_del = mod.add_global(ctx.types.i32, "g_del")
|
||||
|
||||
@@ -382,8 +382,8 @@ def test_comdat():
|
||||
"""Test all Comdat APIs"""
|
||||
with llvm.create_context() as ctx:
|
||||
with ctx.create_module("test") as mod:
|
||||
# Test get_or_insert_comdat
|
||||
comdat = mod.get_or_insert_comdat("my_comdat")
|
||||
# Test add_comdat get-or-insert behavior
|
||||
comdat = mod.add_comdat("my_comdat")
|
||||
assert comdat is not None
|
||||
|
||||
# Test selection_kind property (getter and setter)
|
||||
|
||||
Reference in New Issue
Block a user