authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-31 01:51:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-31 01:51:33-07:00
log55c9ae119382add2b840ae6526884bc9d99c9994
treecfb3d6c0e89ca756c50ec6113b55c3c2bf068f3c
parent3c2093fec64c38b2895fb162b7fe58e6ec232bc6

codegen extern global variables correctly


2 files changed, 44 insertions(+), 21 deletions(-)

src/codegen.cpp+23-15
...@@ -2533,26 +2533,34 @@ static void do_code_gen(CodeGen *g) {...@@ -2533,26 +2533,34 @@ static void do_code_gen(CodeGen *g) {
2533 continue;2533 continue;
2534 }2534 }
25352535
2536 // TODO if the global is exported, set external linkage
2537 LLVMValueRef init_val;
2538
2539 assert(var->decl_node);2536 assert(var->decl_node);
2540 assert(var->decl_node->type == NodeTypeVariableDeclaration);2537 assert(var->decl_node->type == NodeTypeVariableDeclaration);
2541 AstNode *expr_node = var->decl_node->data.variable_declaration.expr;2538
2542 if (expr_node) {2539 LLVMValueRef global_value;
2543 Expr *expr = get_resolved_expr(expr_node);2540 if (var->decl_node->data.variable_declaration.is_extern) {
2544 ConstExprValue *const_val = &expr->const_val;2541 global_value = LLVMAddGlobal(g->module, var->type->type_ref, buf_ptr(&var->name));
2545 assert(const_val->ok);2542
2546 TypeTableEntry *type_entry = expr->type_entry;2543 LLVMSetLinkage(global_value, LLVMExternalLinkage);
2547 init_val = gen_const_val(g, type_entry, const_val);
2548 } else {2544 } else {
2549 init_val = LLVMConstNull(var->type->type_ref);2545 AstNode *expr_node = var->decl_node->data.variable_declaration.expr;
2546 LLVMValueRef init_val;
2547 if (expr_node) {
2548 Expr *expr = get_resolved_expr(expr_node);
2549 ConstExprValue *const_val = &expr->const_val;
2550 assert(const_val->ok);
2551 TypeTableEntry *type_entry = expr->type_entry;
2552 init_val = gen_const_val(g, type_entry, const_val);
2553 } else {
2554 init_val = LLVMConstNull(var->type->type_ref);
2555 }
2556
2557 global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), buf_ptr(&var->name));
2558 LLVMSetInitializer(global_value, init_val);
2559 LLVMSetLinkage(global_value, LLVMInternalLinkage);
2560 LLVMSetUnnamedAddr(global_value, true);
2550 }2561 }
2551 LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), buf_ptr(&var->name));2562
2552 LLVMSetInitializer(global_value, init_val);
2553 LLVMSetGlobalConstant(global_value, var->is_const);2563 LLVMSetGlobalConstant(global_value, var->is_const);
2554 LLVMSetUnnamedAddr(global_value, true);
2555 LLVMSetLinkage(global_value, LLVMInternalLinkage);
25562564
2557 var->value_ref = global_value;2565 var->value_ref = global_value;
2558 }2566 }
src/parser.cpp+21-6
...@@ -2256,7 +2256,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandat...@@ -2256,7 +2256,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandat
2256}2256}
22572257
2258/*2258/*
2259ExternDecl : "extern" FnProto ";"2259ExternDecl = "extern" (FnProto | VariableDeclaration) ";"
2260*/2260*/
2261static AstNode *ast_parse_extern_decl(ParseContext *pc, int *token_index, bool mandatory,2261static AstNode *ast_parse_extern_decl(ParseContext *pc, int *token_index, bool mandatory,
2262 ZigList<AstNode *> *directives, VisibMod visib_mod)2262 ZigList<AstNode *> *directives, VisibMod visib_mod)
...@@ -2271,13 +2271,28 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, int *token_index, bool m...@@ -2271,13 +2271,28 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, int *token_index, bool m
2271 }2271 }
2272 *token_index += 1;2272 *token_index += 1;
22732273
2274 AstNode *node = ast_parse_fn_proto(pc, token_index, true, directives, visib_mod);2274 AstNode *fn_proto_node = ast_parse_fn_proto(pc, token_index, false, directives, visib_mod);
2275 if (fn_proto_node) {
2276 ast_eat_token(pc, token_index, TokenIdSemicolon);
22752277
2276 ast_eat_token(pc, token_index, TokenIdSemicolon);2278 fn_proto_node->data.fn_proto.is_extern = true;
22772279
2278 node->data.fn_proto.is_extern = true;2280 normalize_parent_ptrs(fn_proto_node);
2279 normalize_parent_ptrs(node);2281 return fn_proto_node;
2280 return node;2282 }
2283
2284 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, directives, visib_mod);
2285 if (var_decl_node) {
2286 ast_eat_token(pc, token_index, TokenIdSemicolon);
2287
2288 var_decl_node->data.variable_declaration.is_extern = true;
2289
2290 normalize_parent_ptrs(var_decl_node);
2291 return var_decl_node;
2292 }
2293
2294 Token *token = &pc->tokens->at(*token_index);
2295 ast_invalid_token_error(pc, token);
2281}2296}
22822297
2283/*2298/*