extern variables and object-like macro consts

This commit is contained in:
2026-06-17 21:52:05 +02:00
parent f5605fd3ec
commit 19e9fbdd4b
33 changed files with 3136 additions and 116 deletions
+43 -5
View File
@@ -600,7 +600,15 @@ emit_instruction_stream :: proc(
emit_recovery_value(emitter, instruction_index, instruction, "invalid global reference type")
continue
}
if global.is_static {
if global.external {
fmt.sbprintf(
&emitter.builder,
" %%v%d = load %s, ptr @%s\n",
instruction_index,
llvm_type(global.type, &emitter.module.types),
global.link_name,
)
} else if global.is_static {
fmt.sbprintf(
&emitter.builder,
" %%v%d = load %s, ptr @bro.g.%d\n",
@@ -632,6 +640,15 @@ emit_instruction_stream :: proc(
emit_recovery_value(emitter, instruction_index, instruction, "invalid global address")
continue
}
global := emitter.module.globals[global_id]
if global.external {
fmt.sbprintf(
&emitter.builder,
" %%v%d = getelementptr %s, ptr @%s, i64 0\n",
instruction_index, llvm_type(instruction.type, &emitter.module.types), global.link_name,
)
continue
}
fmt.sbprintf(
&emitter.builder,
" %%v%d = getelementptr %s, ptr @bro.g.%d, i64 0\n",
@@ -1369,7 +1386,28 @@ emit_instruction_stream :: proc(
emit_globals :: proc(emitter: ^Emitter) {
for global, global_id in emitter.module.globals {
if global.is_static {
if global.external {
if global.problematic {
continue
}
duplicate := false
for previous in emitter.module.globals[:global_id] {
if previous.external && !previous.problematic && previous.link_name == global.link_name {
duplicate = true
break
}
}
if duplicate {
continue
}
fmt.sbprintf(
&emitter.builder,
"@%s = external %s %s\n",
global.link_name,
"global" if global.writable else "constant",
llvm_type(global.type, &emitter.module.types),
)
} else if global.is_static {
fmt.sbprintf(
&emitter.builder,
"@bro.g.%d = internal constant %s ",
@@ -1462,7 +1500,7 @@ emit_strings :: proc(emitter: ^Emitter) {
emit_global_accessors :: proc(emitter: ^Emitter) {
placeholder_function := ir.Function{result=types.I64}
for global, global_id in emitter.module.globals {
if global.is_static {
if global.is_static || global.external {
continue
}
type_name := llvm_type(global.type, &emitter.module.types)
@@ -1500,7 +1538,7 @@ emit_global_accessors :: proc(emitter: ^Emitter) {
emit_constructor :: proc(emitter: ^Emitter) {
count := 0
for global in emitter.module.globals {
if !global.is_static && !global.problematic {
if !global.is_static && !global.external && !global.problematic {
count += 1
}
}
@@ -1513,7 +1551,7 @@ emit_constructor :: proc(emitter: ^Emitter) {
)
strings.write_string(&emitter.builder, "define internal void @bro.init() {\nentry:\n")
for global, global_id in emitter.module.globals {
if !global.is_static && !global.problematic {
if !global.is_static && !global.external && !global.problematic {
fmt.sbprintf(&emitter.builder, " %%g%d = call %s @bro.get.%d()\n", global_id, llvm_type(global.type, &emitter.module.types), global_id)
}
}