ldc/ddmd/staticassert.d
David Nadlinger 9f998a398d Initial merge of upstream v2.071.0-b2
Notably, the glue layer side of the changed multiple interface
inheritance layout (DMD a54e89d) has not been implemented yet.

This corresponds to DMD commit 3f6a763c0589dd03c1c206eafd434b593702564e.
2016-04-03 15:15:14 +01:00

129 lines
3.4 KiB
D

// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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
module ddmd.staticassert;
import ddmd.dscope;
import ddmd.dsymbol;
import ddmd.errors;
import ddmd.expression;
import ddmd.globals;
import ddmd.globals;
import ddmd.hdrgen;
import ddmd.id;
import ddmd.identifier;
import ddmd.mtype;
import ddmd.root.outbuffer;
import ddmd.visitor;
/***********************************************************
*/
extern (C++) final class StaticAssert : Dsymbol
{
public:
Expression exp;
Expression msg;
extern (D) this(Loc loc, Expression exp, Expression msg)
{
super(Id.empty);
this.loc = loc;
this.exp = exp;
this.msg = msg;
}
override Dsymbol syntaxCopy(Dsymbol s)
{
assert(!s);
return new StaticAssert(loc, exp.syntaxCopy(), msg ? msg.syntaxCopy() : null);
}
override void addMember(Scope* sc, ScopeDsymbol sds)
{
// we didn't add anything
}
override void semantic(Scope* sc)
{
}
override void semantic2(Scope* sc)
{
//printf("StaticAssert::semantic2() %s\n", toChars());
auto sds = new ScopeDsymbol();
sc = sc.push(sds);
sc.tinst = null;
sc.minst = null;
sc.flags |= SCOPEcondition;
sc = sc.startCTFE();
Expression e = exp.semantic(sc);
e = resolveProperties(sc, e);
sc = sc.endCTFE();
sc = sc.pop();
// Simplify expression, to make error messages nicer if CTFE fails
e = e.optimize(WANTvalue);
if (!e.type.isBoolean())
{
if (e.type.toBasetype() != Type.terror)
exp.error("expression %s of type %s does not have a boolean value", exp.toChars(), e.type.toChars());
return;
}
uint olderrs = global.errors;
e = e.ctfeInterpret();
if (global.errors != olderrs)
{
errorSupplemental(loc, "while evaluating: static assert(%s)", exp.toChars());
}
else if (e.isBool(false))
{
if (msg)
{
sc = sc.startCTFE();
msg = msg.semantic(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\"", cast(int)se.len, se.string);
}
else
error("%s", msg.toChars());
}
else
error("(%s) is false", exp.toChars());
if (sc.tinst)
sc.tinst.printInstantiationTrace();
if (!global.gag)
fatal();
}
else if (!e.isBool(true))
{
error("(%s) is not evaluatable at compile time", exp.toChars());
}
}
override bool oneMember(Dsymbol* ps, Identifier ident)
{
//printf("StaticAssert::oneMember())\n");
*ps = null;
return true;
}
override const(char)* kind() const
{
return "static assert";
}
override void accept(Visitor v)
{
v.visit(this);
}
}