Commit 55c9ae1193
Changed files (2)
src/codegen.cpp
@@ -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;
}
src/parser.cpp
@@ -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);
}
/*