| author | |
| committer | |
| log | e85cd616ef6439fdb9e7ac118251bb7c2296e553 |
| tree | b3661a2f77897e6fcd2483838713193ed0784a5c |
| parent | a97efbd1850cbf12dbf9332f7da2652385a38cd6 |
3 files changed, 50 insertions(+), 1 deletions(-)
src/AstGen.zig+11-1| ... | @@ -1245,6 +1245,7 @@ fn blockExprStmts( | ... | @@ -1245,6 +1245,7 @@ fn blockExprStmts( |
| 1245 | .fn_type_var_args, | 1245 | .fn_type_var_args, |
| 1246 | .fn_type_cc, | 1246 | .fn_type_cc, |
| 1247 | .fn_type_cc_var_args, | 1247 | .fn_type_cc_var_args, |
| 1248 | .has_decl, | ||
| 1248 | .int, | 1249 | .int, |
| 1249 | .float, | 1250 | .float, |
| 1250 | .float128, | 1251 | .float128, |
| ... | @@ -4159,6 +4160,16 @@ fn builtinCall( | ... | @@ -4159,6 +4160,16 @@ fn builtinCall( |
| 4159 | return rvalue(gz, scope, rl, .void_value, node); | 4160 | return rvalue(gz, scope, rl, .void_value, node); |
| 4160 | }, | 4161 | }, |
| 4161 | 4162 | ||
| 4163 | .has_decl => { | ||
| 4164 | const container_type = try typeExpr(gz, scope, params[0]); | ||
| 4165 | const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); | ||
| 4166 | const result = try gz.addPlNode(.has_decl, node, zir.Inst.Bin{ | ||
| 4167 | .lhs = container_type, | ||
| 4168 | .rhs = name, | ||
| 4169 | }); | ||
| 4170 | return rvalue(gz, scope, rl, result, node); | ||
| 4171 | }, | ||
| 4172 | |||
| 4162 | .add_with_overflow, | 4173 | .add_with_overflow, |
| 4163 | .align_cast, | 4174 | .align_cast, |
| 4164 | .align_of, | 4175 | .align_of, |
| ... | @@ -4191,7 +4202,6 @@ fn builtinCall( | ... | @@ -4191,7 +4202,6 @@ fn builtinCall( |
| 4191 | .fence, | 4202 | .fence, |
| 4192 | .field_parent_ptr, | 4203 | .field_parent_ptr, |
| 4193 | .float_to_int, | 4204 | .float_to_int, |
| 4194 | .has_decl, | ||
| 4195 | .has_field, | 4205 | .has_field, |
| 4196 | .int_to_float, | 4206 | .int_to_float, |
| 4197 | .int_to_ptr, | 4207 | .int_to_ptr, |
src/Sema.zig+34| ... | @@ -199,6 +199,7 @@ pub fn analyzeBody( | ... | @@ -199,6 +199,7 @@ pub fn analyzeBody( |
| 199 | .fn_type_cc => try sema.zirFnTypeCc(block, inst, false), | 199 | .fn_type_cc => try sema.zirFnTypeCc(block, inst, false), |
| 200 | .fn_type_cc_var_args => try sema.zirFnTypeCc(block, inst, true), | 200 | .fn_type_cc_var_args => try sema.zirFnTypeCc(block, inst, true), |
| 201 | .fn_type_var_args => try sema.zirFnType(block, inst, true), | 201 | .fn_type_var_args => try sema.zirFnType(block, inst, true), |
| 202 | .has_decl => try sema.zirHasDecl(block, inst), | ||
| 202 | .import => try sema.zirImport(block, inst), | 203 | .import => try sema.zirImport(block, inst), |
| 203 | .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst), | 204 | .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst), |
| 204 | .int => try sema.zirInt(block, inst), | 205 | .int => try sema.zirInt(block, inst), |
| ... | @@ -3624,6 +3625,39 @@ fn validateSwitchNoRange( | ... | @@ -3624,6 +3625,39 @@ fn validateSwitchNoRange( |
| 3624 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); | 3625 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |
| 3625 | } | 3626 | } |
| 3626 | 3627 | ||
| 3628 | fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | ||
| 3629 | const tracy = trace(@src()); | ||
| 3630 | defer tracy.end(); | ||
| 3631 | |||
| 3632 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | ||
| 3633 | const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data; | ||
| 3634 | const src = inst_data.src(); | ||
| 3635 | const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | ||
| 3636 | const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | ||
| 3637 | const container_type = try sema.resolveType(block, lhs_src, extra.lhs); | ||
| 3638 | const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs); | ||
| 3639 | |||
| 3640 | const maybe_scope = container_type.getContainerScope(); | ||
| 3641 | if (maybe_scope == null) { | ||
| 3642 | return sema.mod.fail( | ||
| 3643 | &block.base, | ||
| 3644 | src, | ||
| 3645 | "expected container (struct, enum, or union), found '{}'", | ||
| 3646 | .{container_type}, | ||
| 3647 | ); | ||
| 3648 | } | ||
| 3649 | |||
| 3650 | const found = blk: { | ||
| 3651 | for (maybe_scope.?.decls.items()) |kv| { | ||
| 3652 | if (mem.eql(u8, mem.spanZ(kv.key.name), decl_name)) | ||
| 3653 | break :blk true; | ||
| 3654 | } | ||
| 3655 | break :blk false; | ||
| 3656 | }; | ||
| 3657 | |||
| 3658 | return sema.mod.constBool(sema.arena, src, found); | ||
| 3659 | } | ||
| 3660 | |||
| 3627 | fn zirImport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 3661 | fn zirImport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { |
| 3628 | const tracy = trace(@src()); | 3662 | const tracy = trace(@src()); |
| 3629 | defer tracy.end(); | 3663 | defer tracy.end(); |
src/zir.zig+5| ... | @@ -364,6 +364,9 @@ pub const Inst = struct { | ... | @@ -364,6 +364,9 @@ pub const Inst = struct { |
| 364 | fn_type_cc, | 364 | fn_type_cc, |
| 365 | /// Same as `fn_type_cc` but the function is variadic. | 365 | /// Same as `fn_type_cc` but the function is variadic. |
| 366 | fn_type_cc_var_args, | 366 | fn_type_cc_var_args, |
| 367 | /// Determines whether a container has a declaration matching name. | ||
| 368 | /// Uses the `pl_node` union field. Payload is `Bin`. | ||
| 369 | has_decl, | ||
| 367 | /// `@import(operand)`. | 370 | /// `@import(operand)`. |
| 368 | /// Uses the `un_node` field. | 371 | /// Uses the `un_node` field. |
| 369 | import, | 372 | import, |
| ... | @@ -751,6 +754,7 @@ pub const Inst = struct { | ... | @@ -751,6 +754,7 @@ pub const Inst = struct { |
| 751 | .fn_type_var_args, | 754 | .fn_type_var_args, |
| 752 | .fn_type_cc, | 755 | .fn_type_cc, |
| 753 | .fn_type_cc_var_args, | 756 | .fn_type_cc_var_args, |
| 757 | .has_decl, | ||
| 754 | .int, | 758 | .int, |
| 755 | .float, | 759 | .float, |
| 756 | .float128, | 760 | .float128, |
| ... | @@ -1681,6 +1685,7 @@ const Writer = struct { | ... | @@ -1681,6 +1685,7 @@ const Writer = struct { |
| 1681 | .cmp_gt, | 1685 | .cmp_gt, |
| 1682 | .cmp_neq, | 1686 | .cmp_neq, |
| 1683 | .div, | 1687 | .div, |
| 1688 | .has_decl, | ||
| 1684 | .mod_rem, | 1689 | .mod_rem, |
| 1685 | .shl, | 1690 | .shl, |
| 1686 | .shr, | 1691 | .shr, |