1 /// Copyright: Copyright (c) 2017-2020 Andrey Penechko. 2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 3 /// Authors: Andrey Penechko. 4 module vox.fe.ast.decl.static_assert; 5 6 import vox.all; 7 8 9 @(AstType.decl_static_assert) 10 struct StaticAssertDeclNode 11 { 12 mixin AstNodeData!(AstType.decl_static_assert, 0, AstNodeState.name_register_self_done); 13 AstIndex condition; 14 AstIndex message; // for now only single string is allowed, nullable 15 } 16 17 void print_static_assert(StaticAssertDeclNode* node, ref AstPrintState state) 18 { 19 state.print("#ASSERT"); 20 print_ast(node.condition, state); 21 if (node.message) print_ast(node.message, state); 22 } 23 24 void post_clone_static_assert(StaticAssertDeclNode* node, ref CloneState state) 25 { 26 state.fixAstIndex(node.condition); 27 state.fixAstIndex(node.message); 28 } 29 30 void name_register_nested_static_assert(StaticAssertDeclNode* node, ref NameRegisterState state) 31 { 32 node.state = AstNodeState.name_register_nested; 33 require_name_register(node.condition, state); 34 if (node.message) require_name_register(node.message, state); 35 node.state = AstNodeState.name_register_nested_done; 36 } 37 38 void name_resolve_static_assert(StaticAssertDeclNode* node, ref NameResolveState state) 39 { 40 node.state = AstNodeState.name_resolve; 41 require_name_resolve(node.condition, state); 42 if (node.message) require_name_resolve(node.message, state); 43 node.state = AstNodeState.name_resolve_done; 44 } 45 46 void type_check_static_assert(StaticAssertDeclNode* node, ref TypeCheckState state) 47 { 48 CompilationContext* c = state.context; 49 50 node.state = AstNodeState.type_check; 51 scope(exit) node.state = AstNodeState.type_check_done; 52 53 require_type_check(node.condition, state); 54 if (node.message) { 55 require_type_check(node.message, state); 56 57 if (node.message.astType(c) != AstType.literal_string) { 58 c.error(node.loc, "#assert only supports string literal as a message"); 59 return; 60 } 61 } 62 63 IrIndex val = eval_static_expr(node.condition, c); 64 if (!c.constants.get(val).i64) 65 { 66 if (node.message) 67 c.error(node.loc, "#assert: \"%s\"", node.message.get!StringLiteralExprNode(c).value); 68 else 69 c.error(node.loc, "#assert"); 70 } 71 }