diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-05-15 00:25:13 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-05-15 00:25:13 -0700 |
| commit | 7f90dbbb11456f13eab2588ceb075e55dab93958 (patch) | |
| tree | 4c47a6444f0d4ac1da44fd8611a11f12c92fc1ce /src/analyze.cpp | |
| parent | 6ae6b5f5b546ab63311b6b08281f5962c9d24667 (diff) | |
| download | zig-7f90dbbb11456f13eab2588ceb075e55dab93958.tar.gz zig-7f90dbbb11456f13eab2588ceb075e55dab93958.zip | |
switch on compile var marks entire namespaces
as depending on compile vars.
closes #154
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 93 |
1 files changed, 55 insertions, 38 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 6766c6d247..cdfc2aca4b 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -30,13 +30,15 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry * static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, TypeTableEntry *expected_type, AstNode *node); static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node); -static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn); -static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type); +static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn, + bool depends_on_compile_var); +static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type, + bool depends_on_compile_var); static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, AstNode *node, TypeTableEntry *expected_type, uint64_t x); static AstNode *find_decl(BlockContext *context, Buf *name); static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node, - bool pointer_only, BlockContext *block_context); + bool pointer_only, BlockContext *block_context, bool depends_on_compile_var); static TopLevelDecl *get_as_top_level_decl(AstNode *node); static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *source_node, @@ -2587,7 +2589,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i node->data.field_access_expr.is_member_fn = true; FnTableEntry *fn_entry = fn_decl_node->data.fn_proto.fn_table_entry; - return resolve_expr_const_val_as_fn(g, node, fn_entry); + return resolve_expr_const_val_as_fn(g, node, fn_entry, false); } else { add_node_error(g, node, buf_sprintf("no function named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&bare_struct_type->name))); @@ -2642,7 +2644,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i AstNode *decl_node = entry ? entry->value : nullptr; if (decl_node) { bool pointer_only = false; - return analyze_decl_ref(g, node, decl_node, pointer_only, context); + return analyze_decl_ref(g, node, decl_node, pointer_only, context, false); } else { add_node_error(g, node, buf_sprintf("container '%s' has no member called '%s'", @@ -2652,7 +2654,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i } else if (child_type->id == TypeTableEntryIdPureError) { return analyze_error_literal_expr(g, import, context, node, field_name); } else if (wrapped_in_fn_call) { // this branch should go last, before the error in the else case - return resolve_expr_const_val_as_type(g, node, child_type); + return resolve_expr_const_val_as_type(g, node, child_type, false); } else { add_node_error(g, node, 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 add_error_note(g, msg, decl_node, buf_sprintf("declared here")); } bool pointer_only = false; - return analyze_decl_ref(g, node, decl_node, pointer_only, context); + return analyze_decl_ref(g, node, decl_node, pointer_only, context, + const_val->depends_on_compile_var); } else { const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)"; add_node_error(g, node, @@ -2770,33 +2773,44 @@ static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node) return g->builtin_types.entry_void; } -static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type) { +static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type, + bool depends_on_compile_var) +{ Expr *expr = get_resolved_expr(node); expr->const_val.ok = true; expr->const_val.data.x_type = type; + expr->const_val.depends_on_compile_var = depends_on_compile_var; return g->builtin_types.entry_type; } -static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other) { +static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other, + bool depends_on_compile_var) +{ Expr *expr = get_resolved_expr(node); Expr *other_expr = get_resolved_expr(other); expr->const_val = other_expr->const_val; + expr->const_val.depends_on_compile_var = expr->const_val.depends_on_compile_var || + depends_on_compile_var; return other_expr->type_entry; } -static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn) { +static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn, + bool depends_on_compile_var) +{ Expr *expr = get_resolved_expr(node); expr->const_val.ok = true; expr->const_val.data.x_fn = fn; + expr->const_val.depends_on_compile_var = depends_on_compile_var; return fn->type_entry; } static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode *node, - TypeTableEntry *type_entry) + TypeTableEntry *type_entry, bool depends_on_compile_var) { Expr *expr = get_resolved_expr(node); expr->const_val.ok = true; expr->const_val.data.x_type = type_entry; + expr->const_val.depends_on_compile_var = depends_on_compile_var; return type_entry; } @@ -2922,7 +2936,7 @@ static bool var_is_pure(VariableTableEntry *var, BlockContext *context) { } static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, VariableTableEntry *var, - BlockContext *context) + BlockContext *context, bool depends_on_compile_var) { get_resolved_expr(source_node)->variable = var; if (!var_is_pure(var, context)) { @@ -2931,14 +2945,15 @@ static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, Variabl if (var->is_const && var->val_node) { ConstExprValue *other_const_val = &get_resolved_expr(var->val_node)->const_val; if (other_const_val->ok) { - return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node); + return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node, + depends_on_compile_var); } } return var->type; } static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node, - bool pointer_only, BlockContext *block_context) + bool pointer_only, BlockContext *block_context, bool depends_on_compile_var) { resolve_top_level_decl(g, decl_node, pointer_only); TopLevelDecl *tld = get_as_top_level_decl(decl_node); @@ -2948,27 +2963,29 @@ static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNod if (decl_node->type == NodeTypeVariableDeclaration) { VariableTableEntry *var = decl_node->data.variable_declaration.variable; - return analyze_var_ref(g, source_node, var, block_context); + return analyze_var_ref(g, source_node, var, block_context, depends_on_compile_var); } else if (decl_node->type == NodeTypeFnProto) { if (decl_node->data.fn_proto.generic_params.length > 0) { TypeTableEntry *type_entry = decl_node->data.fn_proto.generic_fn_type; assert(type_entry); - return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry); + return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry, depends_on_compile_var); } else { FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry; assert(fn_entry->type_entry); - return resolve_expr_const_val_as_fn(g, source_node, fn_entry); + return resolve_expr_const_val_as_fn(g, source_node, fn_entry, depends_on_compile_var); } } else if (decl_node->type == NodeTypeStructDecl) { if (decl_node->data.struct_decl.generic_params.length > 0) { TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type; assert(type_entry); - return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry); + return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry, depends_on_compile_var); } else { - return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry); + return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry, + depends_on_compile_var); } } else if (decl_node->type == NodeTypeTypeDecl) { - return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry); + return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry, + depends_on_compile_var); } else { zig_unreachable(); } @@ -2978,25 +2995,25 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, TypeTableEntry *expected_type, AstNode *node, bool pointer_only) { if (node->data.symbol_expr.override_type_entry) { - return resolve_expr_const_val_as_type(g, node, node->data.symbol_expr.override_type_entry); + return resolve_expr_const_val_as_type(g, node, node->data.symbol_expr.override_type_entry, false); } Buf *variable_name = &node->data.symbol_expr.symbol; auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name); if (primitive_table_entry) { - return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value); + return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value, false); } VariableTableEntry *var = find_variable(g, context, variable_name); if (var) { - TypeTableEntry *var_type = analyze_var_ref(g, node, var, context); + TypeTableEntry *var_type = analyze_var_ref(g, node, var, context, false); return var_type; } AstNode *decl_node = find_decl(context, variable_name); if (decl_node) { - return analyze_decl_ref(g, node, decl_node, pointer_only, context); + return analyze_decl_ref(g, node, decl_node, pointer_only, context, false); } if (import->any_imports_failed) { @@ -3819,11 +3836,11 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, return g->builtin_types.entry_invalid; } else { return resolve_expr_const_val_as_type(g, node, - get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint)); + get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint), false); } } else if (context->fn_entry) { return resolve_expr_const_val_as_type(g, node, - get_slice_type(g, child_type, node->data.array_type.is_const)); + get_slice_type(g, child_type, node->data.array_type.is_const), false); } else { add_node_error(g, first_executing_node(size_node), buf_sprintf("unable to evaluate constant expression")); @@ -3831,7 +3848,7 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, } } else { return resolve_expr_const_val_as_type(g, node, - get_slice_type(g, child_type, node->data.array_type.is_const)); + get_slice_type(g, child_type, node->data.array_type.is_const), false); } } @@ -3844,7 +3861,7 @@ static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *impor return type_entry; } - return resolve_expr_const_val_as_type(g, node, type_entry); + return resolve_expr_const_val_as_type(g, node, type_entry, false); } static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, @@ -4973,7 +4990,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry case TypeTableEntryIdUnion: case TypeTableEntryIdFn: case TypeTableEntryIdTypeDecl: - return resolve_expr_const_val_as_type(g, node, type_entry); + return resolve_expr_const_val_as_type(g, node, type_entry, false); } } case BuiltinFnIdCInclude: @@ -5307,10 +5324,10 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp AstNode *impl_decl_node = entry->value; if (impl_decl_node->type == NodeTypeFnProto) { FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry; - return resolve_expr_const_val_as_fn(g, node, fn_table_entry); + return resolve_expr_const_val_as_fn(g, node, fn_table_entry, false); } else if (impl_decl_node->type == NodeTypeStructDecl) { TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry; - return resolve_expr_const_val_as_type(g, node, type_entry); + return resolve_expr_const_val_as_type(g, node, type_entry, false); } else { zig_unreachable(); } @@ -5324,14 +5341,14 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp preview_fn_proto_instance(g, import, impl_decl_node, child_context); g->generic_table.put(generic_fn_type_id, impl_decl_node); FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry; - return resolve_expr_const_val_as_fn(g, node, fn_table_entry); + return resolve_expr_const_val_as_fn(g, node, fn_table_entry, false); } else if (decl_node->type == NodeTypeStructDecl) { AstNode *impl_decl_node = ast_clone_subtree(decl_node, &g->next_node_index); g->generic_table.put(generic_fn_type_id, impl_decl_node); scan_struct_decl(g, import, child_context, impl_decl_node); TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry; resolve_struct_type(g, import, type_entry); - return resolve_expr_const_val_as_type(g, node, type_entry); + return resolve_expr_const_val_as_type(g, node, type_entry, false); } else { zig_unreachable(); } @@ -5480,7 +5497,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo return g->builtin_types.entry_invalid; } else { return resolve_expr_const_val_as_type(g, node, - get_pointer_to_type(g, meta_type, is_const)); + get_pointer_to_type(g, meta_type, is_const), false); } } else if (child_type->id == TypeTableEntryIdNumLitInt || child_type->id == TypeTableEntryIdNumLitFloat) @@ -5520,7 +5537,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in maybe type")); return g->builtin_types.entry_invalid; } else { - return resolve_expr_const_val_as_type(g, node, get_maybe_type(g, meta_type)); + return resolve_expr_const_val_as_type(g, node, get_maybe_type(g, meta_type), false); } } else if (type_entry->id == TypeTableEntryIdUnreachable) { 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 add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in error type")); return g->builtin_types.entry_invalid; } else { - return resolve_expr_const_val_as_type(g, node, get_error_type(g, meta_type)); + return resolve_expr_const_val_as_type(g, node, get_error_type(g, meta_type), false); } } else if (type_entry->id == TypeTableEntryIdUnreachable) { 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 return_type = analyze_fn_proto_expr(g, import, context, expected_type, node); break; case NodeTypeErrorType: - return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error); + return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error, false); break; case NodeTypeTypeLiteral: - return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_type); + return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_type, false); break; case NodeTypeSwitchExpr: return_type = analyze_switch_expr(g, import, context, expected_type, node); |
