diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-01-18 08:50:10 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-01-18 08:50:10 -0700 |
| commit | 3a326d50051ad8b65639e5e2bbe45e41a8b35591 (patch) | |
| tree | 797dc5661ae401c4d75971fb8c722a8834cfb2c9 /src/codegen.cpp | |
| parent | 4c50606b9d41c2c3d9f25dc8bf0848e30e338f6e (diff) | |
| download | zig-3a326d50051ad8b65639e5e2bbe45e41a8b35591.tar.gz zig-3a326d50051ad8b65639e5e2bbe45e41a8b35591.zip | |
pave the road for function pointers
See #14
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 107 |
1 files changed, 11 insertions, 96 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 72c5017d29..8de5fba4e5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -82,29 +82,13 @@ static TypeTableEntry *get_type_for_type_node(AstNode *node) { return const_val->data.x_type; } -static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_node) { - TypeTableEntry *type_entry = get_type_for_type_node(type_node); - - if (type_entry->id == TypeTableEntryIdStruct || type_entry->id == TypeTableEntryIdArray) { - return get_pointer_to_type(g, type_entry, true); - } else { - return type_entry; - } -} - -static LLVMZigDIType *to_llvm_debug_type(CodeGen *g, AstNode *type_node) { - TypeTableEntry *type_entry = get_type_for_type_node(type_node); - return type_entry->di_type; -} - - static bool type_is_unreachable(CodeGen *g, AstNode *type_node) { return get_type_for_type_node(type_node)->id == TypeTableEntryIdUnreachable; } static bool is_param_decl_type_void(CodeGen *g, AstNode *param_decl_node) { assert(param_decl_node->type == NodeTypeParamDecl); - return get_type_for_type_node(param_decl_node->data.param_decl.type)->id == TypeTableEntryIdVoid; + return get_type_for_type_node(param_decl_node->data.param_decl.type)->size_in_bits == 0; } static int count_non_void_params(CodeGen *g, ZigList<AstNode *> *params) { @@ -150,11 +134,14 @@ static TypeTableEntry *get_expr_type(AstNode *node) { return expr->type_entry; } -static bool handle_is_ptr(TypeTableEntry *type_entry) { - return type_entry->id == TypeTableEntryIdStruct || - (type_entry->id == TypeTableEntryIdEnum && type_entry->data.enumeration.gen_field_count != 0) || - type_entry->id == TypeTableEntryIdMaybe || - type_entry->id == TypeTableEntryIdArray; +static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_node) { + TypeTableEntry *type_entry = get_type_for_type_node(type_node); + + if (handle_is_ptr(type_entry)) { + return get_pointer_to_type(g, type_entry, true); + } else { + return type_entry; + } } static LLVMValueRef gen_number_literal_raw(CodeGen *g, AstNode *source_node, @@ -2121,31 +2108,6 @@ static void build_label_blocks(CodeGen *g, AstNode *block_node) { } -static LLVMZigDISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto, - LLVMZigDIFile *di_file) -{ - LLVMZigDIType **types = allocate<LLVMZigDIType*>(1 + fn_proto->params.length); - types[0] = to_llvm_debug_type(g, fn_proto->return_type); - int types_len = fn_proto->params.length + 1; - for (int i = 0; i < fn_proto->params.length; i += 1) { - AstNode *param_node = fn_proto->params.at(i); - assert(param_node->type == NodeTypeParamDecl); - LLVMZigDIType *param_type = to_llvm_debug_type(g, param_node->data.param_decl.type); - types[i + 1] = param_type; - } - return LLVMZigCreateSubroutineType(g->dbuilder, di_file, types, types_len, 0); -} - -static LLVMAttribute to_llvm_fn_attr(FnAttrId attr_id) { - switch (attr_id) { - case FnAttrIdNaked: - return LLVMNakedAttribute; - case FnAttrIdAlwaysInline: - return LLVMAlwaysInlineAttribute; - } - zig_unreachable(); -} - static void do_code_gen(CodeGen *g) { assert(!g->errors.length); @@ -2172,45 +2134,12 @@ static void do_code_gen(CodeGen *g) { // Generate function prototypes for (int fn_proto_i = 0; fn_proto_i < g->fn_protos.length; fn_proto_i += 1) { FnTableEntry *fn_table_entry = g->fn_protos.at(fn_proto_i); - AstNode *proto_node = fn_table_entry->proto_node; assert(proto_node->type == NodeTypeFnProto); AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; - LLVMTypeRef ret_type = get_type_for_type_node(fn_proto->return_type)->type_ref; - int param_count = count_non_void_params(g, &fn_proto->params); - LLVMTypeRef *param_types = allocate<LLVMTypeRef>(param_count); - int gen_param_index = 0; - for (int param_decl_i = 0; param_decl_i < fn_proto->params.length; param_decl_i += 1) { - AstNode *param_node = fn_proto->params.at(param_decl_i); - assert(param_node->type == NodeTypeParamDecl); - if (is_param_decl_type_void(g, param_node)) - continue; - AstNode *type_node = param_node->data.param_decl.type; - param_types[gen_param_index] = fn_proto_type_from_type_node(g, type_node)->type_ref; - gen_param_index += 1; - } - LLVMTypeRef function_type = LLVMFunctionType(ret_type, param_types, param_count, fn_proto->is_var_args); - - LLVMValueRef fn = LLVMAddFunction(g->module, buf_ptr(&fn_table_entry->symbol_name), function_type); - - for (int attr_i = 0; attr_i < fn_table_entry->fn_attr_list.length; attr_i += 1) { - FnAttrId attr_id = fn_table_entry->fn_attr_list.at(attr_i); - LLVMAddFunctionAttr(fn, to_llvm_fn_attr(attr_id)); - } - - LLVMSetLinkage(fn, fn_table_entry->internal_linkage ? LLVMInternalLinkage : LLVMExternalLinkage); - - if (type_is_unreachable(g, fn_proto->return_type)) { - LLVMAddFunctionAttr(fn, LLVMNoReturnAttribute); - } - LLVMSetFunctionCallConv(fn, fn_table_entry->calling_convention); - if (!fn_table_entry->is_extern) { - LLVMAddFunctionAttr(fn, LLVMNoUnwindAttribute); - } - // set parameter attributes - gen_param_index = 0; + int gen_param_index = 0; for (int param_decl_i = 0; param_decl_i < fn_proto->params.length; param_decl_i += 1) { AstNode *param_node = fn_proto->params.at(param_decl_i); assert(param_node->type == NodeTypeParamDecl); @@ -2218,7 +2147,7 @@ static void do_code_gen(CodeGen *g) { continue; AstNode *type_node = param_node->data.param_decl.type; TypeTableEntry *param_type = fn_proto_type_from_type_node(g, type_node); - LLVMValueRef argument_val = LLVMGetParam(fn, gen_param_index); + LLVMValueRef argument_val = LLVMGetParam(fn_table_entry->fn_value, gen_param_index); bool param_is_noalias = param_node->data.param_decl.is_noalias; if (param_type->id == TypeTableEntryIdPointer && param_is_noalias) { LLVMAddAttribute(argument_val, LLVMNoAliasAttribute); @@ -2230,7 +2159,6 @@ static void do_code_gen(CodeGen *g) { gen_param_index += 1; } - fn_table_entry->fn_value = fn; } // Generate function definitions. @@ -2245,22 +2173,9 @@ static void do_code_gen(CodeGen *g) { assert(proto_node->type == NodeTypeFnProto); AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; - // Add debug info. - unsigned line_number = fn_def_node->line + 1; - unsigned scope_line = line_number; - bool is_definition = true; - unsigned flags = 0; - bool is_optimized = g->build_type == CodeGenBuildTypeRelease; - LLVMZigDISubprogram *subprogram = LLVMZigCreateFunction(g->dbuilder, - import->block_context->di_scope, buf_ptr(&fn_table_entry->symbol_name), "", - import->di_file, line_number, - create_di_function_type(g, fn_proto, import->di_file), fn_table_entry->internal_linkage, - is_definition, scope_line, flags, is_optimized, fn); - LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry"); LLVMPositionBuilderAtEnd(g->builder, entry_block); - fn_def_node->data.fn_def.block_context->di_scope = LLVMZigSubprogramToScope(subprogram); AstNode *body_node = fn_def_node->data.fn_def.body; build_label_blocks(g, body_node); |
