authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-15 00:25:13-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-15 00:25:13-07:00
log7f90dbbb11456f13eab2588ceb075e55dab93958
tree4c47a6444f0d4ac1da44fd8611a11f12c92fc1ce
parent6ae6b5f5b546ab63311b6b08281f5962c9d24667

switch on compile var marks entire namespaces

as depending on compile vars. closes #154

4 files changed, 71 insertions(+), 38 deletions(-)

src/analyze.cpp+55-38
......@@ -30,13 +30,15 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
3030static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3131 TypeTableEntry *expected_type, AstNode *node);
3232static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node);
33static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn);
34static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type);
33static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn,
34 bool depends_on_compile_var);
35static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type,
36 bool depends_on_compile_var);
3537static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, AstNode *node,
3638 TypeTableEntry *expected_type, uint64_t x);
3739static AstNode *find_decl(BlockContext *context, Buf *name);
3840static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node,
39 bool pointer_only, BlockContext *block_context);
41 bool pointer_only, BlockContext *block_context, bool depends_on_compile_var);
4042static TopLevelDecl *get_as_top_level_decl(AstNode *node);
4143static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTableEntry *import,
4244 BlockContext *context, AstNode *source_node,
......@@ -2587,7 +2589,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
25872589
25882590 node->data.field_access_expr.is_member_fn = true;
25892591 FnTableEntry *fn_entry = fn_decl_node->data.fn_proto.fn_table_entry;
2590 return resolve_expr_const_val_as_fn(g, node, fn_entry);
2592 return resolve_expr_const_val_as_fn(g, node, fn_entry, false);
25912593 } else {
25922594 add_node_error(g, node, buf_sprintf("no function named '%s' in '%s'",
25932595 buf_ptr(field_name), buf_ptr(&bare_struct_type->name)));
......@@ -2642,7 +2644,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
26422644 AstNode *decl_node = entry ? entry->value : nullptr;
26432645 if (decl_node) {
26442646 bool pointer_only = false;
2645 return analyze_decl_ref(g, node, decl_node, pointer_only, context);
2647 return analyze_decl_ref(g, node, decl_node, pointer_only, context, false);
26462648 } else {
26472649 add_node_error(g, node,
26482650 buf_sprintf("container '%s' has no member called '%s'",
......@@ -2652,7 +2654,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
26522654 } else if (child_type->id == TypeTableEntryIdPureError) {
26532655 return analyze_error_literal_expr(g, import, context, node, field_name);
26542656 } else if (wrapped_in_fn_call) { // this branch should go last, before the error in the else case
2655 return resolve_expr_const_val_as_type(g, node, child_type);
2657 return resolve_expr_const_val_as_type(g, node, child_type, false);
26562658 } else {
26572659 add_node_error(g, node,
26582660 buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
......@@ -2671,7 +2673,8 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
26712673 add_error_note(g, msg, decl_node, buf_sprintf("declared here"));
26722674 }
26732675 bool pointer_only = false;
2674 return analyze_decl_ref(g, node, decl_node, pointer_only, context);
2676 return analyze_decl_ref(g, node, decl_node, pointer_only, context,
2677 const_val->depends_on_compile_var);
26752678 } else {
26762679 const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)";
26772680 add_node_error(g, node,
......@@ -2770,33 +2773,44 @@ static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node)
27702773 return g->builtin_types.entry_void;
27712774}
27722775
2773static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type) {
2776static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type,
2777 bool depends_on_compile_var)
2778{
27742779 Expr *expr = get_resolved_expr(node);
27752780 expr->const_val.ok = true;
27762781 expr->const_val.data.x_type = type;
2782 expr->const_val.depends_on_compile_var = depends_on_compile_var;
27772783 return g->builtin_types.entry_type;
27782784}
27792785
2780static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other) {
2786static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other,
2787 bool depends_on_compile_var)
2788{
27812789 Expr *expr = get_resolved_expr(node);
27822790 Expr *other_expr = get_resolved_expr(other);
27832791 expr->const_val = other_expr->const_val;
2792 expr->const_val.depends_on_compile_var = expr->const_val.depends_on_compile_var ||
2793 depends_on_compile_var;
27842794 return other_expr->type_entry;
27852795}
27862796
2787static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn) {
2797static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn,
2798 bool depends_on_compile_var)
2799{
27882800 Expr *expr = get_resolved_expr(node);
27892801 expr->const_val.ok = true;
27902802 expr->const_val.data.x_fn = fn;
2803 expr->const_val.depends_on_compile_var = depends_on_compile_var;
27912804 return fn->type_entry;
27922805}
27932806
27942807static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode *node,
2795 TypeTableEntry *type_entry)
2808 TypeTableEntry *type_entry, bool depends_on_compile_var)
27962809{
27972810 Expr *expr = get_resolved_expr(node);
27982811 expr->const_val.ok = true;
27992812 expr->const_val.data.x_type = type_entry;
2813 expr->const_val.depends_on_compile_var = depends_on_compile_var;
28002814 return type_entry;
28012815}
28022816
......@@ -2922,7 +2936,7 @@ static bool var_is_pure(VariableTableEntry *var, BlockContext *context) {
29222936}
29232937
29242938static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, VariableTableEntry *var,
2925 BlockContext *context)
2939 BlockContext *context, bool depends_on_compile_var)
29262940{
29272941 get_resolved_expr(source_node)->variable = var;
29282942 if (!var_is_pure(var, context)) {
......@@ -2931,14 +2945,15 @@ static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, Variabl
29312945 if (var->is_const && var->val_node) {
29322946 ConstExprValue *other_const_val = &get_resolved_expr(var->val_node)->const_val;
29332947 if (other_const_val->ok) {
2934 return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node);
2948 return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node,
2949 depends_on_compile_var);
29352950 }
29362951 }
29372952 return var->type;
29382953}
29392954
29402955static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node,
2941 bool pointer_only, BlockContext *block_context)
2956 bool pointer_only, BlockContext *block_context, bool depends_on_compile_var)
29422957{
29432958 resolve_top_level_decl(g, decl_node, pointer_only);
29442959 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
......@@ -2948,27 +2963,29 @@ static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNod
29482963
29492964 if (decl_node->type == NodeTypeVariableDeclaration) {
29502965 VariableTableEntry *var = decl_node->data.variable_declaration.variable;
2951 return analyze_var_ref(g, source_node, var, block_context);
2966 return analyze_var_ref(g, source_node, var, block_context, depends_on_compile_var);
29522967 } else if (decl_node->type == NodeTypeFnProto) {
29532968 if (decl_node->data.fn_proto.generic_params.length > 0) {
29542969 TypeTableEntry *type_entry = decl_node->data.fn_proto.generic_fn_type;
29552970 assert(type_entry);
2956 return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry);
2971 return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry, depends_on_compile_var);
29572972 } else {
29582973 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;
29592974 assert(fn_entry->type_entry);
2960 return resolve_expr_const_val_as_fn(g, source_node, fn_entry);
2975 return resolve_expr_const_val_as_fn(g, source_node, fn_entry, depends_on_compile_var);
29612976 }
29622977 } else if (decl_node->type == NodeTypeStructDecl) {
29632978 if (decl_node->data.struct_decl.generic_params.length > 0) {
29642979 TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;
29652980 assert(type_entry);
2966 return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry);
2981 return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry, depends_on_compile_var);
29672982 } else {
2968 return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry);
2983 return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry,
2984 depends_on_compile_var);
29692985 }
29702986 } else if (decl_node->type == NodeTypeTypeDecl) {
2971 return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry);
2987 return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry,
2988 depends_on_compile_var);
29722989 } else {
29732990 zig_unreachable();
29742991 }
......@@ -2978,25 +2995,25 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import,
29782995 TypeTableEntry *expected_type, AstNode *node, bool pointer_only)
29792996{
29802997 if (node->data.symbol_expr.override_type_entry) {
2981 return resolve_expr_const_val_as_type(g, node, node->data.symbol_expr.override_type_entry);
2998 return resolve_expr_const_val_as_type(g, node, node->data.symbol_expr.override_type_entry, false);
29822999 }
29833000
29843001 Buf *variable_name = &node->data.symbol_expr.symbol;
29853002
29863003 auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name);
29873004 if (primitive_table_entry) {
2988 return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value);
3005 return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value, false);
29893006 }
29903007
29913008 VariableTableEntry *var = find_variable(g, context, variable_name);
29923009 if (var) {
2993 TypeTableEntry *var_type = analyze_var_ref(g, node, var, context);
3010 TypeTableEntry *var_type = analyze_var_ref(g, node, var, context, false);
29943011 return var_type;
29953012 }
29963013
29973014 AstNode *decl_node = find_decl(context, variable_name);
29983015 if (decl_node) {
2999 return analyze_decl_ref(g, node, decl_node, pointer_only, context);
3016 return analyze_decl_ref(g, node, decl_node, pointer_only, context, false);
30003017 }
30013018
30023019 if (import->any_imports_failed) {
......@@ -3819,11 +3836,11 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
38193836 return g->builtin_types.entry_invalid;
38203837 } else {
38213838 return resolve_expr_const_val_as_type(g, node,
3822 get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint));
3839 get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint), false);
38233840 }
38243841 } else if (context->fn_entry) {
38253842 return resolve_expr_const_val_as_type(g, node,
3826 get_slice_type(g, child_type, node->data.array_type.is_const));
3843 get_slice_type(g, child_type, node->data.array_type.is_const), false);
38273844 } else {
38283845 add_node_error(g, first_executing_node(size_node),
38293846 buf_sprintf("unable to evaluate constant expression"));
......@@ -3831,7 +3848,7 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
38313848 }
38323849 } else {
38333850 return resolve_expr_const_val_as_type(g, node,
3834 get_slice_type(g, child_type, node->data.array_type.is_const));
3851 get_slice_type(g, child_type, node->data.array_type.is_const), false);
38353852 }
38363853}
38373854
......@@ -3844,7 +3861,7 @@ static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *impor
38443861 return type_entry;
38453862 }
38463863
3847 return resolve_expr_const_val_as_type(g, node, type_entry);
3864 return resolve_expr_const_val_as_type(g, node, type_entry, false);
38483865}
38493866
38503867static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
......@@ -4973,7 +4990,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
49734990 case TypeTableEntryIdUnion:
49744991 case TypeTableEntryIdFn:
49754992 case TypeTableEntryIdTypeDecl:
4976 return resolve_expr_const_val_as_type(g, node, type_entry);
4993 return resolve_expr_const_val_as_type(g, node, type_entry, false);
49774994 }
49784995 }
49794996 case BuiltinFnIdCInclude:
......@@ -5307,10 +5324,10 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp
53075324 AstNode *impl_decl_node = entry->value;
53085325 if (impl_decl_node->type == NodeTypeFnProto) {
53095326 FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry;
5310 return resolve_expr_const_val_as_fn(g, node, fn_table_entry);
5327 return resolve_expr_const_val_as_fn(g, node, fn_table_entry, false);
53115328 } else if (impl_decl_node->type == NodeTypeStructDecl) {
53125329 TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry;
5313 return resolve_expr_const_val_as_type(g, node, type_entry);
5330 return resolve_expr_const_val_as_type(g, node, type_entry, false);
53145331 } else {
53155332 zig_unreachable();
53165333 }
......@@ -5324,14 +5341,14 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp
53245341 preview_fn_proto_instance(g, import, impl_decl_node, child_context);
53255342 g->generic_table.put(generic_fn_type_id, impl_decl_node);
53265343 FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry;
5327 return resolve_expr_const_val_as_fn(g, node, fn_table_entry);
5344 return resolve_expr_const_val_as_fn(g, node, fn_table_entry, false);
53285345 } else if (decl_node->type == NodeTypeStructDecl) {
53295346 AstNode *impl_decl_node = ast_clone_subtree(decl_node, &g->next_node_index);
53305347 g->generic_table.put(generic_fn_type_id, impl_decl_node);
53315348 scan_struct_decl(g, import, child_context, impl_decl_node);
53325349 TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry;
53335350 resolve_struct_type(g, import, type_entry);
5334 return resolve_expr_const_val_as_type(g, node, type_entry);
5351 return resolve_expr_const_val_as_type(g, node, type_entry, false);
53355352 } else {
53365353 zig_unreachable();
53375354 }
......@@ -5480,7 +5497,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
54805497 return g->builtin_types.entry_invalid;
54815498 } else {
54825499 return resolve_expr_const_val_as_type(g, node,
5483 get_pointer_to_type(g, meta_type, is_const));
5500 get_pointer_to_type(g, meta_type, is_const), false);
54845501 }
54855502 } else if (child_type->id == TypeTableEntryIdNumLitInt ||
54865503 child_type->id == TypeTableEntryIdNumLitFloat)
......@@ -5520,7 +5537,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
55205537 add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in maybe type"));
55215538 return g->builtin_types.entry_invalid;
55225539 } else {
5523 return resolve_expr_const_val_as_type(g, node, get_maybe_type(g, meta_type));
5540 return resolve_expr_const_val_as_type(g, node, get_maybe_type(g, meta_type), false);
55245541 }
55255542 } else if (type_entry->id == TypeTableEntryIdUnreachable) {
55265543 add_node_error(g, *expr_node, buf_sprintf("unable to wrap unreachable in maybe type"));
......@@ -5548,7 +5565,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
55485565 add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in error type"));
55495566 return g->builtin_types.entry_invalid;
55505567 } else {
5551 return resolve_expr_const_val_as_type(g, node, get_error_type(g, meta_type));
5568 return resolve_expr_const_val_as_type(g, node, get_error_type(g, meta_type), false);
55525569 }
55535570 } else if (type_entry->id == TypeTableEntryIdUnreachable) {
55545571 add_node_error(g, *expr_node, buf_sprintf("unable to wrap unreachable in error type"));
......@@ -6159,10 +6176,10 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn
61596176 return_type = analyze_fn_proto_expr(g, import, context, expected_type, node);
61606177 break;
61616178 case NodeTypeErrorType:
6162 return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error);
6179 return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error, false);
61636180 break;
61646181 case NodeTypeTypeLiteral:
6165 return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_type);
6182 return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_type, false);
61666183 break;
61676184 case NodeTypeSwitchExpr:
61686185 return_type = analyze_switch_expr(g, import, context, expected_type, node);
test/a.zig created+1
......@@ -0,0 +1 @@
1pub const a_bool = true;
test/b.zig created+1
......@@ -0,0 +1 @@
1pub const a_bool = false;
test/self_hosted.zig+14
......@@ -1656,3 +1656,17 @@ fn use_generic_param_in_generic_param() {
16561656fn a_generic_fn(T: type, a: T)(b: T) -> T {
16571657 return a + b;
16581658}
1659
1660
1661#attribute("test")
1662fn namespace_depends_on_compile_var() {
1663 if (some_namespace.a_bool) {
1664 assert(some_namespace.a_bool);
1665 } else {
1666 assert(!some_namespace.a_bool);
1667 }
1668}
1669const some_namespace = switch(@compile_var("os")) {
1670 linux => @import("a.zig"),
1671 else => @import("b.zig"),
1672};