From 9b7d9c72b09bc268338b66e708b33213bbaae675 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 29 Oct 2020 10:24:03 +0100 Subject: stage1: Initial implementation of @extern --- src/stage1/codegen.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/stage1/codegen.cpp') diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 4a999b33ca..d22fb91b67 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -6389,6 +6389,30 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutableGen *executable, IrI return LLVMBuildTrunc(g->builder, shifted, get_llvm_type(g, expr_type), ""); } +static LLVMValueRef ir_render_extern(CodeGen *g, IrExecutableGen *executable, + IrInstGenExtern *instruction) +{ + ZigType *expr_type = instruction->base.value->type; + assert(get_src_ptr_type(expr_type)); + + const char *symbol_name = buf_ptr(instruction->name); + const LLVMLinkage linkage = to_llvm_linkage(instruction->linkage, true); + + LLVMValueRef global_value = LLVMGetNamedGlobal(g->module, symbol_name); + if (global_value == nullptr) { + global_value = LLVMAddGlobal(g->module, get_llvm_type(g, expr_type), symbol_name); + LLVMSetLinkage(global_value, linkage); + LLVMSetGlobalConstant(global_value, true); + if (instruction->is_thread_local) + LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel); + } else if (LLVMGetLinkage(global_value) != linkage) { + // XXX: Handle this case better! + zig_panic("duplicate extern symbol"); + } + + return LLVMBuildBitCast(g->builder, global_value, get_llvm_type(g, expr_type), ""); +} + static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutableGen *executable, IrInstGenBitReverse *instruction) { LLVMValueRef op = ir_llvm_value(g, instruction->op); ZigType *int_type = instruction->base.value->type; @@ -6902,6 +6926,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl return ir_render_wasm_memory_size(g, executable, (IrInstGenWasmMemorySize *) instruction); case IrInstGenIdWasmMemoryGrow: return ir_render_wasm_memory_grow(g, executable, (IrInstGenWasmMemoryGrow *) instruction); + case IrInstGenIdExtern: + return ir_render_extern(g, executable, (IrInstGenExtern *) instruction); } zig_unreachable(); } @@ -8800,6 +8826,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdAlignCast, "alignCast", 2); create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1); create_builtin_fn(g, BuiltinFnIdExport, "export", 2); + create_builtin_fn(g, BuiltinFnIdExtern, "extern1", 2); create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0); create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5); create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3); -- cgit v1.2.3 From ccdaf946b969661220737ec747e5a720b13d0bc7 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 21 Nov 2020 09:48:21 +0100 Subject: Rename back to extern, extend a stage1 parser hack Make it recognize extern/export symbols prefixed by @ as a builtin rather than stand-alone keywords. --- src/stage1/codegen.cpp | 2 +- src/stage1/parser.cpp | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/stage1/codegen.cpp') diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index d22fb91b67..26fe00228e 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -8826,7 +8826,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdAlignCast, "alignCast", 2); create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1); create_builtin_fn(g, BuiltinFnIdExport, "export", 2); - create_builtin_fn(g, BuiltinFnIdExtern, "extern1", 2); + create_builtin_fn(g, BuiltinFnIdExtern, "extern", 2); create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0); create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5); create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3); diff --git a/src/stage1/parser.cpp b/src/stage1/parser.cpp index a49773e9ca..eab4ea0f77 100644 --- a/src/stage1/parser.cpp +++ b/src/stage1/parser.cpp @@ -1652,18 +1652,21 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) { // TODO: This is not in line with the grammar. // Because the prev stage 1 tokenizer does not parse // @[a-zA-Z_][a-zA-Z0-9_] as one token, it has to do a - // hack, where it accepts '@' (IDENTIFIER / KEYWORD_export). + // hack, where it accepts '@' (IDENTIFIER / KEYWORD_export / + // KEYWORD_extern). // I'd say that it's better if '@' is part of the builtin // identifier token. Token *at_sign = eat_token_if(pc, TokenIdAtSign); if (at_sign != nullptr) { Buf *name; - Token *token = eat_token_if(pc, TokenIdKeywordExport); - if (token == nullptr) { + Token *token; + if ((token = eat_token_if(pc, TokenIdKeywordExport)) != nullptr) { + name = buf_create_from_str("export"); + } else if ((token = eat_token_if(pc, TokenIdKeywordExtern)) != nullptr) { + name = buf_create_from_str("extern"); + } else { token = expect_token(pc, TokenIdSymbol); name = token_buf(token); - } else { - name = buf_create_from_str("export"); } AstNode *res = ast_expect(pc, ast_parse_fn_call_arguments); -- cgit v1.2.3