| |
| /* Compiler implementation of the D programming language |
| * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved |
| * written by Walter Bright |
| * http://www.digitalmars.com |
| * Distributed under the Boost Software License, Version 1.0. |
| * http://www.boost.org/LICENSE_1_0.txt |
| * https://github.com/D-Programming-Language/dmd/blob/master/src/staticassert.c |
| */ |
| |
| #include "root/dsystem.h" |
| |
| #include "mars.h" |
| #include "dsymbol.h" |
| #include "staticassert.h" |
| #include "expression.h" |
| #include "id.h" |
| #include "scope.h" |
| #include "template.h" |
| #include "declaration.h" |
| |
| Expression *semantic(Expression *e, Scope *sc); |
| bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors); |
| |
| /********************************* AttribDeclaration ****************************/ |
| |
| StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg) |
| : Dsymbol(Id::empty) |
| { |
| this->loc = loc; |
| this->exp = exp; |
| this->msg = msg; |
| } |
| |
| Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s) |
| { |
| assert(!s); |
| return new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL); |
| } |
| |
| void StaticAssert::addMember(Scope *, ScopeDsymbol *) |
| { |
| // we didn't add anything |
| } |
| |
| void StaticAssert::semantic(Scope *) |
| { |
| } |
| |
| void StaticAssert::semantic2(Scope *sc) |
| { |
| //printf("StaticAssert::semantic2() %s\n", toChars()); |
| ScopeDsymbol *sds = new ScopeDsymbol(); |
| sc = sc->push(sds); |
| sc->tinst = NULL; |
| sc->minst = NULL; |
| |
| bool errors = false; |
| bool result = evalStaticCondition(sc, exp, exp, errors); |
| sc = sc->pop(); |
| if (errors) |
| { |
| errorSupplemental(loc, "while evaluating: static assert(%s)", exp->toChars()); |
| } |
| else if (!result) |
| { |
| if (msg) |
| { |
| sc = sc->startCTFE(); |
| msg = ::semantic(msg, sc); |
| msg = resolveProperties(sc, msg); |
| sc = sc->endCTFE(); |
| msg = msg->ctfeInterpret(); |
| if (StringExp * se = msg->toStringExp()) |
| { |
| // same with pragma(msg) |
| se = se->toUTF8(sc); |
| error("\"%.*s\"", (int)se->len, (char *)se->string); |
| } |
| else |
| error("%s", msg->toChars()); |
| } |
| else |
| error("(%s) is false", exp->toChars()); |
| if (sc->tinst) |
| sc->tinst->printInstantiationTrace(); |
| if (!global.gag) |
| fatal(); |
| } |
| } |
| |
| bool StaticAssert::oneMember(Dsymbol **ps, Identifier *) |
| { |
| //printf("StaticAssert::oneMember())\n"); |
| *ps = NULL; |
| return true; |
| } |
| |
| const char *StaticAssert::kind() const |
| { |
| return "static assert"; |
| } |