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
StaticAssert(Loc loc,Expression * exp,Expression * msg)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
syntaxCopy(Dsymbol * s)35 Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s)
36 {
37 assert(!s);
38 return new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
39 }
40
addMember(Scope *,ScopeDsymbol *)41 void StaticAssert::addMember(Scope *, ScopeDsymbol *)
42 {
43 // we didn't add anything
44 }
45
semantic(Scope *)46 void StaticAssert::semantic(Scope *)
47 {
48 }
49
semantic2(Scope * sc)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
oneMember(Dsymbol ** ps,Identifier *)92 bool StaticAssert::oneMember(Dsymbol **ps, Identifier *)
93 {
94 //printf("StaticAssert::oneMember())\n");
95 *ps = NULL;
96 return true;
97 }
98
kind()99 const char *StaticAssert::kind() const
100 {
101 return "static assert";
102 }
103