mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00

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.
129 lines
3.4 KiB
D
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);
|
|
}
|
|
}
|