IR: support import builtin function
parent
4619b5de06
commit
84f7805029
|
@ -117,12 +117,6 @@ enum ReturnKnowledge {
|
||||||
ReturnKnowledgeSkipDefers,
|
ReturnKnowledgeSkipDefers,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Expr {
|
|
||||||
IrInstruction *instruction;
|
|
||||||
ReturnKnowledge return_knowledge;
|
|
||||||
VariableTableEntry *variable;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StructValExprCodeGen {
|
struct StructValExprCodeGen {
|
||||||
TypeTableEntry *type_entry;
|
TypeTableEntry *type_entry;
|
||||||
LLVMValueRef ptr;
|
LLVMValueRef ptr;
|
||||||
|
@ -152,6 +146,7 @@ struct TopLevelDecl {
|
||||||
bool dep_loop_flag;
|
bool dep_loop_flag;
|
||||||
TldResolution resolution;
|
TldResolution resolution;
|
||||||
AstNode *parent_decl;
|
AstNode *parent_decl;
|
||||||
|
IrInstruction *value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeEnumField {
|
struct TypeEnumField {
|
||||||
|
@ -232,7 +227,6 @@ struct AstNodeFnProto {
|
||||||
AstNode *fn_def_node;
|
AstNode *fn_def_node;
|
||||||
FnTableEntry *fn_table_entry;
|
FnTableEntry *fn_table_entry;
|
||||||
bool skip;
|
bool skip;
|
||||||
Expr resolved_expr;
|
|
||||||
// computed from params field
|
// computed from params field
|
||||||
size_t inline_arg_count;
|
size_t inline_arg_count;
|
||||||
size_t inline_or_var_type_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
|
// 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.
|
// child_block if there are no defers or var decls in the block.
|
||||||
BlockContext *nested_block;
|
BlockContext *nested_block;
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ReturnKind {
|
enum ReturnKind {
|
||||||
|
@ -287,9 +280,6 @@ struct AstNodeReturnExpr {
|
||||||
ReturnKind kind;
|
ReturnKind kind;
|
||||||
// might be null in case of return void;
|
// might be null in case of return void;
|
||||||
AstNode *expr;
|
AstNode *expr;
|
||||||
|
|
||||||
// populated by semantic analyzer:
|
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeDefer {
|
struct AstNodeDefer {
|
||||||
|
@ -297,7 +287,6 @@ struct AstNodeDefer {
|
||||||
AstNode *expr;
|
AstNode *expr;
|
||||||
|
|
||||||
// populated by semantic analyzer:
|
// populated by semantic analyzer:
|
||||||
Expr resolved_expr;
|
|
||||||
size_t index_in_block;
|
size_t index_in_block;
|
||||||
LLVMBasicBlockRef basic_block;
|
LLVMBasicBlockRef basic_block;
|
||||||
BlockContext *child_block;
|
BlockContext *child_block;
|
||||||
|
@ -314,7 +303,6 @@ struct AstNodeVariableDeclaration {
|
||||||
AstNode *expr;
|
AstNode *expr;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
VariableTableEntry *variable;
|
VariableTableEntry *variable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -392,7 +380,6 @@ struct AstNodeBinOpExpr {
|
||||||
// populated by semantic analyzer:
|
// populated by semantic analyzer:
|
||||||
// for when op is BinOpTypeAssign
|
// for when op is BinOpTypeAssign
|
||||||
VariableTableEntry *var_entry;
|
VariableTableEntry *var_entry;
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeUnwrapErrorExpr {
|
struct AstNodeUnwrapErrorExpr {
|
||||||
|
@ -401,7 +388,6 @@ struct AstNodeUnwrapErrorExpr {
|
||||||
AstNode *op2;
|
AstNode *op2;
|
||||||
|
|
||||||
// populated by semantic analyzer:
|
// populated by semantic analyzer:
|
||||||
Expr resolved_expr;
|
|
||||||
VariableTableEntry *var;
|
VariableTableEntry *var;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -434,7 +420,6 @@ struct AstNodeFnCallExpr {
|
||||||
|
|
||||||
// populated by semantic analyzer:
|
// populated by semantic analyzer:
|
||||||
BuiltinFnEntry *builtin_fn;
|
BuiltinFnEntry *builtin_fn;
|
||||||
Expr resolved_expr;
|
|
||||||
FnTableEntry *fn_entry;
|
FnTableEntry *fn_entry;
|
||||||
CastOp cast_op;
|
CastOp cast_op;
|
||||||
// if cast_op is CastOpArrayToString, this will be a pointer to
|
// if cast_op is CastOpArrayToString, this will be a pointer to
|
||||||
|
@ -447,7 +432,6 @@ struct AstNodeArrayAccessExpr {
|
||||||
AstNode *subscript;
|
AstNode *subscript;
|
||||||
|
|
||||||
// populated by semantic analyzer:
|
// populated by semantic analyzer:
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeSliceExpr {
|
struct AstNodeSliceExpr {
|
||||||
|
@ -457,7 +441,6 @@ struct AstNodeSliceExpr {
|
||||||
bool is_const;
|
bool is_const;
|
||||||
|
|
||||||
// populated by semantic analyzer:
|
// populated by semantic analyzer:
|
||||||
Expr resolved_expr;
|
|
||||||
StructValExprCodeGen resolved_struct_val_expr;
|
StructValExprCodeGen resolved_struct_val_expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -468,7 +451,6 @@ struct AstNodeFieldAccessExpr {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
TypeStructField *type_struct_field;
|
TypeStructField *type_struct_field;
|
||||||
TypeEnumField *type_enum_field;
|
TypeEnumField *type_enum_field;
|
||||||
Expr resolved_expr;
|
|
||||||
StructValExprCodeGen resolved_struct_val_expr; // for enum values
|
StructValExprCodeGen resolved_struct_val_expr; // for enum values
|
||||||
TypeTableEntry *bare_container_type;
|
TypeTableEntry *bare_container_type;
|
||||||
bool is_member_fn;
|
bool is_member_fn;
|
||||||
|
@ -495,7 +477,6 @@ struct AstNodePrefixOpExpr {
|
||||||
AstNode *primary_expr;
|
AstNode *primary_expr;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeUse {
|
struct AstNodeUse {
|
||||||
|
@ -511,7 +492,6 @@ struct AstNodeIfBoolExpr {
|
||||||
AstNode *else_node; // null, block node, or other if expr node
|
AstNode *else_node; // null, block node, or other if expr node
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeIfVarExpr {
|
struct AstNodeIfVarExpr {
|
||||||
|
@ -522,7 +502,6 @@ struct AstNodeIfVarExpr {
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
TypeTableEntry *type;
|
TypeTableEntry *type;
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeWhileExpr {
|
struct AstNodeWhileExpr {
|
||||||
|
@ -535,7 +514,6 @@ struct AstNodeWhileExpr {
|
||||||
bool condition_always_true;
|
bool condition_always_true;
|
||||||
bool contains_break;
|
bool contains_break;
|
||||||
bool contains_continue;
|
bool contains_continue;
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeForExpr {
|
struct AstNodeForExpr {
|
||||||
|
@ -549,7 +527,6 @@ struct AstNodeForExpr {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
bool contains_break;
|
bool contains_break;
|
||||||
bool contains_continue;
|
bool contains_continue;
|
||||||
Expr resolved_expr;
|
|
||||||
VariableTableEntry *elem_var;
|
VariableTableEntry *elem_var;
|
||||||
VariableTableEntry *index_var;
|
VariableTableEntry *index_var;
|
||||||
};
|
};
|
||||||
|
@ -560,7 +537,6 @@ struct AstNodeSwitchExpr {
|
||||||
bool is_inline;
|
bool is_inline;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeSwitchProng {
|
struct AstNodeSwitchProng {
|
||||||
|
@ -580,7 +556,6 @@ struct AstNodeLabel {
|
||||||
Buf *name;
|
Buf *name;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
LabelTableEntry *label_entry;
|
LabelTableEntry *label_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -588,7 +563,6 @@ struct AstNodeGoto {
|
||||||
Buf *name;
|
Buf *name;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
LabelTableEntry *label_entry;
|
LabelTableEntry *label_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -634,7 +608,6 @@ struct AstNodeAsmExpr {
|
||||||
ZigList<Buf*> clobber_list;
|
ZigList<Buf*> clobber_list;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ContainerKind {
|
enum ContainerKind {
|
||||||
|
@ -670,14 +643,12 @@ struct AstNodeStringLiteral {
|
||||||
bool c;
|
bool c;
|
||||||
|
|
||||||
// populated by semantic analyzer:
|
// populated by semantic analyzer:
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeCharLiteral {
|
struct AstNodeCharLiteral {
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
|
|
||||||
// populated by semantic analyzer:
|
// populated by semantic analyzer:
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeNumberLiteral {
|
struct AstNodeNumberLiteral {
|
||||||
|
@ -688,7 +659,6 @@ struct AstNodeNumberLiteral {
|
||||||
bool overflow;
|
bool overflow;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeStructValueField {
|
struct AstNodeStructValueField {
|
||||||
|
@ -711,35 +681,29 @@ struct AstNodeContainerInitExpr {
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
StructValExprCodeGen resolved_struct_val_expr;
|
StructValExprCodeGen resolved_struct_val_expr;
|
||||||
Expr resolved_expr;
|
|
||||||
TypeTableEntry *enum_type;
|
TypeTableEntry *enum_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeNullLiteral {
|
struct AstNodeNullLiteral {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeUndefinedLiteral {
|
struct AstNodeUndefinedLiteral {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeZeroesLiteral {
|
struct AstNodeZeroesLiteral {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeThisLiteral {
|
struct AstNodeThisLiteral {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeSymbolExpr {
|
struct AstNodeSymbolExpr {
|
||||||
Buf *symbol;
|
Buf *symbol;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
TypeEnumField *enum_field;
|
TypeEnumField *enum_field;
|
||||||
uint32_t err_value;
|
uint32_t err_value;
|
||||||
};
|
};
|
||||||
|
@ -748,17 +712,14 @@ struct AstNodeBoolLiteral {
|
||||||
bool value;
|
bool value;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeBreakExpr {
|
struct AstNodeBreakExpr {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeContinueExpr {
|
struct AstNodeContinueExpr {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeArrayType {
|
struct AstNodeArrayType {
|
||||||
|
@ -767,22 +728,18 @@ struct AstNodeArrayType {
|
||||||
bool is_const;
|
bool is_const;
|
||||||
|
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeErrorType {
|
struct AstNodeErrorType {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeTypeLiteral {
|
struct AstNodeTypeLiteral {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeVarLiteral {
|
struct AstNodeVarLiteral {
|
||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
Expr resolved_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNode {
|
struct AstNode {
|
||||||
|
@ -1329,7 +1286,6 @@ struct CodeGen {
|
||||||
LLVMValueRef err_name_table;
|
LLVMValueRef err_name_table;
|
||||||
|
|
||||||
IrInstruction *invalid_instruction;
|
IrInstruction *invalid_instruction;
|
||||||
Buf *len_buf;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariableTableEntry {
|
struct VariableTableEntry {
|
||||||
|
@ -1389,9 +1345,6 @@ struct BlockContext {
|
||||||
ZigLLVMDIScope *di_scope;
|
ZigLLVMDIScope *di_scope;
|
||||||
Buf *c_import_buf;
|
Buf *c_import_buf;
|
||||||
|
|
||||||
// if this is true, then this code will not be generated
|
|
||||||
bool codegen_excluded;
|
|
||||||
|
|
||||||
bool safety_off;
|
bool safety_off;
|
||||||
AstNode *safety_set_node;
|
AstNode *safety_set_node;
|
||||||
};
|
};
|
||||||
|
@ -1433,7 +1386,6 @@ enum IrInstructionId {
|
||||||
IrInstructionIdStorePtr,
|
IrInstructionIdStorePtr,
|
||||||
IrInstructionIdFieldPtr,
|
IrInstructionIdFieldPtr,
|
||||||
IrInstructionIdStructFieldPtr,
|
IrInstructionIdStructFieldPtr,
|
||||||
IrInstructionIdReadField,
|
|
||||||
IrInstructionIdElemPtr,
|
IrInstructionIdElemPtr,
|
||||||
IrInstructionIdVarPtr,
|
IrInstructionIdVarPtr,
|
||||||
IrInstructionIdCall,
|
IrInstructionIdCall,
|
||||||
|
@ -1460,6 +1412,8 @@ enum IrInstructionId {
|
||||||
IrInstructionIdClz,
|
IrInstructionIdClz,
|
||||||
IrInstructionIdCtz,
|
IrInstructionIdCtz,
|
||||||
IrInstructionIdStaticEval,
|
IrInstructionIdStaticEval,
|
||||||
|
IrInstructionIdImport,
|
||||||
|
IrInstructionIdArrayLen,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstruction {
|
struct IrInstruction {
|
||||||
|
@ -1628,13 +1582,6 @@ struct IrInstructionStructFieldPtr {
|
||||||
bool is_const;
|
bool is_const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstructionReadField {
|
|
||||||
IrInstruction base;
|
|
||||||
|
|
||||||
IrInstruction *container_ptr;
|
|
||||||
Buf *field_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IrInstructionElemPtr {
|
struct IrInstructionElemPtr {
|
||||||
IrInstruction base;
|
IrInstruction base;
|
||||||
|
|
||||||
|
@ -1816,6 +1763,18 @@ struct IrInstructionStaticEval {
|
||||||
IrInstruction *value;
|
IrInstruction *value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IrInstructionImport {
|
||||||
|
IrInstruction base;
|
||||||
|
|
||||||
|
IrInstruction *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IrInstructionArrayLen {
|
||||||
|
IrInstruction base;
|
||||||
|
|
||||||
|
IrInstruction *array_value;
|
||||||
|
};
|
||||||
|
|
||||||
enum LValPurpose {
|
enum LValPurpose {
|
||||||
LValPurposeNone,
|
LValPurposeNone,
|
||||||
LValPurposeAssign,
|
LValPurposeAssign,
|
||||||
|
|
175
src/analyze.cpp
175
src/analyze.cpp
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type);
|
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 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) {
|
AstNode *first_executing_node(AstNode *node) {
|
||||||
switch (node->type) {
|
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;
|
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) {
|
switch (node->type) {
|
||||||
case NodeTypeRoot:
|
case NodeTypeRoot:
|
||||||
for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
|
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;
|
implicit_type = g->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
if (implicit_type->id != TypeTableEntryIdInvalid) {
|
if (implicit_type->id != TypeTableEntryIdInvalid) {
|
||||||
Expr *expr = get_resolved_expr(var_decl->expr);
|
|
||||||
assert(result->static_value.special != ConstValSpecialRuntime);
|
assert(result->static_value.special != ConstValSpecialRuntime);
|
||||||
expr->instruction = result;
|
var_decl->top_level_decl.value = result;
|
||||||
}
|
}
|
||||||
} else if (!is_extern) {
|
} else if (!is_extern) {
|
||||||
add_node_error(g, node, buf_sprintf("variables must be initialized"));
|
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) {
|
if (parent) {
|
||||||
context->parent_loop_node = parent->parent_loop_node;
|
context->parent_loop_node = parent->parent_loop_node;
|
||||||
context->c_import_buf = parent->c_import_buf;
|
context->c_import_buf = parent->c_import_buf;
|
||||||
context->codegen_excluded = parent->codegen_excluded;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node && node->type == NodeTypeFnDef) {
|
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) {
|
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);
|
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;
|
tld->import->any_imports_failed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tld->resolution = TldResolutionOk;
|
tld->resolution = TldResolutionOk;
|
||||||
|
|
||||||
ConstExprValue *const_val = &expr->instruction->static_value;
|
ConstExprValue *const_val = &use_target_value->static_value;
|
||||||
assert(const_val->special != ConstValSpecialRuntime);
|
assert(const_val->special != ConstValSpecialRuntime);
|
||||||
|
|
||||||
ImportTableEntry *target_import = const_val->data.x_import;
|
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);
|
assert(node->type == NodeTypeUse);
|
||||||
if (get_as_top_level_decl(node)->resolution != TldResolutionUnresolved) {
|
if (get_as_top_level_decl(node)->resolution != TldResolutionUnresolved) {
|
||||||
return;
|
return;
|
||||||
|
@ -2519,7 +2515,7 @@ static void resolve_use_decl(CodeGen *g, AstNode *node) {
|
||||||
add_symbols_from_import(g, node, 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);
|
assert(node->type == NodeTypeUse);
|
||||||
TopLevelDecl *tld = get_as_top_level_decl(node);
|
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) {
|
TopLevelDecl *get_as_top_level_decl(AstNode *node) {
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case NodeTypeVariableDeclaration:
|
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 generic_fn_type_id_hash(GenericFnTypeId *id) {
|
||||||
uint32_t result = 0;
|
zig_panic("TODO generic_fn_type_id_hash");
|
||||||
result += hash_ptr(id->decl_node);
|
//uint32_t result = 0;
|
||||||
for (size_t i = 0; i < id->generic_param_count; i += 1) {
|
//result += hash_ptr(id->decl_node);
|
||||||
GenericParamValue *generic_param = &id->generic_params[i];
|
//for (size_t i = 0; i < id->generic_param_count; i += 1) {
|
||||||
if (generic_param->node) {
|
// GenericParamValue *generic_param = &id->generic_params[i];
|
||||||
ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;
|
// if (generic_param->node) {
|
||||||
assert(const_val->special != ConstValSpecialRuntime);
|
// ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;
|
||||||
result += hash_const_val(generic_param->type, const_val);
|
// assert(const_val->special != ConstValSpecialRuntime);
|
||||||
}
|
// result += hash_const_val(generic_param->type, const_val);
|
||||||
result += hash_ptr(generic_param->type);
|
// }
|
||||||
}
|
// result += hash_ptr(generic_param->type);
|
||||||
return result;
|
//}
|
||||||
|
//return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
|
bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
|
||||||
if (a->decl_node != b->decl_node) return false;
|
zig_panic("TODO generic_fn_type_id_eql");
|
||||||
assert(a->generic_param_count == b->generic_param_count);
|
//if (a->decl_node != b->decl_node) return false;
|
||||||
for (size_t i = 0; i < a->generic_param_count; i += 1) {
|
//assert(a->generic_param_count == b->generic_param_count);
|
||||||
GenericParamValue *a_val = &a->generic_params[i];
|
//for (size_t i = 0; i < a->generic_param_count; i += 1) {
|
||||||
GenericParamValue *b_val = &b->generic_params[i];
|
// GenericParamValue *a_val = &a->generic_params[i];
|
||||||
if (a_val->type != b_val->type) return false;
|
// GenericParamValue *b_val = &b->generic_params[i];
|
||||||
if (a_val->node && b_val->node) {
|
// if (a_val->type != b_val->type) return false;
|
||||||
ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;
|
// if (a_val->node && b_val->node) {
|
||||||
ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;
|
// ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;
|
||||||
assert(a_const_val->special != ConstValSpecialRuntime);
|
// ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;
|
||||||
assert(b_const_val->special != ConstValSpecialRuntime);
|
// assert(a_const_val->special != ConstValSpecialRuntime);
|
||||||
if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {
|
// assert(b_const_val->special != ConstValSpecialRuntime);
|
||||||
return false;
|
// if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {
|
||||||
}
|
// return false;
|
||||||
} else {
|
// }
|
||||||
assert(!a_val->node && !b_val->node);
|
// } else {
|
||||||
}
|
// assert(!a_val->node && !b_val->node);
|
||||||
}
|
// }
|
||||||
return true;
|
//}
|
||||||
|
//return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool type_has_bits(TypeTableEntry *type_entry) {
|
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);
|
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);
|
return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 *new_type_table_entry(TypeTableEntryId id);
|
||||||
TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
|
TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
|
||||||
BlockContext *new_block_context(AstNode *node, BlockContext *parent);
|
BlockContext *new_block_context(AstNode *node, BlockContext *parent);
|
||||||
Expr *get_resolved_expr(AstNode *node);
|
|
||||||
bool is_node_void_expr(AstNode *node);
|
bool is_node_void_expr(AstNode *node);
|
||||||
uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
|
uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
|
||||||
TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, size_t size_in_bits);
|
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);
|
BlockContext *get_container_block_context(TypeTableEntry *type_entry);
|
||||||
TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
|
TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
|
||||||
bool is_container_ref(TypeTableEntry *type_entry);
|
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
|
#endif
|
||||||
|
|
|
@ -528,25 +528,24 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NodeTypeFnCallExpr:
|
case NodeTypeFnCallExpr:
|
||||||
if (node->data.fn_call_expr.is_builtin) {
|
{
|
||||||
fprintf(ar->f, "@");
|
if (node->data.fn_call_expr.is_builtin) {
|
||||||
} else {
|
fprintf(ar->f, "@");
|
||||||
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, ", ");
|
|
||||||
}
|
}
|
||||||
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:
|
case NodeTypeArrayAccessExpr:
|
||||||
render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr);
|
render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr);
|
||||||
fprintf(ar->f, "[");
|
fprintf(ar->f, "[");
|
||||||
|
|
|
@ -65,8 +65,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
|
||||||
g->is_test_build = false;
|
g->is_test_build = false;
|
||||||
g->want_h_file = true;
|
g->want_h_file = true;
|
||||||
|
|
||||||
g->len_buf = buf_create_from_str("len");
|
|
||||||
|
|
||||||
// the error.Ok value
|
// the error.Ok value
|
||||||
g->error_decls.append(nullptr);
|
g->error_decls.append(nullptr);
|
||||||
|
|
||||||
|
@ -1682,6 +1680,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||||
case IrInstructionIdSizeOf:
|
case IrInstructionIdSizeOf:
|
||||||
case IrInstructionIdSwitchTarget:
|
case IrInstructionIdSwitchTarget:
|
||||||
case IrInstructionIdStaticEval:
|
case IrInstructionIdStaticEval:
|
||||||
|
case IrInstructionIdImport:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case IrInstructionIdReturn:
|
case IrInstructionIdReturn:
|
||||||
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
|
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
|
||||||
|
@ -1728,8 +1727,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||||
case IrInstructionIdSwitchVar:
|
case IrInstructionIdSwitchVar:
|
||||||
case IrInstructionIdContainerInitList:
|
case IrInstructionIdContainerInitList:
|
||||||
case IrInstructionIdContainerInitFields:
|
case IrInstructionIdContainerInitFields:
|
||||||
case IrInstructionIdReadField:
|
|
||||||
case IrInstructionIdEnumTag:
|
case IrInstructionIdEnumTag:
|
||||||
|
case IrInstructionIdArrayLen:
|
||||||
zig_panic("TODO render more IR instructions to LLVM");
|
zig_panic("TODO render more IR instructions to LLVM");
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
|
@ -2114,7 +2113,7 @@ static void do_code_gen(CodeGen *g) {
|
||||||
|
|
||||||
if (var->type->id == TypeTableEntryIdNumLitFloat) {
|
if (var->type->id == TypeTableEntryIdNumLitFloat) {
|
||||||
// Generate debug info for it but that's it.
|
// 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);
|
assert(const_val->special != ConstValSpecialRuntime);
|
||||||
TypeTableEntry *var_type = g->builtin_types.entry_f64;
|
TypeTableEntry *var_type = g->builtin_types.entry_f64;
|
||||||
LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);
|
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) {
|
if (var->type->id == TypeTableEntryIdNumLitInt) {
|
||||||
// Generate debug info for it but that's it.
|
// 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);
|
assert(const_val->special != ConstValSpecialRuntime);
|
||||||
TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
|
TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
|
||||||
g->builtin_types.entry_isize : g->builtin_types.entry_usize;
|
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);
|
LLVMSetLinkage(global_value, LLVMExternalLinkage);
|
||||||
} else {
|
} else {
|
||||||
AstNode *expr_node = var->decl_node->data.variable_declaration.expr;
|
IrInstruction *instruction = var->decl_node->data.variable_declaration.top_level_decl.value;
|
||||||
IrInstruction *instruction = get_resolved_expr(expr_node)->instruction;
|
|
||||||
render_const_val(g, instruction->type_entry, &instruction->static_value);
|
render_const_val(g, instruction->type_entry, &instruction->static_value);
|
||||||
render_const_val_global(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;
|
global_value = instruction->static_value.llvm_global;
|
||||||
|
|
1172
src/ir.cpp
1172
src/ir.cpp
File diff suppressed because it is too large
Load Diff
|
@ -115,6 +115,12 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TypeTableEntryIdNamespace:
|
||||||
|
{
|
||||||
|
ImportTableEntry *import = const_val->data.x_import;
|
||||||
|
fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TypeTableEntryIdVar:
|
case TypeTableEntryIdVar:
|
||||||
case TypeTableEntryIdFloat:
|
case TypeTableEntryIdFloat:
|
||||||
case TypeTableEntryIdStruct:
|
case TypeTableEntryIdStruct:
|
||||||
|
@ -124,7 +130,6 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
|
||||||
case TypeTableEntryIdEnum:
|
case TypeTableEntryIdEnum:
|
||||||
case TypeTableEntryIdUnion:
|
case TypeTableEntryIdUnion:
|
||||||
case TypeTableEntryIdTypeDecl:
|
case TypeTableEntryIdTypeDecl:
|
||||||
case TypeTableEntryIdNamespace:
|
|
||||||
case TypeTableEntryIdGenericFn:
|
case TypeTableEntryIdGenericFn:
|
||||||
zig_panic("TODO render more constant types in IR printer");
|
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, ")");
|
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) {
|
static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
|
||||||
fprintf(irp->f, "@StructFieldPtr(&");
|
fprintf(irp->f, "@StructFieldPtr(&");
|
||||||
ir_print_other_instruction(irp, instruction->struct_ptr);
|
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, ")");
|
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) {
|
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||||
ir_print_prefix(irp, instruction);
|
ir_print_prefix(irp, instruction);
|
||||||
switch (instruction->id) {
|
switch (instruction->id) {
|
||||||
|
@ -643,9 +654,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||||
case IrInstructionIdFieldPtr:
|
case IrInstructionIdFieldPtr:
|
||||||
ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);
|
ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);
|
||||||
break;
|
break;
|
||||||
case IrInstructionIdReadField:
|
|
||||||
ir_print_read_field(irp, (IrInstructionReadField *)instruction);
|
|
||||||
break;
|
|
||||||
case IrInstructionIdStructFieldPtr:
|
case IrInstructionIdStructFieldPtr:
|
||||||
ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);
|
ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);
|
||||||
break;
|
break;
|
||||||
|
@ -700,6 +708,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||||
case IrInstructionIdStaticEval:
|
case IrInstructionIdStaticEval:
|
||||||
ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);
|
ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);
|
||||||
break;
|
break;
|
||||||
|
case IrInstructionIdImport:
|
||||||
|
ir_print_import(irp, (IrInstructionImport *)instruction);
|
||||||
|
break;
|
||||||
|
case IrInstructionIdArrayLen:
|
||||||
|
ir_print_array_len(irp, (IrInstructionArrayLen *)instruction);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
fprintf(irp->f, "\n");
|
fprintf(irp->f, "\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
pub fn foo() -> i32 { 1234 }
|
|
@ -1,3 +1,5 @@
|
||||||
|
const case_namespace_fn_call = @import("cases/namespace_fn_call.zig");
|
||||||
|
|
||||||
pub const SYS_write = 1;
|
pub const SYS_write = 1;
|
||||||
pub const SYS_exit = 60;
|
pub const SYS_exit = 60;
|
||||||
pub const stdout_fileno = 1;
|
pub const stdout_fileno = 1;
|
||||||
|
@ -61,6 +63,10 @@ fn testInlineSwitch() {
|
||||||
assert(result + 1 == 14);
|
assert(result + 1 == 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn testNamespaceFnCall() {
|
||||||
|
assert(case_namespace_fn_call.foo() == 1234);
|
||||||
|
}
|
||||||
|
|
||||||
fn assert(ok: bool) {
|
fn assert(ok: bool) {
|
||||||
if (!ok)
|
if (!ok)
|
||||||
@unreachable();
|
@unreachable();
|
||||||
|
@ -73,6 +79,7 @@ fn runAllTests() {
|
||||||
switchWithNumbers();
|
switchWithNumbers();
|
||||||
switchWithAllRanges();
|
switchWithAllRanges();
|
||||||
testInlineSwitch();
|
testInlineSwitch();
|
||||||
|
testNamespaceFnCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
export nakedcc fn _start() -> unreachable {
|
export nakedcc fn _start() -> unreachable {
|
||||||
|
|
Loading…
Reference in New Issue