authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-09 22:54:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-09 22:54:23-04:00
log623741171629055a22a35bb8278d81a81dcffbde
treeda0cc10fd43c5d167edc59dc587dba1befbb08b4
parent01f066de379caf545ec65c572f75cc1ed1312799

inline function call with builtin function instead...

...of special syntax. partially reverts 41144a8566a6fbd779403f6b69424bb640c94a7f closes #306

9 files changed, 56 insertions(+), 169 deletions(-)

doc/langref.md+3-6
...@@ -79,7 +79,7 @@ SwitchProng = (list(SwitchItem, ",") | "else") "=>" option("|" option("*") Symbo...@@ -79,7 +79,7 @@ SwitchProng = (list(SwitchItem, ",") | "else") "=>" option("|" option("*") Symbo
7979
80SwitchItem = Expression | (Expression "..." Expression)80SwitchItem = Expression | (Expression "..." Expression)
8181
82ForExpression(body) = "for" "(" Expression ")" option("|" option("*") Symbol option("," Symbol) "|") body option("else" BlockExpression(body))82ForExpression(body) = option("inline") "for" "(" Expression ")" option("|" option("*") Symbol option("," Symbol) "|") body option("else" BlockExpression(body))
8383
84BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression84BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression
8585
...@@ -95,7 +95,7 @@ TryExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|")...@@ -95,7 +95,7 @@ TryExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|")
9595
96TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body))96TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body))
9797
98WhileExpression(body) = "while" "(" Expression ")" option("|" option("*") Symbol "|") option(":" "(" Expression ")") body option("else" option("|" Symbol "|") BlockExpression(body))98WhileExpression(body) = option("inline") "while" "(" Expression ")" option("|" option("*") Symbol "|") option(":" "(" Expression ")") body option("else" option("|" Symbol "|") BlockExpression(body))
9999
100BoolAndExpression = ComparisonExpression "and" BoolAndExpression | ComparisonExpression100BoolAndExpression = ComparisonExpression "and" BoolAndExpression | ComparisonExpression
101101
...@@ -125,9 +125,7 @@ MultiplyOperator = "*" | "/" | "%" | "**" | "*%"...@@ -125,9 +125,7 @@ MultiplyOperator = "*" | "/" | "%" | "**" | "*%"
125125
126PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression126PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression
127127
128SuffixOpExpression = InlineExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)128SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
129
130InlineExpression = option("inline") PrimaryExpression
131129
132FieldAccessExpression = "." Symbol130FieldAccessExpression = "." Symbol
133131
...@@ -161,7 +159,6 @@ ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" ma...@@ -161,7 +159,6 @@ ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" ma
161## Operator Precedence159## Operator Precedence
162160
163```161```
164inline x
165x() x[] x.y162x() x[] x.y
166!x -x -%x ~x *x &x ?x %x %%x ??x163!x -x -%x ~x *x &x ?x %x %%x ??x
167x{}164x{}
src/all_types.hpp+1-15
...@@ -175,7 +175,6 @@ struct ConstErrValue {...@@ -175,7 +175,6 @@ struct ConstErrValue {
175struct ConstBoundFnValue {175struct ConstBoundFnValue {
176 FnTableEntry *fn;176 FnTableEntry *fn;
177 IrInstruction *first_arg;177 IrInstruction *first_arg;
178 bool is_inline;
179};178};
180179
181struct ConstArgTuple {180struct ConstArgTuple {
...@@ -209,7 +208,6 @@ enum RuntimeHintPtr {...@@ -209,7 +208,6 @@ enum RuntimeHintPtr {
209208
210struct ConstFn {209struct ConstFn {
211 FnTableEntry *fn_entry;210 FnTableEntry *fn_entry;
212 bool is_inline;
213};211};
214212
215struct ConstExprValue {213struct ConstExprValue {
...@@ -379,7 +377,6 @@ enum NodeType {...@@ -379,7 +377,6 @@ enum NodeType {
379 NodeTypeVarLiteral,377 NodeTypeVarLiteral,
380 NodeTypeTryExpr,378 NodeTypeTryExpr,
381 NodeTypeTestExpr,379 NodeTypeTestExpr,
382 NodeTypeInlineExpr,
383};380};
384381
385struct AstNodeRoot {382struct AstNodeRoot {
...@@ -796,10 +793,6 @@ struct AstNodeErrorType {...@@ -796,10 +793,6 @@ struct AstNodeErrorType {
796struct AstNodeVarLiteral {793struct AstNodeVarLiteral {
797};794};
798795
799struct AstNodeInlineExpr {
800 AstNode *body;
801};
802
803struct AstNode {796struct AstNode {
804 enum NodeType type;797 enum NodeType type;
805 size_t line;798 size_t line;
...@@ -857,7 +850,6 @@ struct AstNode {...@@ -857,7 +850,6 @@ struct AstNode {
857 AstNodeArrayType array_type;850 AstNodeArrayType array_type;
858 AstNodeErrorType error_type;851 AstNodeErrorType error_type;
859 AstNodeVarLiteral var_literal;852 AstNodeVarLiteral var_literal;
860 AstNodeInlineExpr inline_expr;
861 } data;853 } data;
862};854};
863855
...@@ -1214,6 +1206,7 @@ enum BuiltinFnId {...@@ -1214,6 +1206,7 @@ enum BuiltinFnId {
1214 BuiltinFnIdEnumTagName,1206 BuiltinFnIdEnumTagName,
1215 BuiltinFnIdFieldParentPtr,1207 BuiltinFnIdFieldParentPtr,
1216 BuiltinFnIdOffsetOf,1208 BuiltinFnIdOffsetOf,
1209 BuiltinFnIdInlineCall,
1217};1210};
12181211
1219struct BuiltinFnEntry {1212struct BuiltinFnEntry {
...@@ -1791,7 +1784,6 @@ enum IrInstructionId {...@@ -1791,7 +1784,6 @@ enum IrInstructionId {
1791 IrInstructionIdDeclRef,1784 IrInstructionIdDeclRef,
1792 IrInstructionIdPanic,1785 IrInstructionIdPanic,
1793 IrInstructionIdEnumTagName,1786 IrInstructionIdEnumTagName,
1794 IrInstructionIdSetFnRefInline,
1795 IrInstructionIdFieldParentPtr,1787 IrInstructionIdFieldParentPtr,
1796 IrInstructionIdOffsetOf,1788 IrInstructionIdOffsetOf,
1797};1789};
...@@ -2532,12 +2524,6 @@ struct IrInstructionEnumTagName {...@@ -2532,12 +2524,6 @@ struct IrInstructionEnumTagName {
2532 IrInstruction *target;2524 IrInstruction *target;
2533};2525};
25342526
2535struct IrInstructionSetFnRefInline {
2536 IrInstruction base;
2537
2538 IrInstruction *fn_ref;
2539};
2540
2541struct IrInstructionFieldParentPtr {2527struct IrInstructionFieldParentPtr {
2542 IrInstruction base;2528 IrInstruction base;
25432529
src/analyze.cpp+4-9
...@@ -2195,7 +2195,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -2195,7 +2195,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
2195 case NodeTypeVarLiteral:2195 case NodeTypeVarLiteral:
2196 case NodeTypeTryExpr:2196 case NodeTypeTryExpr:
2197 case NodeTypeTestExpr:2197 case NodeTypeTestExpr:
2198 case NodeTypeInlineExpr:
2199 zig_unreachable();2198 zig_unreachable();
2200 }2199 }
2201}2200}
...@@ -3304,8 +3303,7 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -3304,8 +3303,7 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
3304 // TODO better hashing algorithm3303 // TODO better hashing algorithm
3305 return 31643936;3304 return 31643936;
3306 case TypeTableEntryIdFn:3305 case TypeTableEntryIdFn:
3307 return hash_ptr(const_val->data.x_fn.fn_entry) +3306 return 4133894920 ^ hash_ptr(const_val->data.x_fn.fn_entry);
3308 (const_val->data.x_fn.is_inline ? 4133894920 : 3983484790);
3309 case TypeTableEntryIdNamespace:3307 case TypeTableEntryIdNamespace:
3310 return hash_ptr(const_val->data.x_import);3308 return hash_ptr(const_val->data.x_import);
3311 case TypeTableEntryIdBlock:3309 case TypeTableEntryIdBlock:
...@@ -3756,8 +3754,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -3756,8 +3754,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
3756 case TypeTableEntryIdPureError:3754 case TypeTableEntryIdPureError:
3757 return a->data.x_pure_err == b->data.x_pure_err;3755 return a->data.x_pure_err == b->data.x_pure_err;
3758 case TypeTableEntryIdFn:3756 case TypeTableEntryIdFn:
3759 return a->data.x_fn.fn_entry == b->data.x_fn.fn_entry &&3757 return a->data.x_fn.fn_entry == b->data.x_fn.fn_entry;
3760 a->data.x_fn.is_inline == b->data.x_fn.is_inline;
3761 case TypeTableEntryIdBool:3758 case TypeTableEntryIdBool:
3762 return a->data.x_bool == b->data.x_bool;3759 return a->data.x_bool == b->data.x_bool;
3763 case TypeTableEntryIdInt:3760 case TypeTableEntryIdInt:
...@@ -3997,8 +3994,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -3997,8 +3994,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
3997 case TypeTableEntryIdFn:3994 case TypeTableEntryIdFn:
3998 {3995 {
3999 FnTableEntry *fn_entry = const_val->data.x_fn.fn_entry;3996 FnTableEntry *fn_entry = const_val->data.x_fn.fn_entry;
4000 const char *inline_str = const_val->data.x_fn.is_inline ? "inline " : "";3997 buf_appendf(buf, "%s", buf_ptr(&fn_entry->symbol_name));
4001 buf_appendf(buf, "%s%s", inline_str, buf_ptr(&fn_entry->symbol_name));
4002 return;3998 return;
4003 }3999 }
4004 case TypeTableEntryIdBlock:4000 case TypeTableEntryIdBlock:
...@@ -4080,8 +4076,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -4080,8 +4076,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
4080 case TypeTableEntryIdBoundFn:4076 case TypeTableEntryIdBoundFn:
4081 {4077 {
4082 FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn;4078 FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn;
4083 const char *inline_str = const_val->data.x_bound_fn.is_inline ? "inline " : "";4079 buf_appendf(buf, "(bound fn %s)", buf_ptr(&fn_entry->symbol_name));
4084 buf_appendf(buf, "(%sbound fn %s)", inline_str, buf_ptr(&fn_entry->symbol_name));
4085 return;4080 return;
4086 }4081 }
4087 case TypeTableEntryIdStruct:4082 case TypeTableEntryIdStruct:
src/ast_render.cpp-8
...@@ -236,8 +236,6 @@ static const char *node_type_str(NodeType node_type) {...@@ -236,8 +236,6 @@ static const char *node_type_str(NodeType node_type) {
236 return "TryExpr";236 return "TryExpr";
237 case NodeTypeTestExpr:237 case NodeTypeTestExpr:
238 return "TestExpr";238 return "TestExpr";
239 case NodeTypeInlineExpr:
240 return "InlineExpr";
241 }239 }
242 zig_unreachable();240 zig_unreachable();
243}241}
...@@ -927,12 +925,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -927,12 +925,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
927 render_node_ungrouped(ar, node->data.unwrap_err_expr.op2);925 render_node_ungrouped(ar, node->data.unwrap_err_expr.op2);
928 break;926 break;
929 }927 }
930 case NodeTypeInlineExpr:
931 {
932 fprintf(ar->f, "inline ");
933 render_node_grouped(ar, node->data.inline_expr.body);
934 break;
935 }
936 case NodeTypeFnDecl:928 case NodeTypeFnDecl:
937 case NodeTypeParamDecl:929 case NodeTypeParamDecl:
938 case NodeTypeErrorValueDecl:930 case NodeTypeErrorValueDecl:
src/codegen.cpp+7-1
...@@ -3017,7 +3017,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -3017,7 +3017,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
3017 case IrInstructionIdSetGlobalLinkage:3017 case IrInstructionIdSetGlobalLinkage:
3018 case IrInstructionIdDeclRef:3018 case IrInstructionIdDeclRef:
3019 case IrInstructionIdSwitchVar:3019 case IrInstructionIdSwitchVar:
3020 case IrInstructionIdSetFnRefInline:
3021 case IrInstructionIdOffsetOf:3020 case IrInstructionIdOffsetOf:
3022 zig_unreachable();3021 zig_unreachable();
3023 case IrInstructionIdReturn:3022 case IrInstructionIdReturn:
...@@ -3596,6 +3595,7 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const...@@ -3596,6 +3595,7 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const
3596}3595}
35973596
3598static void delete_unused_builtin_fns(CodeGen *g) {3597static void delete_unused_builtin_fns(CodeGen *g) {
3598 // TODO get rid of this function
3599 auto it = g->builtin_fn_table.entry_iterator();3599 auto it = g->builtin_fn_table.entry_iterator();
3600 for (;;) {3600 for (;;) {
3601 auto *entry = it.next();3601 auto *entry = it.next();
...@@ -4330,6 +4330,7 @@ static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char...@@ -4330,6 +4330,7 @@ static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char
43304330
4331static void define_builtin_fns(CodeGen *g) {4331static void define_builtin_fns(CodeGen *g) {
4332 {4332 {
4333 // TODO make lazy and get rid of delete_unused_builtin_fns
4333 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdBreakpoint, "breakpoint", 0);4334 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdBreakpoint, "breakpoint", 0);
4334 builtin_fn->ref_count = 1;4335 builtin_fn->ref_count = 1;
43354336
...@@ -4340,6 +4341,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4340,6 +4341,7 @@ static void define_builtin_fns(CodeGen *g) {
4340 g->trap_fn_val = builtin_fn->fn_val;4341 g->trap_fn_val = builtin_fn->fn_val;
4341 }4342 }
4342 {4343 {
4344 // TODO make lazy and get rid of delete_unused_builtin_fns
4343 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdReturnAddress,4345 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdReturnAddress,
4344 "returnAddress", 0);4346 "returnAddress", 0);
4345 TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);4347 TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
...@@ -4352,6 +4354,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4352,6 +4354,7 @@ static void define_builtin_fns(CodeGen *g) {
4352 g->return_address_fn_val = builtin_fn->fn_val;4354 g->return_address_fn_val = builtin_fn->fn_val;
4353 }4355 }
4354 {4356 {
4357 // TODO make lazy and get rid of delete_unused_builtin_fns
4355 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdFrameAddress,4358 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdFrameAddress,
4356 "frameAddress", 0);4359 "frameAddress", 0);
4357 TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);4360 TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
...@@ -4364,6 +4367,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4364,6 +4367,7 @@ static void define_builtin_fns(CodeGen *g) {
4364 g->frame_address_fn_val = builtin_fn->fn_val;4367 g->frame_address_fn_val = builtin_fn->fn_val;
4365 }4368 }
4366 {4369 {
4370 // TODO make lazy and get rid of delete_unused_builtin_fns
4367 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3);4371 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3);
4368 builtin_fn->ref_count = 1;4372 builtin_fn->ref_count = 1;
43694373
...@@ -4382,6 +4386,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4382,6 +4386,7 @@ static void define_builtin_fns(CodeGen *g) {
4382 g->memcpy_fn_val = builtin_fn->fn_val;4386 g->memcpy_fn_val = builtin_fn->fn_val;
4383 }4387 }
4384 {4388 {
4389 // TODO make lazy and get rid of delete_unused_builtin_fns
4385 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);4390 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);
4386 builtin_fn->ref_count = 1;4391 builtin_fn->ref_count = 1;
43874392
...@@ -4443,6 +4448,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4443,6 +4448,7 @@ static void define_builtin_fns(CodeGen *g) {
4443 create_builtin_fn(g, BuiltinFnIdDivFloor, "divFloor", 2);4448 create_builtin_fn(g, BuiltinFnIdDivFloor, "divFloor", 2);
4444 create_builtin_fn(g, BuiltinFnIdRem, "rem", 2);4449 create_builtin_fn(g, BuiltinFnIdRem, "rem", 2);
4445 create_builtin_fn(g, BuiltinFnIdMod, "mod", 2);4450 create_builtin_fn(g, BuiltinFnIdMod, "mod", 2);
4451 create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX);
4446}4452}
44474453
4448static const char *bool_to_str(bool b) {4454static const char *bool_to_str(bool b) {
src/ir.cpp+28-82
...@@ -553,10 +553,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) {...@@ -553,10 +553,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) {
553 return IrInstructionIdEnumTagName;553 return IrInstructionIdEnumTagName;
554}554}
555555
556static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnRefInline *) {
557 return IrInstructionIdSetFnRefInline;
558}
559
560static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) {556static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) {
561 return IrInstructionIdFieldParentPtr;557 return IrInstructionIdFieldParentPtr;
562}558}
...@@ -2142,18 +2138,6 @@ static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNo...@@ -2142,18 +2138,6 @@ static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNo
2142 return &instruction->base;2138 return &instruction->base;
2143}2139}
21442140
2145static IrInstruction *ir_build_set_fn_ref_inline(IrBuilder *irb, Scope *scope, AstNode *source_node,
2146 IrInstruction *fn_ref)
2147{
2148 IrInstructionSetFnRefInline *instruction = ir_build_instruction<IrInstructionSetFnRefInline>(
2149 irb, scope, source_node);
2150 instruction->fn_ref = fn_ref;
2151
2152 ir_ref_instruction(fn_ref, irb->current_basic_block);
2153
2154 return &instruction->base;
2155}
2156
2157static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,2141static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
2158 IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field)2142 IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field)
2159{2143{
...@@ -2838,13 +2822,6 @@ static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionEnumTagNam...@@ -2838,13 +2822,6 @@ static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionEnumTagNam
2838 }2822 }
2839}2823}
28402824
2841static IrInstruction *ir_instruction_setfnrefinline_get_dep(IrInstructionSetFnRefInline *instruction, size_t index) {
2842 switch (index) {
2843 case 0: return instruction->fn_ref;
2844 default: return nullptr;
2845 }
2846}
2847
2848static IrInstruction *ir_instruction_fieldparentptr_get_dep(IrInstructionFieldParentPtr *instruction, size_t index) {2825static IrInstruction *ir_instruction_fieldparentptr_get_dep(IrInstructionFieldParentPtr *instruction, size_t index) {
2849 switch (index) {2826 switch (index) {
2850 case 0: return instruction->type_value;2827 case 0: return instruction->type_value;
...@@ -3048,8 +3025,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -3048,8 +3025,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
3048 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);3025 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);
3049 case IrInstructionIdEnumTagName:3026 case IrInstructionIdEnumTagName:
3050 return ir_instruction_enumtagname_get_dep((IrInstructionEnumTagName *) instruction, index);3027 return ir_instruction_enumtagname_get_dep((IrInstructionEnumTagName *) instruction, index);
3051 case IrInstructionIdSetFnRefInline:
3052 return ir_instruction_setfnrefinline_get_dep((IrInstructionSetFnRefInline *) instruction, index);
3053 case IrInstructionIdFieldParentPtr:3028 case IrInstructionIdFieldParentPtr:
3054 return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index);3029 return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index);
3055 case IrInstructionIdOffsetOf:3030 case IrInstructionIdOffsetOf:
...@@ -4376,6 +4351,30 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4376,6 +4351,30 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43764351
4377 return ir_build_offset_of(irb, scope, node, arg0_value, arg1_value);4352 return ir_build_offset_of(irb, scope, node, arg0_value, arg1_value);
4378 }4353 }
4354 case BuiltinFnIdInlineCall:
4355 {
4356 if (node->data.fn_call_expr.params.length == 0) {
4357 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0"));
4358 return irb->codegen->invalid_instruction;
4359 }
4360
4361 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(0);
4362 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
4363 if (fn_ref == irb->codegen->invalid_instruction)
4364 return fn_ref;
4365
4366 size_t arg_count = node->data.fn_call_expr.params.length - 1;
4367
4368 IrInstruction **args = allocate<IrInstruction*>(arg_count);
4369 for (size_t i = 0; i < arg_count; i += 1) {
4370 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 1);
4371 args[i] = ir_gen_node(irb, arg_node, scope);
4372 if (args[i] == irb->codegen->invalid_instruction)
4373 return args[i];
4374 }
4375
4376 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, true);
4377 }
4379 }4378 }
4380 zig_unreachable();4379 zig_unreachable();
4381}4380}
...@@ -5800,19 +5799,6 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5800,19 +5799,6 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
5800 return ir_build_fn_proto(irb, parent_scope, node, param_types, return_type);5799 return ir_build_fn_proto(irb, parent_scope, node, param_types, return_type);
5801}5800}
58025801
5803static IrInstruction *ir_gen_inline_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
5804 assert(node->type == NodeTypeInlineExpr);
5805
5806 AstNode *body_node = node->data.inline_expr.body;
5807
5808 IrInstruction *fn_ptr = ir_gen_node(irb, body_node, parent_scope);
5809 if (fn_ptr == irb->codegen->invalid_instruction)
5810 return irb->codegen->invalid_instruction;
5811
5812 return ir_build_set_fn_ref_inline(irb, parent_scope, node, fn_ptr);
5813}
5814
5815
5816static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,5802static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
5817 LVal lval)5803 LVal lval)
5818{5804{
...@@ -5903,8 +5889,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -5903,8 +5889,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
5903 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);5889 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);
5904 case NodeTypeFnProto:5890 case NodeTypeFnProto:
5905 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);5891 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);
5906 case NodeTypeInlineExpr:
5907 return ir_lval_wrap(irb, scope, ir_gen_inline_expr(irb, scope, node), lval);
5908 case NodeTypeFnDef:5892 case NodeTypeFnDef:
5909 zig_panic("TODO IR gen NodeTypeFnDef");5893 zig_panic("TODO IR gen NodeTypeFnDef");
5910 case NodeTypeFnDecl:5894 case NodeTypeFnDecl:
...@@ -6809,7 +6793,7 @@ static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value...@@ -6809,7 +6793,7 @@ static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value
6809 return const_val->data.x_type;6793 return const_val->data.x_type;
6810}6794}
68116795
6812static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value, bool *is_inline) {6796static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) {
6813 if (fn_value == ira->codegen->invalid_instruction)6797 if (fn_value == ira->codegen->invalid_instruction)
6814 return nullptr;6798 return nullptr;
68156799
...@@ -6826,7 +6810,6 @@ static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value, bool...@@ -6826,7 +6810,6 @@ static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value, bool
6826 if (!const_val)6810 if (!const_val)
6827 return nullptr;6811 return nullptr;
68286812
6829 *is_inline = const_val->data.x_fn.is_inline;
6830 return const_val->data.x_fn.fn_entry;6813 return const_val->data.x_fn.fn_entry;
6831}6814}
68326815
...@@ -9179,17 +9162,15 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -9179,17 +9162,15 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
9179 ir_link_new_instruction(cast_instruction, &call_instruction->base);9162 ir_link_new_instruction(cast_instruction, &call_instruction->base);
9180 return ir_finish_anal(ira, cast_instruction->value.type);9163 return ir_finish_anal(ira, cast_instruction->value.type);
9181 } else if (fn_ref->value.type->id == TypeTableEntryIdFn) {9164 } else if (fn_ref->value.type->id == TypeTableEntryIdFn) {
9182 bool is_inline;9165 FnTableEntry *fn_table_entry = ir_resolve_fn(ira, fn_ref);
9183 FnTableEntry *fn_table_entry = ir_resolve_fn(ira, fn_ref, &is_inline);
9184 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,9166 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,
9185 fn_ref, nullptr, is_comptime, is_inline);9167 fn_ref, nullptr, is_comptime, call_instruction->is_inline);
9186 } else if (fn_ref->value.type->id == TypeTableEntryIdBoundFn) {9168 } else if (fn_ref->value.type->id == TypeTableEntryIdBoundFn) {
9187 assert(fn_ref->value.special == ConstValSpecialStatic);9169 assert(fn_ref->value.special == ConstValSpecialStatic);
9188 FnTableEntry *fn_table_entry = fn_ref->value.data.x_bound_fn.fn;9170 FnTableEntry *fn_table_entry = fn_ref->value.data.x_bound_fn.fn;
9189 IrInstruction *first_arg_ptr = fn_ref->value.data.x_bound_fn.first_arg;9171 IrInstruction *first_arg_ptr = fn_ref->value.data.x_bound_fn.first_arg;
9190 bool is_inline = fn_ref->value.data.x_bound_fn.is_inline;
9191 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,9172 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,
9192 nullptr, first_arg_ptr, is_comptime, is_inline);9173 nullptr, first_arg_ptr, is_comptime, call_instruction->is_inline);
9193 } else {9174 } else {
9194 ir_add_error_node(ira, fn_ref->source_node,9175 ir_add_error_node(ira, fn_ref->source_node,
9195 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name)));9176 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name)));
...@@ -11736,38 +11717,6 @@ static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIn...@@ -11736,38 +11717,6 @@ static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIn
11736 return result->value.type;11717 return result->value.type;
11737}11718}
1173811719
11739static TypeTableEntry *ir_analyze_instruction_set_fn_ref_inline(IrAnalyze *ira,
11740 IrInstructionSetFnRefInline *instruction)
11741{
11742 IrInstruction *fn_ref = instruction->fn_ref->other;
11743 if (type_is_invalid(fn_ref->value.type))
11744 return ira->codegen->builtin_types.entry_invalid;
11745
11746 if (fn_ref->value.type->id == TypeTableEntryIdFn) {
11747 ConstExprValue *fn_ref_val = ir_resolve_const(ira, fn_ref, UndefBad);
11748 if (!fn_ref_val)
11749 return ira->codegen->builtin_types.entry_invalid;
11750
11751 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
11752 *out_val = *fn_ref_val;
11753 out_val->data.x_fn.is_inline = true;
11754 return out_val->type;
11755 } else if (fn_ref->value.type->id == TypeTableEntryIdBoundFn) {
11756 ConstExprValue *fn_ref_val = ir_resolve_const(ira, fn_ref, UndefBad);
11757 if (!fn_ref_val)
11758 return ira->codegen->builtin_types.entry_invalid;
11759
11760 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
11761 *out_val = *fn_ref_val;
11762 out_val->data.x_bound_fn.is_inline = true;
11763 return out_val->type;
11764 } else {
11765 ir_add_error(ira, &instruction->base,
11766 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_ref->value.type->name)));
11767 return ira->codegen->builtin_types.entry_invalid;
11768 }
11769}
11770
11771static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,11720static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
11772 IrInstructionFieldParentPtr *instruction)11721 IrInstructionFieldParentPtr *instruction)
11773{11722{
...@@ -13403,8 +13352,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -13403,8 +13352,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
13403 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);13352 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
13404 case IrInstructionIdEnumTagName:13353 case IrInstructionIdEnumTagName:
13405 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionEnumTagName *)instruction);13354 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionEnumTagName *)instruction);
13406 case IrInstructionIdSetFnRefInline:
13407 return ir_analyze_instruction_set_fn_ref_inline(ira, (IrInstructionSetFnRefInline *)instruction);
13408 case IrInstructionIdFieldParentPtr:13355 case IrInstructionIdFieldParentPtr:
13409 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction);13356 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction);
13410 case IrInstructionIdOffsetOf:13357 case IrInstructionIdOffsetOf:
...@@ -13585,7 +13532,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -13585,7 +13532,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
13585 case IrInstructionIdErrName:13532 case IrInstructionIdErrName:
13586 case IrInstructionIdTypeName:13533 case IrInstructionIdTypeName:
13587 case IrInstructionIdEnumTagName:13534 case IrInstructionIdEnumTagName:
13588 case IrInstructionIdSetFnRefInline:
13589 case IrInstructionIdFieldParentPtr:13535 case IrInstructionIdFieldParentPtr:
13590 case IrInstructionIdOffsetOf:13536 case IrInstructionIdOffsetOf:
13591 return false;13537 return false;
src/ir_print.cpp-8
...@@ -866,11 +866,6 @@ static void ir_print_panic(IrPrint *irp, IrInstructionPanic *instruction) {...@@ -866,11 +866,6 @@ static void ir_print_panic(IrPrint *irp, IrInstructionPanic *instruction) {
866 fprintf(irp->f, ")");866 fprintf(irp->f, ")");
867}867}
868868
869static void ir_print_set_fn_ref_inline(IrPrint *irp, IrInstructionSetFnRefInline *instruction) {
870 fprintf(irp->f, "inline ");
871 ir_print_other_instruction(irp, instruction->fn_ref);
872}
873
874static void ir_print_field_parent_ptr(IrPrint *irp, IrInstructionFieldParentPtr *instruction) {869static void ir_print_field_parent_ptr(IrPrint *irp, IrInstructionFieldParentPtr *instruction) {
875 fprintf(irp->f, "@fieldParentPtr(");870 fprintf(irp->f, "@fieldParentPtr(");
876 ir_print_other_instruction(irp, instruction->type_value);871 ir_print_other_instruction(irp, instruction->type_value);
...@@ -1167,9 +1162,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1167,9 +1162,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1167 case IrInstructionIdPanic:1162 case IrInstructionIdPanic:
1168 ir_print_panic(irp, (IrInstructionPanic *)instruction);1163 ir_print_panic(irp, (IrInstructionPanic *)instruction);
1169 break;1164 break;
1170 case IrInstructionIdSetFnRefInline:
1171 ir_print_set_fn_ref_inline(irp, (IrInstructionSetFnRefInline *)instruction);
1172 break;
1173 case IrInstructionIdFieldParentPtr:1165 case IrInstructionIdFieldParentPtr:
1174 ir_print_field_parent_ptr(irp, (IrInstructionFieldParentPtr *)instruction);1166 ir_print_field_parent_ptr(irp, (IrInstructionFieldParentPtr *)instruction);
1175 break;1167 break;
src/parser.cpp+12-39
...@@ -850,32 +850,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, size_t *token_inde...@@ -850,32 +850,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, size_t *token_inde
850}850}
851851
852/*852/*
853InlineExpression = option("inline") PrimaryExpression853SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
854*/
855static AstNode *ast_parse_inline_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
856 Token *token = &pc->tokens->at(*token_index);
857
858 if (token->id == TokenIdKeywordInline) {
859 *token_index += 1;
860 AstNode *primary_expr_node = ast_parse_primary_expr(pc, token_index, true);
861 if (primary_expr_node->type == NodeTypeWhileExpr) {
862 primary_expr_node->data.while_expr.is_inline = true;
863 return primary_expr_node;
864 } else if (primary_expr_node->type == NodeTypeForExpr) {
865 primary_expr_node->data.for_expr.is_inline = true;
866 return primary_expr_node;
867 } else {
868 AstNode *node = ast_create_node(pc, NodeTypeInlineExpr, token);
869 node->data.inline_expr.body = primary_expr_node;
870 return node;
871 }
872 } else {
873 return ast_parse_primary_expr(pc, token_index, mandatory);
874 }
875}
876
877/*
878SuffixOpExpression = InlineExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
879FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)854FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)
880ArrayAccessExpression : token(LBracket) Expression token(RBracket)855ArrayAccessExpression : token(LBracket) Expression token(RBracket)
881SliceExpression = "[" Expression "..." option(Expression) "]"856SliceExpression = "[" Expression "..." option(Expression) "]"
...@@ -883,8 +858,8 @@ FieldAccessExpression : token(Dot) token(Symbol)...@@ -883,8 +858,8 @@ FieldAccessExpression : token(Dot) token(Symbol)
883StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression858StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression
884*/859*/
885static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {860static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
886 AstNode *inline_expr = ast_parse_inline_expr(pc, token_index, mandatory);861 AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory);
887 if (!inline_expr)862 if (!primary_expr)
888 return nullptr;863 return nullptr;
889864
890 while (true) {865 while (true) {
...@@ -893,10 +868,10 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,...@@ -893,10 +868,10 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,
893 *token_index += 1;868 *token_index += 1;
894869
895 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token);870 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token);
896 node->data.fn_call_expr.fn_ref_expr = inline_expr;871 node->data.fn_call_expr.fn_ref_expr = primary_expr;
897 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);872 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);
898873
899 inline_expr = node;874 primary_expr = node;
900 } else if (first_token->id == TokenIdLBracket) {875 } else if (first_token->id == TokenIdLBracket) {
901 *token_index += 1;876 *token_index += 1;
902877
...@@ -908,21 +883,21 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,...@@ -908,21 +883,21 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,
908 *token_index += 1;883 *token_index += 1;
909884
910 AstNode *node = ast_create_node(pc, NodeTypeSliceExpr, first_token);885 AstNode *node = ast_create_node(pc, NodeTypeSliceExpr, first_token);
911 node->data.slice_expr.array_ref_expr = inline_expr;886 node->data.slice_expr.array_ref_expr = primary_expr;
912 node->data.slice_expr.start = expr_node;887 node->data.slice_expr.start = expr_node;
913 node->data.slice_expr.end = ast_parse_expression(pc, token_index, false);888 node->data.slice_expr.end = ast_parse_expression(pc, token_index, false);
914889
915 ast_eat_token(pc, token_index, TokenIdRBracket);890 ast_eat_token(pc, token_index, TokenIdRBracket);
916891
917 inline_expr = node;892 primary_expr = node;
918 } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) {893 } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) {
919 *token_index += 1;894 *token_index += 1;
920895
921 AstNode *node = ast_create_node(pc, NodeTypeArrayAccessExpr, first_token);896 AstNode *node = ast_create_node(pc, NodeTypeArrayAccessExpr, first_token);
922 node->data.array_access_expr.array_ref_expr = inline_expr;897 node->data.array_access_expr.array_ref_expr = primary_expr;
923 node->data.array_access_expr.subscript = expr_node;898 node->data.array_access_expr.subscript = expr_node;
924899
925 inline_expr = node;900 primary_expr = node;
926 } else {901 } else {
927 ast_invalid_token_error(pc, first_token);902 ast_invalid_token_error(pc, first_token);
928 }903 }
...@@ -932,12 +907,12 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,...@@ -932,12 +907,12 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,
932 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);907 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
933908
934 AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token);909 AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token);
935 node->data.field_access_expr.struct_expr = inline_expr;910 node->data.field_access_expr.struct_expr = primary_expr;
936 node->data.field_access_expr.field_name = token_buf(name_token);911 node->data.field_access_expr.field_name = token_buf(name_token);
937912
938 inline_expr = node;913 primary_expr = node;
939 } else {914 } else {
940 return inline_expr;915 return primary_expr;
941 }916 }
942 }917 }
943}918}
...@@ -2733,7 +2708,5 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2733,7 +2708,5 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2733 case NodeTypeVarLiteral:2708 case NodeTypeVarLiteral:
2734 // none2709 // none
2735 break;2710 break;
2736 case NodeTypeInlineExpr:
2737 visit_field(&node->data.inline_expr.body, visit, context);
2738 }2711 }
2739}2712}
test/cases/fn.zig+1-1
...@@ -90,7 +90,7 @@ fn fn4() -> u32 {8}...@@ -90,7 +90,7 @@ fn fn4() -> u32 {8}
9090
9191
92test "inline function call" {92test "inline function call" {
93 assert((inline add(3, 9)) == 12);93 assert(@inlineCall(add, 3, 9) == 12);
94}94}
9595
96fn add(a: i32, b: i32) -> i32 { a + b }96fn add(a: i32, b: i32) -> i32 { a + b }