mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 00:35:10 +00:00
codegen extern global variables correctly
This commit is contained in:
parent
3c2093fec6
commit
55c9ae1193
@ -2533,26 +2533,34 @@ static void do_code_gen(CodeGen *g) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO if the global is exported, set external linkage
|
||||
LLVMValueRef init_val;
|
||||
|
||||
assert(var->decl_node);
|
||||
assert(var->decl_node->type == NodeTypeVariableDeclaration);
|
||||
AstNode *expr_node = var->decl_node->data.variable_declaration.expr;
|
||||
if (expr_node) {
|
||||
Expr *expr = get_resolved_expr(expr_node);
|
||||
ConstExprValue *const_val = &expr->const_val;
|
||||
assert(const_val->ok);
|
||||
TypeTableEntry *type_entry = expr->type_entry;
|
||||
init_val = gen_const_val(g, type_entry, const_val);
|
||||
|
||||
LLVMValueRef global_value;
|
||||
if (var->decl_node->data.variable_declaration.is_extern) {
|
||||
global_value = LLVMAddGlobal(g->module, var->type->type_ref, buf_ptr(&var->name));
|
||||
|
||||
LLVMSetLinkage(global_value, LLVMExternalLinkage);
|
||||
} else {
|
||||
init_val = LLVMConstNull(var->type->type_ref);
|
||||
AstNode *expr_node = var->decl_node->data.variable_declaration.expr;
|
||||
LLVMValueRef init_val;
|
||||
if (expr_node) {
|
||||
Expr *expr = get_resolved_expr(expr_node);
|
||||
ConstExprValue *const_val = &expr->const_val;
|
||||
assert(const_val->ok);
|
||||
TypeTableEntry *type_entry = expr->type_entry;
|
||||
init_val = gen_const_val(g, type_entry, const_val);
|
||||
} else {
|
||||
init_val = LLVMConstNull(var->type->type_ref);
|
||||
}
|
||||
|
||||
global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), buf_ptr(&var->name));
|
||||
LLVMSetInitializer(global_value, init_val);
|
||||
LLVMSetLinkage(global_value, LLVMInternalLinkage);
|
||||
LLVMSetUnnamedAddr(global_value, true);
|
||||
}
|
||||
LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), buf_ptr(&var->name));
|
||||
LLVMSetInitializer(global_value, init_val);
|
||||
|
||||
LLVMSetGlobalConstant(global_value, var->is_const);
|
||||
LLVMSetUnnamedAddr(global_value, true);
|
||||
LLVMSetLinkage(global_value, LLVMInternalLinkage);
|
||||
|
||||
var->value_ref = global_value;
|
||||
}
|
||||
|
||||
@ -2256,7 +2256,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandat
|
||||
}
|
||||
|
||||
/*
|
||||
ExternDecl : "extern" FnProto ";"
|
||||
ExternDecl = "extern" (FnProto | VariableDeclaration) ";"
|
||||
*/
|
||||
static AstNode *ast_parse_extern_decl(ParseContext *pc, int *token_index, bool mandatory,
|
||||
ZigList<AstNode *> *directives, VisibMod visib_mod)
|
||||
@ -2271,13 +2271,28 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, int *token_index, bool m
|
||||
}
|
||||
*token_index += 1;
|
||||
|
||||
AstNode *node = ast_parse_fn_proto(pc, token_index, true, directives, visib_mod);
|
||||
AstNode *fn_proto_node = ast_parse_fn_proto(pc, token_index, false, directives, visib_mod);
|
||||
if (fn_proto_node) {
|
||||
ast_eat_token(pc, token_index, TokenIdSemicolon);
|
||||
|
||||
ast_eat_token(pc, token_index, TokenIdSemicolon);
|
||||
fn_proto_node->data.fn_proto.is_extern = true;
|
||||
|
||||
node->data.fn_proto.is_extern = true;
|
||||
normalize_parent_ptrs(node);
|
||||
return node;
|
||||
normalize_parent_ptrs(fn_proto_node);
|
||||
return fn_proto_node;
|
||||
}
|
||||
|
||||
AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, directives, visib_mod);
|
||||
if (var_decl_node) {
|
||||
ast_eat_token(pc, token_index, TokenIdSemicolon);
|
||||
|
||||
var_decl_node->data.variable_declaration.is_extern = true;
|
||||
|
||||
normalize_parent_ptrs(var_decl_node);
|
||||
return var_decl_node;
|
||||
}
|
||||
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
ast_invalid_token_error(pc, token);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user