1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (c) 1999-2016 by Digital Mars, All Rights Reserved 6 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 7 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 8 * Source: $(DMDSRC _staticassert.d) 9 */ 10 11 module ddmd.staticassert; 12 13 import ddmd.dscope; 14 import ddmd.dsymbol; 15 import ddmd.errors; 16 import ddmd.expression; 17 import ddmd.globals; 18 import ddmd.id; 19 import ddmd.identifier; 20 import ddmd.mtype; 21 import ddmd.visitor; 22 23 /*********************************************************** 24 */ 25 extern (C++) final class StaticAssert : Dsymbol 26 { 27 Expression exp; 28 Expression msg; 29 30 extern (D) this(Loc loc, Expression exp, Expression msg) 31 { 32 super(Id.empty); 33 this.loc = loc; 34 this.exp = exp; 35 this.msg = msg; 36 } 37 38 override Dsymbol syntaxCopy(Dsymbol s) 39 { 40 assert(!s); 41 return new StaticAssert(loc, exp.syntaxCopy(), msg ? msg.syntaxCopy() : null); 42 } 43 44 override void addMember(Scope* sc, ScopeDsymbol sds) 45 { 46 // we didn't add anything 47 } 48 49 override void semantic(Scope* sc) 50 { 51 } 52 53 override void semantic2(Scope* sc) 54 { 55 //printf("StaticAssert::semantic2() %s\n", toChars()); 56 auto sds = new ScopeDsymbol(); 57 sc = sc.push(sds); 58 sc.tinst = null; 59 sc.minst = null; 60 sc.flags |= SCOPEcondition; 61 sc = sc.startCTFE(); 62 Expression e = exp.semantic(sc); 63 e = resolveProperties(sc, e); 64 sc = sc.endCTFE(); 65 sc = sc.pop(); 66 // Simplify expression, to make error messages nicer if CTFE fails 67 e = e.optimize(WANTvalue); 68 if (!e.type.isBoolean()) 69 { 70 if (e.type.toBasetype() != Type.terror) 71 exp.error("expression %s of type %s does not have a boolean value", exp.toChars(), e.type.toChars()); 72 return; 73 } 74 uint olderrs = global.errors; 75 e = e.ctfeInterpret(); 76 if (global.errors != olderrs) 77 { 78 errorSupplemental(loc, "while evaluating: static assert(%s)", exp.toChars()); 79 } 80 else if (e.isBool(false)) 81 { 82 if (msg) 83 { 84 sc = sc.startCTFE(); 85 msg = msg.semantic(sc); 86 msg = resolveProperties(sc, msg); 87 sc = sc.endCTFE(); 88 msg = msg.ctfeInterpret(); 89 if (StringExp se = msg.toStringExp()) 90 { 91 // same with pragma(msg) 92 se = se.toUTF8(sc); 93 error("\"%.*s\"", cast(int)se.len, se..string); 94 } 95 else 96 error("%s", msg.toChars()); 97 } 98 else 99 error("(%s) is false", exp.toChars()); 100 if (sc.tinst) 101 sc.tinst.printInstantiationTrace(); 102 if (!global.gag) 103 fatal(); 104 } 105 else if (!e.isBool(true)) 106 { 107 error("(%s) is not evaluatable at compile time", exp.toChars()); 108 } 109 } 110 111 override bool oneMember(Dsymbol* ps, Identifier ident) 112 { 113 //printf("StaticAssert::oneMember())\n"); 114 *ps = null; 115 return true; 116 } 117 118 override const(char)* kind() const 119 { 120 return "static assert"; 121 } 122 123 override void accept(Visitor v) 124 { 125 v.visit(this); 126 } 127 }