@@ -1011,6 +1011,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *)
1011
1011
return IrInstructionIdAssertNonNull;
1012
1012
}
1013
1013
1014
+ static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) {
1015
+ return IrInstructionIdHasDecl;
1016
+ }
1017
+
1014
1018
template<typename T>
1015
1019
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
1016
1020
T *special_instruction = allocate<T>(1);
@@ -3014,6 +3018,19 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc
3014
3018
return &instruction->base;
3015
3019
}
3016
3020
3021
+ static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *source_node,
3022
+ IrInstruction *container, IrInstruction *name)
3023
+ {
3024
+ IrInstructionHasDecl *instruction = ir_build_instruction<IrInstructionHasDecl>(irb, scope, source_node);
3025
+ instruction->container = container;
3026
+ instruction->name = name;
3027
+
3028
+ ir_ref_instruction(container, irb->current_basic_block);
3029
+ ir_ref_instruction(name, irb->current_basic_block);
3030
+
3031
+ return &instruction->base;
3032
+ }
3033
+
3017
3034
static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {
3018
3035
IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);
3019
3036
instruction->scope_is_comptime = scope_is_comptime;
@@ -5098,6 +5115,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5098
5115
}
5099
5116
return ir_lval_wrap(irb, scope, result, lval);
5100
5117
}
5118
+ case BuiltinFnIdHasDecl:
5119
+ {
5120
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5121
+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
5122
+ if (arg0_value == irb->codegen->invalid_instruction)
5123
+ return arg0_value;
5124
+
5125
+ AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5126
+ IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
5127
+ if (arg1_value == irb->codegen->invalid_instruction)
5128
+ return arg1_value;
5129
+
5130
+ IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value);
5131
+ return ir_lval_wrap(irb, scope, has_decl, lval);
5132
+ }
5101
5133
}
5102
5134
zig_unreachable();
5103
5135
}
@@ -23173,6 +23205,33 @@ static IrInstruction *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira,
23173
23205
return ir_const_void(ira, &instruction->base);
23174
23206
}
23175
23207
23208
+ static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstructionHasDecl *instruction) {
23209
+ ZigType *container_type = ir_resolve_type(ira, instruction->container->child);
23210
+ if (type_is_invalid(container_type))
23211
+ return ira->codegen->invalid_instruction;
23212
+
23213
+ Buf *name = ir_resolve_str(ira, instruction->name->child);
23214
+ if (name == nullptr)
23215
+ return ira->codegen->invalid_instruction;
23216
+
23217
+ if (!is_container(container_type)) {
23218
+ ir_add_error(ira, instruction->container,
23219
+ buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&container_type->name)));
23220
+ return ira->codegen->invalid_instruction;
23221
+ }
23222
+
23223
+ ScopeDecls *container_scope = get_container_scope(container_type);
23224
+ Tld *tld = find_container_decl(ira->codegen, container_scope, name);
23225
+ if (tld == nullptr)
23226
+ return ir_const_bool(ira, &instruction->base, false);
23227
+
23228
+ if (tld->visib_mod == VisibModPrivate && tld->import != get_scope_import(instruction->base.scope)) {
23229
+ return ir_const_bool(ira, &instruction->base, false);
23230
+ }
23231
+
23232
+ return ir_const_bool(ira, &instruction->base, true);
23233
+ }
23234
+
23176
23235
static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
23177
23236
switch (instruction->id) {
23178
23237
case IrInstructionIdInvalid:
@@ -23467,6 +23526,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23467
23526
return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction);
23468
23527
case IrInstructionIdCheckRuntimeScope:
23469
23528
return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction);
23529
+ case IrInstructionIdHasDecl:
23530
+ return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);
23470
23531
}
23471
23532
zig_unreachable();
23472
23533
}
@@ -23703,6 +23764,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
23703
23764
case IrInstructionIdEnumToInt:
23704
23765
case IrInstructionIdVectorToArray:
23705
23766
case IrInstructionIdArrayToVector:
23767
+ case IrInstructionIdHasDecl:
23706
23768
return false;
23707
23769
23708
23770
case IrInstructionIdAsm:
0 commit comments