1 2 /* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved 4 * written by Walter Bright 5 * http://www.digitalmars.com 6 * Distributed under the Boost Software License, Version 1.0. 7 * http://www.boost.org/LICENSE_1_0.txt 8 * https://github.com/D-Programming-Language/dmd/blob/master/src/staticassert.c 9 */ 10 11 #include "root/dsystem.h" 12 13 #include "mars.h" 14 #include "dsymbol.h" 15 #include "staticassert.h" 16 #include "expression.h" 17 #include "id.h" 18 #include "scope.h" 19 #include "template.h" 20 #include "declaration.h" 21 22 Expression *semantic(Expression *e, Scope *sc); 23 bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors); 24 25 /********************************* AttribDeclaration ****************************/ 26 27 StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg) 28 : Dsymbol(Id::empty) 29 { 30 this->loc = loc; 31 this->exp = exp; 32 this->msg = msg; 33 } 34 35 Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s) 36 { 37 assert(!s); 38 return new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL); 39 } 40 41 void StaticAssert::addMember(Scope *, ScopeDsymbol *) 42 { 43 // we didn't add anything 44 } 45 46 void StaticAssert::semantic(Scope *) 47 { 48 } 49 50 void StaticAssert::semantic2(Scope *sc) 51 { 52 //printf("StaticAssert::semantic2() %s\n", toChars()); 53 ScopeDsymbol *sds = new ScopeDsymbol(); 54 sc = sc->push(sds); 55 sc->tinst = NULL; 56 sc->minst = NULL; 57 58 bool errors = false; 59 bool result = evalStaticCondition(sc, exp, exp, errors); 60 sc = sc->pop(); 61 if (errors) 62 { 63 errorSupplemental(loc, "while evaluating: static assert(%s)", exp->toChars()); 64 } 65 else if (!result) 66 { 67 if (msg) 68 { 69 sc = sc->startCTFE(); 70 msg = ::semantic(msg, sc); 71 msg = resolveProperties(sc, msg); 72 sc = sc->endCTFE(); 73 msg = msg->ctfeInterpret(); 74 if (StringExp * se = msg->toStringExp()) 75 { 76 // same with pragma(msg) 77 se = se->toUTF8(sc); 78 error("\"%.*s\"", (int)se->len, (char *)se->string); 79 } 80 else 81 error("%s", msg->toChars()); 82 } 83 else 84 error("(%s) is false", exp->toChars()); 85 if (sc->tinst) 86 sc->tinst->printInstantiationTrace(); 87 if (!global.gag) 88 fatal(); 89 } 90 } 91 92 bool StaticAssert::oneMember(Dsymbol **ps, Identifier *) 93 { 94 //printf("StaticAssert::oneMember())\n"); 95 *ps = NULL; 96 return true; 97 } 98 99 const char *StaticAssert::kind() const 100 { 101 return "static assert"; 102 } 103