IR: support import builtin function

master
Andrew Kelley 2016-11-26 20:52:22 -05:00
parent 4619b5de06
commit 84f7805029
9 changed files with 422 additions and 1085 deletions

View File

@ -117,12 +117,6 @@ enum ReturnKnowledge {
ReturnKnowledgeSkipDefers,
};
struct Expr {
IrInstruction *instruction;
ReturnKnowledge return_knowledge;
VariableTableEntry *variable;
};
struct StructValExprCodeGen {
TypeTableEntry *type_entry;
LLVMValueRef ptr;
@ -152,6 +146,7 @@ struct TopLevelDecl {
bool dep_loop_flag;
TldResolution resolution;
AstNode *parent_decl;
IrInstruction *value;
};
struct TypeEnumField {
@ -232,7 +227,6 @@ struct AstNodeFnProto {
AstNode *fn_def_node;
FnTableEntry *fn_table_entry;
bool skip;
Expr resolved_expr;
// computed from params field
size_t inline_arg_count;
size_t inline_or_var_type_arg_count;
@ -274,7 +268,6 @@ struct AstNodeBlock {
// you can follow its parents up to child_block. it will equal
// child_block if there are no defers or var decls in the block.
BlockContext *nested_block;
Expr resolved_expr;
};
enum ReturnKind {
@ -287,9 +280,6 @@ struct AstNodeReturnExpr {
ReturnKind kind;
// might be null in case of return void;
AstNode *expr;
// populated by semantic analyzer:
Expr resolved_expr;
};
struct AstNodeDefer {
@ -297,7 +287,6 @@ struct AstNodeDefer {
AstNode *expr;
// populated by semantic analyzer:
Expr resolved_expr;
size_t index_in_block;
LLVMBasicBlockRef basic_block;
BlockContext *child_block;
@ -314,7 +303,6 @@ struct AstNodeVariableDeclaration {
AstNode *expr;
// populated by semantic analyzer
Expr resolved_expr;
VariableTableEntry *variable;
};
@ -392,7 +380,6 @@ struct AstNodeBinOpExpr {
// populated by semantic analyzer:
// for when op is BinOpTypeAssign
VariableTableEntry *var_entry;
Expr resolved_expr;
};
struct AstNodeUnwrapErrorExpr {
@ -401,7 +388,6 @@ struct AstNodeUnwrapErrorExpr {
AstNode *op2;
// populated by semantic analyzer:
Expr resolved_expr;
VariableTableEntry *var;
};
@ -434,7 +420,6 @@ struct AstNodeFnCallExpr {
// populated by semantic analyzer:
BuiltinFnEntry *builtin_fn;
Expr resolved_expr;
FnTableEntry *fn_entry;
CastOp cast_op;
// if cast_op is CastOpArrayToString, this will be a pointer to
@ -447,7 +432,6 @@ struct AstNodeArrayAccessExpr {
AstNode *subscript;
// populated by semantic analyzer:
Expr resolved_expr;
};
struct AstNodeSliceExpr {
@ -457,7 +441,6 @@ struct AstNodeSliceExpr {
bool is_const;
// populated by semantic analyzer:
Expr resolved_expr;
StructValExprCodeGen resolved_struct_val_expr;
};
@ -468,7 +451,6 @@ struct AstNodeFieldAccessExpr {
// populated by semantic analyzer
TypeStructField *type_struct_field;
TypeEnumField *type_enum_field;
Expr resolved_expr;
StructValExprCodeGen resolved_struct_val_expr; // for enum values
TypeTableEntry *bare_container_type;
bool is_member_fn;
@ -495,7 +477,6 @@ struct AstNodePrefixOpExpr {
AstNode *primary_expr;
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeUse {
@ -511,7 +492,6 @@ struct AstNodeIfBoolExpr {
AstNode *else_node; // null, block node, or other if expr node
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeIfVarExpr {
@ -522,7 +502,6 @@ struct AstNodeIfVarExpr {
// populated by semantic analyzer
TypeTableEntry *type;
Expr resolved_expr;
};
struct AstNodeWhileExpr {
@ -535,7 +514,6 @@ struct AstNodeWhileExpr {
bool condition_always_true;
bool contains_break;
bool contains_continue;
Expr resolved_expr;
};
struct AstNodeForExpr {
@ -549,7 +527,6 @@ struct AstNodeForExpr {
// populated by semantic analyzer
bool contains_break;
bool contains_continue;
Expr resolved_expr;
VariableTableEntry *elem_var;
VariableTableEntry *index_var;
};
@ -560,7 +537,6 @@ struct AstNodeSwitchExpr {
bool is_inline;
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeSwitchProng {
@ -580,7 +556,6 @@ struct AstNodeLabel {
Buf *name;
// populated by semantic analyzer
Expr resolved_expr;
LabelTableEntry *label_entry;
};
@ -588,7 +563,6 @@ struct AstNodeGoto {
Buf *name;
// populated by semantic analyzer
Expr resolved_expr;
LabelTableEntry *label_entry;
};
@ -634,7 +608,6 @@ struct AstNodeAsmExpr {
ZigList<Buf*> clobber_list;
// populated by semantic analyzer
Expr resolved_expr;
};
enum ContainerKind {
@ -670,14 +643,12 @@ struct AstNodeStringLiteral {
bool c;
// populated by semantic analyzer:
Expr resolved_expr;
};
struct AstNodeCharLiteral {
uint8_t value;
// populated by semantic analyzer:
Expr resolved_expr;
};
struct AstNodeNumberLiteral {
@ -688,7 +659,6 @@ struct AstNodeNumberLiteral {
bool overflow;
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeStructValueField {
@ -711,35 +681,29 @@ struct AstNodeContainerInitExpr {
// populated by semantic analyzer
StructValExprCodeGen resolved_struct_val_expr;
Expr resolved_expr;
TypeTableEntry *enum_type;
};
struct AstNodeNullLiteral {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeUndefinedLiteral {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeZeroesLiteral {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeThisLiteral {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeSymbolExpr {
Buf *symbol;
// populated by semantic analyzer
Expr resolved_expr;
TypeEnumField *enum_field;
uint32_t err_value;
};
@ -748,17 +712,14 @@ struct AstNodeBoolLiteral {
bool value;
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeBreakExpr {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeContinueExpr {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeArrayType {
@ -767,22 +728,18 @@ struct AstNodeArrayType {
bool is_const;
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeErrorType {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeTypeLiteral {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNodeVarLiteral {
// populated by semantic analyzer
Expr resolved_expr;
};
struct AstNode {
@ -1329,7 +1286,6 @@ struct CodeGen {
LLVMValueRef err_name_table;
IrInstruction *invalid_instruction;
Buf *len_buf;
};
struct VariableTableEntry {
@ -1389,9 +1345,6 @@ struct BlockContext {
ZigLLVMDIScope *di_scope;
Buf *c_import_buf;
// if this is true, then this code will not be generated
bool codegen_excluded;
bool safety_off;
AstNode *safety_set_node;
};
@ -1433,7 +1386,6 @@ enum IrInstructionId {
IrInstructionIdStorePtr,
IrInstructionIdFieldPtr,
IrInstructionIdStructFieldPtr,
IrInstructionIdReadField,
IrInstructionIdElemPtr,
IrInstructionIdVarPtr,
IrInstructionIdCall,
@ -1460,6 +1412,8 @@ enum IrInstructionId {
IrInstructionIdClz,
IrInstructionIdCtz,
IrInstructionIdStaticEval,
IrInstructionIdImport,
IrInstructionIdArrayLen,
};
struct IrInstruction {
@ -1628,13 +1582,6 @@ struct IrInstructionStructFieldPtr {
bool is_const;
};
struct IrInstructionReadField {
IrInstruction base;
IrInstruction *container_ptr;
Buf *field_name;
};
struct IrInstructionElemPtr {
IrInstruction base;
@ -1816,6 +1763,18 @@ struct IrInstructionStaticEval {
IrInstruction *value;
};
struct IrInstructionImport {
IrInstruction base;
IrInstruction *name;
};
struct IrInstructionArrayLen {
IrInstruction base;
IrInstruction *array_value;
};
enum LValPurpose {
LValPurposeNone,
LValPurposeAssign,

View File

@ -19,7 +19,6 @@
static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type);
static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);
static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node);
AstNode *first_executing_node(AstNode *node) {
switch (node->type) {
@ -1670,7 +1669,7 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;
}
static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) {
void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) {
switch (node->type) {
case NodeTypeRoot:
for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
@ -1947,9 +1946,8 @@ static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node
implicit_type = g->builtin_types.entry_invalid;
}
if (implicit_type->id != TypeTableEntryIdInvalid) {
Expr *expr = get_resolved_expr(var_decl->expr);
assert(result->static_value.special != ConstValSpecialRuntime);
expr->instruction = result;
var_decl->top_level_decl.value = result;
}
} else if (!is_extern) {
add_node_error(g, node, buf_sprintf("variables must be initialized"));
@ -2206,7 +2204,6 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
if (parent) {
context->parent_loop_node = parent->parent_loop_node;
context->c_import_buf = parent->c_import_buf;
context->codegen_excluded = parent->codegen_excluded;
}
if (node && node->type == NodeTypeFnDef) {
@ -2455,17 +2452,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {
TopLevelDecl *tld = get_as_top_level_decl(dst_use_node);
AstNode *use_target_node = src_use_node->data.use.expr;
Expr *expr = get_resolved_expr(use_target_node);
if (expr->instruction->type_entry->id == TypeTableEntryIdInvalid) {
IrInstruction *use_target_value = tld->value;
if (use_target_value->type_entry->id == TypeTableEntryIdInvalid) {
tld->import->any_imports_failed = true;
return;
}
tld->resolution = TldResolutionOk;
ConstExprValue *const_val = &expr->instruction->static_value;
ConstExprValue *const_val = &use_target_value->static_value;
assert(const_val->special != ConstValSpecialRuntime);
ImportTableEntry *target_import = const_val->data.x_import;
@ -2511,7 +2507,7 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
}
static void resolve_use_decl(CodeGen *g, AstNode *node) {
void resolve_use_decl(CodeGen *g, AstNode *node) {
assert(node->type == NodeTypeUse);
if (get_as_top_level_decl(node)->resolution != TldResolutionUnresolved) {
return;
@ -2519,7 +2515,7 @@ static void resolve_use_decl(CodeGen *g, AstNode *node) {
add_symbols_from_import(g, node, node);
}
static void preview_use_decl(CodeGen *g, AstNode *node) {
void preview_use_decl(CodeGen *g, AstNode *node) {
assert(node->type == NodeTypeUse);
TopLevelDecl *tld = get_as_top_level_decl(node);
@ -2637,97 +2633,6 @@ void semantic_analyze(CodeGen *g) {
}
}
Expr *get_resolved_expr(AstNode *node) {
switch (node->type) {
case NodeTypeReturnExpr:
return &node->data.return_expr.resolved_expr;
case NodeTypeDefer:
return &node->data.defer.resolved_expr;
case NodeTypeBinOpExpr:
return &node->data.bin_op_expr.resolved_expr;
case NodeTypeUnwrapErrorExpr:
return &node->data.unwrap_err_expr.resolved_expr;
case NodeTypePrefixOpExpr:
return &node->data.prefix_op_expr.resolved_expr;
case NodeTypeFnCallExpr:
return &node->data.fn_call_expr.resolved_expr;
case NodeTypeArrayAccessExpr:
return &node->data.array_access_expr.resolved_expr;
case NodeTypeSliceExpr:
return &node->data.slice_expr.resolved_expr;
case NodeTypeFieldAccessExpr:
return &node->data.field_access_expr.resolved_expr;
case NodeTypeIfBoolExpr:
return &node->data.if_bool_expr.resolved_expr;
case NodeTypeIfVarExpr:
return &node->data.if_var_expr.resolved_expr;
case NodeTypeWhileExpr:
return &node->data.while_expr.resolved_expr;
case NodeTypeForExpr:
return &node->data.for_expr.resolved_expr;
case NodeTypeAsmExpr:
return &node->data.asm_expr.resolved_expr;
case NodeTypeContainerInitExpr:
return &node->data.container_init_expr.resolved_expr;
case NodeTypeNumberLiteral:
return &node->data.number_literal.resolved_expr;
case NodeTypeStringLiteral:
return &node->data.string_literal.resolved_expr;
case NodeTypeBlock:
return &node->data.block.resolved_expr;
case NodeTypeSymbol:
return &node->data.symbol_expr.resolved_expr;
case NodeTypeVariableDeclaration:
return &node->data.variable_declaration.resolved_expr;
case NodeTypeCharLiteral:
return &node->data.char_literal.resolved_expr;
case NodeTypeBoolLiteral:
return &node->data.bool_literal.resolved_expr;
case NodeTypeNullLiteral:
return &node->data.null_literal.resolved_expr;
case NodeTypeUndefinedLiteral:
return &node->data.undefined_literal.resolved_expr;
case NodeTypeZeroesLiteral:
return &node->data.zeroes_literal.resolved_expr;
case NodeTypeThisLiteral:
return &node->data.this_literal.resolved_expr;
case NodeTypeGoto:
return &node->data.goto_expr.resolved_expr;
case NodeTypeBreak:
return &node->data.break_expr.resolved_expr;
case NodeTypeContinue:
return &node->data.continue_expr.resolved_expr;
case NodeTypeLabel:
return &node->data.label.resolved_expr;
case NodeTypeArrayType:
return &node->data.array_type.resolved_expr;
case NodeTypeErrorType:
return &node->data.error_type.resolved_expr;
case NodeTypeTypeLiteral:
return &node->data.type_literal.resolved_expr;
case NodeTypeSwitchExpr:
return &node->data.switch_expr.resolved_expr;
case NodeTypeFnProto:
return &node->data.fn_proto.resolved_expr;
case NodeTypeVarLiteral:
return &node->data.var_literal.resolved_expr;
case NodeTypeSwitchProng:
case NodeTypeSwitchRange:
case NodeTypeRoot:
case NodeTypeFnDef:
case NodeTypeFnDecl:
case NodeTypeParamDecl:
case NodeTypeUse:
case NodeTypeContainerDecl:
case NodeTypeStructField:
case NodeTypeStructValueField:
case NodeTypeErrorValueDecl:
case NodeTypeTypeDecl:
zig_unreachable();
}
zig_unreachable();
}
TopLevelDecl *get_as_top_level_decl(AstNode *node) {
switch (node->type) {
case NodeTypeVariableDeclaration:
@ -2997,40 +2902,42 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
}
uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) {
uint32_t result = 0;
result += hash_ptr(id->decl_node);
for (size_t i = 0; i < id->generic_param_count; i += 1) {
GenericParamValue *generic_param = &id->generic_params[i];
if (generic_param->node) {
ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;
assert(const_val->special != ConstValSpecialRuntime);
result += hash_const_val(generic_param->type, const_val);
}
result += hash_ptr(generic_param->type);
}
return result;
zig_panic("TODO generic_fn_type_id_hash");
//uint32_t result = 0;
//result += hash_ptr(id->decl_node);
//for (size_t i = 0; i < id->generic_param_count; i += 1) {
// GenericParamValue *generic_param = &id->generic_params[i];
// if (generic_param->node) {
// ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;
// assert(const_val->special != ConstValSpecialRuntime);
// result += hash_const_val(generic_param->type, const_val);
// }
// result += hash_ptr(generic_param->type);
//}
//return result;
}
bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
if (a->decl_node != b->decl_node) return false;
assert(a->generic_param_count == b->generic_param_count);
for (size_t i = 0; i < a->generic_param_count; i += 1) {
GenericParamValue *a_val = &a->generic_params[i];
GenericParamValue *b_val = &b->generic_params[i];
if (a_val->type != b_val->type) return false;
if (a_val->node && b_val->node) {
ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;
ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;
assert(a_const_val->special != ConstValSpecialRuntime);
assert(b_const_val->special != ConstValSpecialRuntime);
if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {
return false;
}
} else {
assert(!a_val->node && !b_val->node);
}
}
return true;
zig_panic("TODO generic_fn_type_id_eql");
//if (a->decl_node != b->decl_node) return false;
//assert(a->generic_param_count == b->generic_param_count);
//for (size_t i = 0; i < a->generic_param_count; i += 1) {
// GenericParamValue *a_val = &a->generic_params[i];
// GenericParamValue *b_val = &b->generic_params[i];
// if (a_val->type != b_val->type) return false;
// if (a_val->node && b_val->node) {
// ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;
// ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;
// assert(a_const_val->special != ConstValSpecialRuntime);
// assert(b_const_val->special != ConstValSpecialRuntime);
// if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {
// return false;
// }
// } else {
// assert(!a_val->node && !b_val->node);
// }
//}
//return true;
}
bool type_has_bits(TypeTableEntry *type_entry) {
@ -3095,5 +3002,3 @@ uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) {
TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry);
return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref);
}

View File

@ -16,7 +16,6 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *m
TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
BlockContext *new_block_context(AstNode *node, BlockContext *parent);
Expr *get_resolved_expr(AstNode *node);
bool is_node_void_expr(AstNode *node);
uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, size_t size_in_bits);
@ -63,5 +62,8 @@ TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
BlockContext *get_container_block_context(TypeTableEntry *type_entry);
TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
bool is_container_ref(TypeTableEntry *type_entry);
void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node);
void preview_use_decl(CodeGen *g, AstNode *node);
void resolve_use_decl(CodeGen *g, AstNode *node);
#endif

View File

@ -528,25 +528,24 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
break;
}
case NodeTypeFnCallExpr:
if (node->data.fn_call_expr.is_builtin) {
fprintf(ar->f, "@");
} else {
fprintf(ar->f, "(");
}
render_node_ungrouped(ar, node->data.fn_call_expr.fn_ref_expr);
if (!node->data.fn_call_expr.is_builtin) {
fprintf(ar->f, ")");
}
fprintf(ar->f, "(");
for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
AstNode *param = node->data.fn_call_expr.params.at(i);
if (i != 0) {
fprintf(ar->f, ", ");
{
if (node->data.fn_call_expr.is_builtin) {
fprintf(ar->f, "@");
}
render_node_grouped(ar, param);
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
bool grouped = (fn_ref_node->type != NodeTypeBinOpExpr);
render_node_extra(ar, fn_ref_node, grouped);
fprintf(ar->f, "(");
for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
AstNode *param = node->data.fn_call_expr.params.at(i);
if (i != 0) {
fprintf(ar->f, ", ");
}
render_node_grouped(ar, param);
}
fprintf(ar->f, ")");
break;
}
fprintf(ar->f, ")");
break;
case NodeTypeArrayAccessExpr:
render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr);
fprintf(ar->f, "[");

View File

@ -65,8 +65,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
g->is_test_build = false;
g->want_h_file = true;
g->len_buf = buf_create_from_str("len");
// the error.Ok value
g->error_decls.append(nullptr);
@ -1682,6 +1680,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdSizeOf:
case IrInstructionIdSwitchTarget:
case IrInstructionIdStaticEval:
case IrInstructionIdImport:
zig_unreachable();
case IrInstructionIdReturn:
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
@ -1728,8 +1727,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdSwitchVar:
case IrInstructionIdContainerInitList:
case IrInstructionIdContainerInitFields:
case IrInstructionIdReadField:
case IrInstructionIdEnumTag:
case IrInstructionIdArrayLen:
zig_panic("TODO render more IR instructions to LLVM");
}
zig_unreachable();
@ -2114,7 +2113,7 @@ static void do_code_gen(CodeGen *g) {
if (var->type->id == TypeTableEntryIdNumLitFloat) {
// Generate debug info for it but that's it.
ConstExprValue *const_val = &get_resolved_expr(var->val_node)->instruction->static_value;
ConstExprValue *const_val = &var->decl_node->data.variable_declaration.top_level_decl.value->static_value;
assert(const_val->special != ConstValSpecialRuntime);
TypeTableEntry *var_type = g->builtin_types.entry_f64;
LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);
@ -2124,7 +2123,7 @@ static void do_code_gen(CodeGen *g) {
if (var->type->id == TypeTableEntryIdNumLitInt) {
// Generate debug info for it but that's it.
ConstExprValue *const_val = &get_resolved_expr(var->val_node)->instruction->static_value;
ConstExprValue *const_val = &var->decl_node->data.variable_declaration.top_level_decl.value->static_value;
assert(const_val->special != ConstValSpecialRuntime);
TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
g->builtin_types.entry_isize : g->builtin_types.entry_usize;
@ -2149,8 +2148,7 @@ static void do_code_gen(CodeGen *g) {
LLVMSetLinkage(global_value, LLVMExternalLinkage);
} else {
AstNode *expr_node = var->decl_node->data.variable_declaration.expr;
IrInstruction *instruction = get_resolved_expr(expr_node)->instruction;
IrInstruction *instruction = var->decl_node->data.variable_declaration.top_level_decl.value;
render_const_val(g, instruction->type_entry, &instruction->static_value);
render_const_val_global(g, instruction->type_entry, &instruction->static_value);
global_value = instruction->static_value.llvm_global;

1172
src/ir.cpp

File diff suppressed because it is too large Load Diff

View File

@ -115,6 +115,12 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
}
break;
}
case TypeTableEntryIdNamespace:
{
ImportTableEntry *import = const_val->data.x_import;
fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path));
break;
}
case TypeTableEntryIdVar:
case TypeTableEntryIdFloat:
case TypeTableEntryIdStruct:
@ -124,7 +130,6 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdTypeDecl:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdGenericFn:
zig_panic("TODO render more constant types in IR printer");
}
@ -407,11 +412,6 @@ static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction)
fprintf(irp->f, ")");
}
static void ir_print_read_field(IrPrint *irp, IrInstructionReadField *instruction) {
ir_print_other_instruction(irp, instruction->container_ptr);
fprintf(irp->f, ".%s", buf_ptr(instruction->field_name));
}
static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
fprintf(irp->f, "@StructFieldPtr(&");
ir_print_other_instruction(irp, instruction->struct_ptr);
@ -575,6 +575,17 @@ static void ir_print_static_eval(IrPrint *irp, IrInstructionStaticEval *instruct
fprintf(irp->f, ")");
}
static void ir_print_import(IrPrint *irp, IrInstructionImport *instruction) {
fprintf(irp->f, "@import(");
ir_print_other_instruction(irp, instruction->name);
fprintf(irp->f, ")");
}
static void ir_print_array_len(IrPrint *irp, IrInstructionArrayLen *instruction) {
ir_print_other_instruction(irp, instruction->array_value);
fprintf(irp->f, ".len");
}
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
ir_print_prefix(irp, instruction);
switch (instruction->id) {
@ -643,9 +654,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdFieldPtr:
ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);
break;
case IrInstructionIdReadField:
ir_print_read_field(irp, (IrInstructionReadField *)instruction);
break;
case IrInstructionIdStructFieldPtr:
ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);
break;
@ -700,6 +708,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdStaticEval:
ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);
break;
case IrInstructionIdImport:
ir_print_import(irp, (IrInstructionImport *)instruction);
break;
case IrInstructionIdArrayLen:
ir_print_array_len(irp, (IrInstructionArrayLen *)instruction);
break;
}
fprintf(irp->f, "\n");
}

View File

@ -0,0 +1 @@
pub fn foo() -> i32 { 1234 }

View File

@ -1,3 +1,5 @@
const case_namespace_fn_call = @import("cases/namespace_fn_call.zig");
pub const SYS_write = 1;
pub const SYS_exit = 60;
pub const stdout_fileno = 1;
@ -61,6 +63,10 @@ fn testInlineSwitch() {
assert(result + 1 == 14);
}
fn testNamespaceFnCall() {
assert(case_namespace_fn_call.foo() == 1234);
}
fn assert(ok: bool) {
if (!ok)
@unreachable();
@ -73,6 +79,7 @@ fn runAllTests() {
switchWithNumbers();
switchWithAllRanges();
testInlineSwitch();
testNamespaceFnCall();
}
export nakedcc fn _start() -> unreachable {