mirror of
https://github.com/dlang/dmd.git
synced 2025-05-04 00:53:20 +03:00
Break dependency of expression.d on ctfeexp.d
This commit is contained in:
parent
14b5325a64
commit
38173e34b4
5 changed files with 646 additions and 653 deletions
|
@ -15,6 +15,7 @@ import core.stdc.string;
|
||||||
|
|
||||||
import dmd.astenums;
|
import dmd.astenums;
|
||||||
import dmd.arraytypes;
|
import dmd.arraytypes;
|
||||||
|
import dmd.ctfeexpr;
|
||||||
import dmd.dmodule;
|
import dmd.dmodule;
|
||||||
import dmd.errors;
|
import dmd.errors;
|
||||||
import dmd.expression;
|
import dmd.expression;
|
||||||
|
|
|
@ -35,75 +35,98 @@ import dmd.root.rmem;
|
||||||
import dmd.tokens;
|
import dmd.tokens;
|
||||||
import dmd.visitor;
|
import dmd.visitor;
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
/***********************************************************
|
/* A type meant as a union of all the Expression types,
|
||||||
* A reference to a class, or an interface. We need this when we
|
* to serve essentially as a Variant that will sit on the stack
|
||||||
* point to a base class (we must record what the type is).
|
* during CTFE to reduce memory consumption.
|
||||||
*/
|
*/
|
||||||
extern (C++) final class ClassReferenceExp : Expression
|
extern (D) struct UnionExp
|
||||||
{
|
{
|
||||||
StructLiteralExp value;
|
// yes, default constructor does nothing
|
||||||
|
extern (D) this(Expression e)
|
||||||
extern (D) this(const ref Loc loc, StructLiteralExp lit, Type type) @safe
|
|
||||||
{
|
{
|
||||||
super(loc, EXP.classReference);
|
memcpy(&this, cast(void*)e, e.size);
|
||||||
assert(lit && lit.sd && lit.sd.isClassDeclaration());
|
|
||||||
this.value = lit;
|
|
||||||
this.type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassDeclaration originalClass()
|
/* Extract pointer to Expression
|
||||||
|
*/
|
||||||
|
extern (D) Expression exp() return
|
||||||
{
|
{
|
||||||
return value.sd.isClassDeclaration();
|
return cast(Expression)&u;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return index of the field, or -1 if not found
|
/* Convert to an allocated Expression
|
||||||
private int getFieldIndex(Type fieldtype, uint fieldoffset)
|
*/
|
||||||
|
extern (D) Expression copy()
|
||||||
{
|
{
|
||||||
ClassDeclaration cd = originalClass();
|
Expression e = exp();
|
||||||
uint fieldsSoFar = 0;
|
//if (e.size > sizeof(u)) printf("%s\n", EXPtoString(e.op).ptr);
|
||||||
for (size_t j = 0; j < value.elements.length; j++)
|
assert(e.size <= u.sizeof);
|
||||||
|
switch (e.op)
|
||||||
{
|
{
|
||||||
while (j - fieldsSoFar >= cd.fields.length)
|
case EXP.cantExpression: return CTFEExp.cantexp;
|
||||||
{
|
case EXP.voidExpression: return CTFEExp.voidexp;
|
||||||
fieldsSoFar += cd.fields.length;
|
case EXP.break_: return CTFEExp.breakexp;
|
||||||
cd = cd.baseClass;
|
case EXP.continue_: return CTFEExp.continueexp;
|
||||||
|
case EXP.goto_: return CTFEExp.gotoexp;
|
||||||
|
default: return e.copy();
|
||||||
}
|
}
|
||||||
VarDeclaration v2 = cd.fields[j - fieldsSoFar];
|
|
||||||
if (fieldoffset == v2.offset && fieldtype.size() == v2.type.size())
|
|
||||||
{
|
|
||||||
return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return index of the field, or -1 if not found
|
private:
|
||||||
// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
|
// Ensure that the union is suitably aligned.
|
||||||
int findFieldIndexByName(VarDeclaration v)
|
align(8) union _AnonStruct_u
|
||||||
{
|
{
|
||||||
ClassDeclaration cd = originalClass();
|
char[__traits(classInstanceSize, Expression)] exp;
|
||||||
size_t fieldsSoFar = 0;
|
char[__traits(classInstanceSize, IntegerExp)] integerexp;
|
||||||
for (size_t j = 0; j < value.elements.length; j++)
|
char[__traits(classInstanceSize, ErrorExp)] errorexp;
|
||||||
{
|
char[__traits(classInstanceSize, RealExp)] realexp;
|
||||||
while (j - fieldsSoFar >= cd.fields.length)
|
char[__traits(classInstanceSize, ComplexExp)] complexexp;
|
||||||
{
|
char[__traits(classInstanceSize, SymOffExp)] symoffexp;
|
||||||
fieldsSoFar += cd.fields.length;
|
char[__traits(classInstanceSize, StringExp)] stringexp;
|
||||||
cd = cd.baseClass;
|
char[__traits(classInstanceSize, ArrayLiteralExp)] arrayliteralexp;
|
||||||
}
|
char[__traits(classInstanceSize, AssocArrayLiteralExp)] assocarrayliteralexp;
|
||||||
VarDeclaration v2 = cd.fields[j - fieldsSoFar];
|
char[__traits(classInstanceSize, StructLiteralExp)] structliteralexp;
|
||||||
if (v == v2)
|
char[__traits(classInstanceSize, CompoundLiteralExp)] compoundliteralexp;
|
||||||
{
|
char[__traits(classInstanceSize, NullExp)] nullexp;
|
||||||
return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
|
char[__traits(classInstanceSize, DotVarExp)] dotvarexp;
|
||||||
}
|
char[__traits(classInstanceSize, AddrExp)] addrexp;
|
||||||
}
|
char[__traits(classInstanceSize, IndexExp)] indexexp;
|
||||||
return -1;
|
char[__traits(classInstanceSize, SliceExp)] sliceexp;
|
||||||
|
char[__traits(classInstanceSize, VectorExp)] vectorexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
override void accept(Visitor v)
|
_AnonStruct_u u;
|
||||||
{
|
|
||||||
v.visit(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emplaceExp(T : Expression, Args...)(void* p, Args args)
|
||||||
|
{
|
||||||
|
static if (__VERSION__ < 2099)
|
||||||
|
const init = typeid(T).initializer;
|
||||||
|
else
|
||||||
|
const init = __traits(initSymbol, T);
|
||||||
|
p[0 .. __traits(classInstanceSize, T)] = init[];
|
||||||
|
(cast(T)p).__ctor(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void emplaceExp(T : UnionExp)(T* p, Expression e)
|
||||||
|
{
|
||||||
|
memcpy(p, cast(void*)e, e.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate an error message when this exception is not caught
|
||||||
|
void generateUncaughtError(ThrownExceptionExp tee)
|
||||||
|
{
|
||||||
|
UnionExp ue = void;
|
||||||
|
Expression e = resolveSlice((*tee.thrown.value.elements)[0], &ue);
|
||||||
|
StringExp se = e.toStringExp();
|
||||||
|
error(tee.thrown.loc, "uncaught CTFE exception `%s(%s)`", tee.thrown.type.toChars(), se ? se.toChars() : e.toChars());
|
||||||
|
/* Also give the line where the throw statement was. We won't have it
|
||||||
|
* in the case where the ThrowStatement is generated internally
|
||||||
|
* (eg, in ScopeStatement)
|
||||||
|
*/
|
||||||
|
if (tee.loc.isValid() && !tee.loc.equals(tee.thrown.loc))
|
||||||
|
.errorSupplemental(tee.loc, "thrown from here");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
|
@ -121,100 +144,6 @@ int findFieldIndexByName(const StructDeclaration sd, const VarDeclaration v) pur
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
* Fake class which holds the thrown exception.
|
|
||||||
* Used for implementing exception handling.
|
|
||||||
*/
|
|
||||||
extern (C++) final class ThrownExceptionExp : Expression
|
|
||||||
{
|
|
||||||
ClassReferenceExp thrown; // the thing being tossed
|
|
||||||
|
|
||||||
extern (D) this(const ref Loc loc, ClassReferenceExp victim) @safe
|
|
||||||
{
|
|
||||||
super(loc, EXP.thrownException);
|
|
||||||
this.thrown = victim;
|
|
||||||
this.type = victim.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
override const(char)* toChars() const
|
|
||||||
{
|
|
||||||
return "CTFE ThrownException";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate an error message when this exception is not caught
|
|
||||||
extern (D) void generateUncaughtError()
|
|
||||||
{
|
|
||||||
UnionExp ue = void;
|
|
||||||
Expression e = resolveSlice((*thrown.value.elements)[0], &ue);
|
|
||||||
StringExp se = e.toStringExp();
|
|
||||||
error(thrown.loc, "uncaught CTFE exception `%s(%s)`", thrown.type.toChars(), se ? se.toChars() : e.toChars());
|
|
||||||
/* Also give the line where the throw statement was. We won't have it
|
|
||||||
* in the case where the ThrowStatement is generated internally
|
|
||||||
* (eg, in ScopeStatement)
|
|
||||||
*/
|
|
||||||
if (loc.isValid() && !loc.equals(thrown.loc))
|
|
||||||
.errorSupplemental(loc, "thrown from here");
|
|
||||||
}
|
|
||||||
|
|
||||||
override void accept(Visitor v)
|
|
||||||
{
|
|
||||||
v.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
* This type is only used by the interpreter.
|
|
||||||
*/
|
|
||||||
extern (C++) final class CTFEExp : Expression
|
|
||||||
{
|
|
||||||
extern (D) this(EXP tok)
|
|
||||||
{
|
|
||||||
super(Loc.initial, tok);
|
|
||||||
type = Type.tvoid;
|
|
||||||
}
|
|
||||||
|
|
||||||
override const(char)* toChars() const
|
|
||||||
{
|
|
||||||
switch (op)
|
|
||||||
{
|
|
||||||
case EXP.cantExpression:
|
|
||||||
return "<cant>";
|
|
||||||
case EXP.voidExpression:
|
|
||||||
return "cast(void)0";
|
|
||||||
case EXP.showCtfeContext:
|
|
||||||
return "<error>";
|
|
||||||
case EXP.break_:
|
|
||||||
return "<break>";
|
|
||||||
case EXP.continue_:
|
|
||||||
return "<continue>";
|
|
||||||
case EXP.goto_:
|
|
||||||
return "<goto>";
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern (D) __gshared CTFEExp cantexp;
|
|
||||||
extern (D) __gshared CTFEExp voidexp;
|
|
||||||
extern (D) __gshared CTFEExp breakexp;
|
|
||||||
extern (D) __gshared CTFEExp continueexp;
|
|
||||||
extern (D) __gshared CTFEExp gotoexp;
|
|
||||||
/* Used when additional information is needed regarding
|
|
||||||
* a ctfe error.
|
|
||||||
*/
|
|
||||||
extern (D) __gshared CTFEExp showcontext;
|
|
||||||
|
|
||||||
extern (D) static bool isCantExp(const Expression e) @safe
|
|
||||||
{
|
|
||||||
return e && e.op == EXP.cantExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern (D) static bool isGotoExp(const Expression e) @safe
|
|
||||||
{
|
|
||||||
return e && e.op == EXP.goto_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// True if 'e' is CTFEExp::cantexp, or an exception
|
// True if 'e' is CTFEExp::cantexp, or an exception
|
||||||
bool exceptionOrCantInterpret(const Expression e) @safe
|
bool exceptionOrCantInterpret(const Expression e) @safe
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,14 +18,10 @@ import core.stdc.stdio;
|
||||||
import core.stdc.string;
|
import core.stdc.string;
|
||||||
|
|
||||||
import dmd.aggregate;
|
import dmd.aggregate;
|
||||||
import dmd.aliasthis;
|
|
||||||
import dmd.arrayop;
|
|
||||||
import dmd.arraytypes;
|
import dmd.arraytypes;
|
||||||
import dmd.astenums;
|
import dmd.astenums;
|
||||||
import dmd.ast_node;
|
import dmd.ast_node;
|
||||||
import dmd.gluelayer;
|
import dmd.gluelayer;
|
||||||
import dmd.ctfeexpr;
|
|
||||||
import dmd.ctorflow;
|
|
||||||
import dmd.dclass;
|
import dmd.dclass;
|
||||||
import dmd.declaration;
|
import dmd.declaration;
|
||||||
import dmd.dimport;
|
import dmd.dimport;
|
||||||
|
@ -43,39 +39,21 @@ import dmd.identifier;
|
||||||
import dmd.init;
|
import dmd.init;
|
||||||
import dmd.location;
|
import dmd.location;
|
||||||
import dmd.mtype;
|
import dmd.mtype;
|
||||||
import dmd.opover;
|
|
||||||
import dmd.optimize;
|
import dmd.optimize;
|
||||||
import dmd.root.complex;
|
import dmd.root.complex;
|
||||||
import dmd.root.ctfloat;
|
import dmd.root.ctfloat;
|
||||||
import dmd.root.filename;
|
|
||||||
import dmd.common.outbuffer;
|
import dmd.common.outbuffer;
|
||||||
import dmd.root.optional;
|
import dmd.root.optional;
|
||||||
import dmd.root.rmem;
|
import dmd.root.rmem;
|
||||||
import dmd.rootobject;
|
import dmd.rootobject;
|
||||||
import dmd.root.string;
|
import dmd.root.string;
|
||||||
import dmd.root.utf;
|
import dmd.root.utf;
|
||||||
import dmd.safe;
|
|
||||||
import dmd.target;
|
import dmd.target;
|
||||||
import dmd.tokens;
|
import dmd.tokens;
|
||||||
import dmd.visitor;
|
import dmd.visitor;
|
||||||
|
|
||||||
enum LOGSEMANTIC = false;
|
enum LOGSEMANTIC = false;
|
||||||
|
|
||||||
void emplaceExp(T : Expression, Args...)(void* p, Args args)
|
|
||||||
{
|
|
||||||
static if (__VERSION__ < 2099)
|
|
||||||
const init = typeid(T).initializer;
|
|
||||||
else
|
|
||||||
const init = __traits(initSymbol, T);
|
|
||||||
p[0 .. __traits(classInstanceSize, T)] = init[];
|
|
||||||
(cast(T)p).__ctor(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void emplaceExp(T : UnionExp)(T* p, Expression e)
|
|
||||||
{
|
|
||||||
memcpy(p, cast(void*)e, e.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return value for `checkModifiable`
|
/// Return value for `checkModifiable`
|
||||||
enum Modifiable
|
enum Modifiable
|
||||||
{
|
{
|
||||||
|
@ -274,70 +252,6 @@ TemplateDeclaration getFuncTemplateDecl(Dsymbol s) @safe
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************/
|
|
||||||
/* A type meant as a union of all the Expression types,
|
|
||||||
* to serve essentially as a Variant that will sit on the stack
|
|
||||||
* during CTFE to reduce memory consumption.
|
|
||||||
*/
|
|
||||||
extern (D) struct UnionExp
|
|
||||||
{
|
|
||||||
// yes, default constructor does nothing
|
|
||||||
extern (D) this(Expression e)
|
|
||||||
{
|
|
||||||
memcpy(&this, cast(void*)e, e.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract pointer to Expression
|
|
||||||
*/
|
|
||||||
extern (D) Expression exp() return
|
|
||||||
{
|
|
||||||
return cast(Expression)&u;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert to an allocated Expression
|
|
||||||
*/
|
|
||||||
extern (D) Expression copy()
|
|
||||||
{
|
|
||||||
Expression e = exp();
|
|
||||||
//if (e.size > sizeof(u)) printf("%s\n", EXPtoString(e.op).ptr);
|
|
||||||
assert(e.size <= u.sizeof);
|
|
||||||
switch (e.op)
|
|
||||||
{
|
|
||||||
case EXP.cantExpression: return CTFEExp.cantexp;
|
|
||||||
case EXP.voidExpression: return CTFEExp.voidexp;
|
|
||||||
case EXP.break_: return CTFEExp.breakexp;
|
|
||||||
case EXP.continue_: return CTFEExp.continueexp;
|
|
||||||
case EXP.goto_: return CTFEExp.gotoexp;
|
|
||||||
default: return e.copy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Ensure that the union is suitably aligned.
|
|
||||||
align(8) union _AnonStruct_u
|
|
||||||
{
|
|
||||||
char[__traits(classInstanceSize, Expression)] exp;
|
|
||||||
char[__traits(classInstanceSize, IntegerExp)] integerexp;
|
|
||||||
char[__traits(classInstanceSize, ErrorExp)] errorexp;
|
|
||||||
char[__traits(classInstanceSize, RealExp)] realexp;
|
|
||||||
char[__traits(classInstanceSize, ComplexExp)] complexexp;
|
|
||||||
char[__traits(classInstanceSize, SymOffExp)] symoffexp;
|
|
||||||
char[__traits(classInstanceSize, StringExp)] stringexp;
|
|
||||||
char[__traits(classInstanceSize, ArrayLiteralExp)] arrayliteralexp;
|
|
||||||
char[__traits(classInstanceSize, AssocArrayLiteralExp)] assocarrayliteralexp;
|
|
||||||
char[__traits(classInstanceSize, StructLiteralExp)] structliteralexp;
|
|
||||||
char[__traits(classInstanceSize, CompoundLiteralExp)] compoundliteralexp;
|
|
||||||
char[__traits(classInstanceSize, NullExp)] nullexp;
|
|
||||||
char[__traits(classInstanceSize, DotVarExp)] dotvarexp;
|
|
||||||
char[__traits(classInstanceSize, AddrExp)] addrexp;
|
|
||||||
char[__traits(classInstanceSize, IndexExp)] indexexp;
|
|
||||||
char[__traits(classInstanceSize, SliceExp)] sliceexp;
|
|
||||||
char[__traits(classInstanceSize, VectorExp)] vectorexp;
|
|
||||||
}
|
|
||||||
|
|
||||||
_AnonStruct_u u;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************ TypeDotIdExp ************************************/
|
/************************ TypeDotIdExp ************************************/
|
||||||
/* Things like:
|
/* Things like:
|
||||||
* int.size
|
* int.size
|
||||||
|
@ -1195,7 +1109,7 @@ extern (C++) final class IntegerExp : Expression
|
||||||
*/
|
*/
|
||||||
extern (C++) final class ErrorExp : Expression
|
extern (C++) final class ErrorExp : Expression
|
||||||
{
|
{
|
||||||
private extern (D) this()
|
extern (D) this()
|
||||||
{
|
{
|
||||||
super(Loc.initial, EXP.error);
|
super(Loc.initial, EXP.error);
|
||||||
type = Type.terror;
|
type = Type.terror;
|
||||||
|
@ -5262,6 +5176,155 @@ extern (C++) final class PrettyFuncInitExp : DefaultInitExp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* A reference to a class, or an interface. We need this when we
|
||||||
|
* point to a base class (we must record what the type is).
|
||||||
|
*/
|
||||||
|
extern (C++) final class ClassReferenceExp : Expression
|
||||||
|
{
|
||||||
|
StructLiteralExp value;
|
||||||
|
|
||||||
|
extern (D) this(const ref Loc loc, StructLiteralExp lit, Type type) @safe
|
||||||
|
{
|
||||||
|
super(loc, EXP.classReference);
|
||||||
|
assert(lit && lit.sd && lit.sd.isClassDeclaration());
|
||||||
|
this.value = lit;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassDeclaration originalClass()
|
||||||
|
{
|
||||||
|
return value.sd.isClassDeclaration();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return index of the field, or -1 if not found
|
||||||
|
int getFieldIndex(Type fieldtype, uint fieldoffset)
|
||||||
|
{
|
||||||
|
ClassDeclaration cd = originalClass();
|
||||||
|
uint fieldsSoFar = 0;
|
||||||
|
for (size_t j = 0; j < value.elements.length; j++)
|
||||||
|
{
|
||||||
|
while (j - fieldsSoFar >= cd.fields.length)
|
||||||
|
{
|
||||||
|
fieldsSoFar += cd.fields.length;
|
||||||
|
cd = cd.baseClass;
|
||||||
|
}
|
||||||
|
VarDeclaration v2 = cd.fields[j - fieldsSoFar];
|
||||||
|
if (fieldoffset == v2.offset && fieldtype.size() == v2.type.size())
|
||||||
|
{
|
||||||
|
return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return index of the field, or -1 if not found
|
||||||
|
// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
|
||||||
|
int findFieldIndexByName(VarDeclaration v)
|
||||||
|
{
|
||||||
|
ClassDeclaration cd = originalClass();
|
||||||
|
size_t fieldsSoFar = 0;
|
||||||
|
for (size_t j = 0; j < value.elements.length; j++)
|
||||||
|
{
|
||||||
|
while (j - fieldsSoFar >= cd.fields.length)
|
||||||
|
{
|
||||||
|
fieldsSoFar += cd.fields.length;
|
||||||
|
cd = cd.baseClass;
|
||||||
|
}
|
||||||
|
VarDeclaration v2 = cd.fields[j - fieldsSoFar];
|
||||||
|
if (v == v2)
|
||||||
|
{
|
||||||
|
return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void accept(Visitor v)
|
||||||
|
{
|
||||||
|
v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* This type is only used by the interpreter.
|
||||||
|
*/
|
||||||
|
extern (C++) final class CTFEExp : Expression
|
||||||
|
{
|
||||||
|
extern (D) this(EXP tok)
|
||||||
|
{
|
||||||
|
super(Loc.initial, tok);
|
||||||
|
type = Type.tvoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
override const(char)* toChars() const
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case EXP.cantExpression:
|
||||||
|
return "<cant>";
|
||||||
|
case EXP.voidExpression:
|
||||||
|
return "cast(void)0";
|
||||||
|
case EXP.showCtfeContext:
|
||||||
|
return "<error>";
|
||||||
|
case EXP.break_:
|
||||||
|
return "<break>";
|
||||||
|
case EXP.continue_:
|
||||||
|
return "<continue>";
|
||||||
|
case EXP.goto_:
|
||||||
|
return "<goto>";
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern (D) __gshared CTFEExp cantexp;
|
||||||
|
extern (D) __gshared CTFEExp voidexp;
|
||||||
|
extern (D) __gshared CTFEExp breakexp;
|
||||||
|
extern (D) __gshared CTFEExp continueexp;
|
||||||
|
extern (D) __gshared CTFEExp gotoexp;
|
||||||
|
/* Used when additional information is needed regarding
|
||||||
|
* a ctfe error.
|
||||||
|
*/
|
||||||
|
extern (D) __gshared CTFEExp showcontext;
|
||||||
|
|
||||||
|
extern (D) static bool isCantExp(const Expression e) @safe
|
||||||
|
{
|
||||||
|
return e && e.op == EXP.cantExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern (D) static bool isGotoExp(const Expression e) @safe
|
||||||
|
{
|
||||||
|
return e && e.op == EXP.goto_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Fake class which holds the thrown exception.
|
||||||
|
* Used for implementing exception handling.
|
||||||
|
*/
|
||||||
|
extern (C++) final class ThrownExceptionExp : Expression
|
||||||
|
{
|
||||||
|
ClassReferenceExp thrown; // the thing being tossed
|
||||||
|
|
||||||
|
extern (D) this(const ref Loc loc, ClassReferenceExp victim) @safe
|
||||||
|
{
|
||||||
|
super(loc, EXP.thrownException);
|
||||||
|
this.thrown = victim;
|
||||||
|
this.type = victim.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
override const(char)* toChars() const
|
||||||
|
{
|
||||||
|
return "CTFE ThrownException";
|
||||||
|
}
|
||||||
|
|
||||||
|
override void accept(Visitor v)
|
||||||
|
{
|
||||||
|
v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Objective-C class reference expression.
|
* Objective-C class reference expression.
|
||||||
*
|
*
|
||||||
|
|
|
@ -117,6 +117,56 @@ class StaticIfCondition;
|
||||||
class ForeachStatement;
|
class ForeachStatement;
|
||||||
class ForeachRangeStatement;
|
class ForeachRangeStatement;
|
||||||
struct OutBuffer;
|
struct OutBuffer;
|
||||||
|
class TypeInfoClassDeclaration;
|
||||||
|
class Initializer;
|
||||||
|
struct IntRange;
|
||||||
|
struct ModuleDeclaration;
|
||||||
|
template <typename Datum>
|
||||||
|
struct FileMapping;
|
||||||
|
struct Escape;
|
||||||
|
class ErrorSink;
|
||||||
|
class LabelStatement;
|
||||||
|
class SwitchStatement;
|
||||||
|
class Statement;
|
||||||
|
class TryFinallyStatement;
|
||||||
|
class ScopeGuardStatement;
|
||||||
|
struct DocComment;
|
||||||
|
class WithStatement;
|
||||||
|
struct AA;
|
||||||
|
class Tuple;
|
||||||
|
class Parameter;
|
||||||
|
class TemplateParameter;
|
||||||
|
struct TemplatePrevious;
|
||||||
|
struct TYPE;
|
||||||
|
class TypeBasic;
|
||||||
|
class TypeFunction;
|
||||||
|
class TypeError;
|
||||||
|
class TypeVector;
|
||||||
|
class TypeSArray;
|
||||||
|
class TypeDArray;
|
||||||
|
class TypeAArray;
|
||||||
|
class TypePointer;
|
||||||
|
class TypeReference;
|
||||||
|
class TypeDelegate;
|
||||||
|
class TypeIdentifier;
|
||||||
|
class TypeInstance;
|
||||||
|
class TypeTypeof;
|
||||||
|
class TypeReturn;
|
||||||
|
class TypeStruct;
|
||||||
|
class TypeEnum;
|
||||||
|
class TypeClass;
|
||||||
|
class TypeSlice;
|
||||||
|
class TypeNull;
|
||||||
|
class TypeMixin;
|
||||||
|
class TypeTraits;
|
||||||
|
class TypeNoreturn;
|
||||||
|
class TypeTag;
|
||||||
|
class TemplateTypeParameter;
|
||||||
|
class TemplateValueParameter;
|
||||||
|
class TemplateAliasParameter;
|
||||||
|
class TemplateThisParameter;
|
||||||
|
class TemplateTupleParameter;
|
||||||
|
class TypeQualified;
|
||||||
class StringExp;
|
class StringExp;
|
||||||
class IntegerExp;
|
class IntegerExp;
|
||||||
class ErrorExp;
|
class ErrorExp;
|
||||||
|
@ -231,56 +281,6 @@ class ThrownExceptionExp;
|
||||||
class UnaExp;
|
class UnaExp;
|
||||||
class BinExp;
|
class BinExp;
|
||||||
class BinAssignExp;
|
class BinAssignExp;
|
||||||
class TypeInfoClassDeclaration;
|
|
||||||
class Initializer;
|
|
||||||
struct IntRange;
|
|
||||||
struct ModuleDeclaration;
|
|
||||||
template <typename Datum>
|
|
||||||
struct FileMapping;
|
|
||||||
struct Escape;
|
|
||||||
class ErrorSink;
|
|
||||||
class LabelStatement;
|
|
||||||
class SwitchStatement;
|
|
||||||
class Statement;
|
|
||||||
class TryFinallyStatement;
|
|
||||||
class ScopeGuardStatement;
|
|
||||||
struct DocComment;
|
|
||||||
class WithStatement;
|
|
||||||
struct AA;
|
|
||||||
class Tuple;
|
|
||||||
class Parameter;
|
|
||||||
class TemplateParameter;
|
|
||||||
struct TemplatePrevious;
|
|
||||||
struct TYPE;
|
|
||||||
class TypeBasic;
|
|
||||||
class TypeFunction;
|
|
||||||
class TypeError;
|
|
||||||
class TypeVector;
|
|
||||||
class TypeSArray;
|
|
||||||
class TypeDArray;
|
|
||||||
class TypeAArray;
|
|
||||||
class TypePointer;
|
|
||||||
class TypeReference;
|
|
||||||
class TypeDelegate;
|
|
||||||
class TypeIdentifier;
|
|
||||||
class TypeInstance;
|
|
||||||
class TypeTypeof;
|
|
||||||
class TypeReturn;
|
|
||||||
class TypeStruct;
|
|
||||||
class TypeEnum;
|
|
||||||
class TypeClass;
|
|
||||||
class TypeSlice;
|
|
||||||
class TypeNull;
|
|
||||||
class TypeMixin;
|
|
||||||
class TypeTraits;
|
|
||||||
class TypeNoreturn;
|
|
||||||
class TypeTag;
|
|
||||||
class TemplateTypeParameter;
|
|
||||||
class TemplateValueParameter;
|
|
||||||
class TemplateAliasParameter;
|
|
||||||
class TemplateThisParameter;
|
|
||||||
class TemplateTupleParameter;
|
|
||||||
class TypeQualified;
|
|
||||||
class CaseStatement;
|
class CaseStatement;
|
||||||
class Catch;
|
class Catch;
|
||||||
struct Designator;
|
struct Designator;
|
||||||
|
@ -789,310 +789,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EXP : uint8_t
|
|
||||||
{
|
|
||||||
reserved = 0u,
|
|
||||||
negate = 1u,
|
|
||||||
cast_ = 2u,
|
|
||||||
null_ = 3u,
|
|
||||||
assert_ = 4u,
|
|
||||||
array = 5u,
|
|
||||||
call = 6u,
|
|
||||||
address = 7u,
|
|
||||||
type = 8u,
|
|
||||||
throw_ = 9u,
|
|
||||||
new_ = 10u,
|
|
||||||
delete_ = 11u,
|
|
||||||
star = 12u,
|
|
||||||
symbolOffset = 13u,
|
|
||||||
variable = 14u,
|
|
||||||
dotVariable = 15u,
|
|
||||||
dotIdentifier = 16u,
|
|
||||||
dotTemplateInstance = 17u,
|
|
||||||
dotType = 18u,
|
|
||||||
slice = 19u,
|
|
||||||
arrayLength = 20u,
|
|
||||||
dollar = 21u,
|
|
||||||
template_ = 22u,
|
|
||||||
dotTemplateDeclaration = 23u,
|
|
||||||
declaration = 24u,
|
|
||||||
dSymbol = 25u,
|
|
||||||
typeid_ = 26u,
|
|
||||||
uadd = 27u,
|
|
||||||
remove = 28u,
|
|
||||||
newAnonymousClass = 29u,
|
|
||||||
arrayLiteral = 30u,
|
|
||||||
assocArrayLiteral = 31u,
|
|
||||||
structLiteral = 32u,
|
|
||||||
classReference = 33u,
|
|
||||||
thrownException = 34u,
|
|
||||||
delegatePointer = 35u,
|
|
||||||
delegateFunctionPointer = 36u,
|
|
||||||
lessThan = 37u,
|
|
||||||
greaterThan = 38u,
|
|
||||||
lessOrEqual = 39u,
|
|
||||||
greaterOrEqual = 40u,
|
|
||||||
equal = 41u,
|
|
||||||
notEqual = 42u,
|
|
||||||
identity = 43u,
|
|
||||||
notIdentity = 44u,
|
|
||||||
index = 45u,
|
|
||||||
is_ = 46u,
|
|
||||||
leftShift = 47u,
|
|
||||||
rightShift = 48u,
|
|
||||||
leftShiftAssign = 49u,
|
|
||||||
rightShiftAssign = 50u,
|
|
||||||
unsignedRightShift = 51u,
|
|
||||||
unsignedRightShiftAssign = 52u,
|
|
||||||
concatenate = 53u,
|
|
||||||
concatenateAssign = 54u,
|
|
||||||
concatenateElemAssign = 55u,
|
|
||||||
concatenateDcharAssign = 56u,
|
|
||||||
add = 57u,
|
|
||||||
min = 58u,
|
|
||||||
addAssign = 59u,
|
|
||||||
minAssign = 60u,
|
|
||||||
mul = 61u,
|
|
||||||
div = 62u,
|
|
||||||
mod = 63u,
|
|
||||||
mulAssign = 64u,
|
|
||||||
divAssign = 65u,
|
|
||||||
modAssign = 66u,
|
|
||||||
and_ = 67u,
|
|
||||||
or_ = 68u,
|
|
||||||
xor_ = 69u,
|
|
||||||
andAssign = 70u,
|
|
||||||
orAssign = 71u,
|
|
||||||
xorAssign = 72u,
|
|
||||||
assign = 73u,
|
|
||||||
not_ = 74u,
|
|
||||||
tilde = 75u,
|
|
||||||
plusPlus = 76u,
|
|
||||||
minusMinus = 77u,
|
|
||||||
construct = 78u,
|
|
||||||
blit = 79u,
|
|
||||||
dot = 80u,
|
|
||||||
comma = 81u,
|
|
||||||
question = 82u,
|
|
||||||
andAnd = 83u,
|
|
||||||
orOr = 84u,
|
|
||||||
prePlusPlus = 85u,
|
|
||||||
preMinusMinus = 86u,
|
|
||||||
identifier = 87u,
|
|
||||||
string_ = 88u,
|
|
||||||
this_ = 89u,
|
|
||||||
super_ = 90u,
|
|
||||||
halt = 91u,
|
|
||||||
tuple = 92u,
|
|
||||||
error = 93u,
|
|
||||||
void_ = 94u,
|
|
||||||
int64 = 95u,
|
|
||||||
float64 = 96u,
|
|
||||||
complex80 = 97u,
|
|
||||||
import_ = 98u,
|
|
||||||
delegate_ = 99u,
|
|
||||||
function_ = 100u,
|
|
||||||
mixin_ = 101u,
|
|
||||||
in_ = 102u,
|
|
||||||
break_ = 103u,
|
|
||||||
continue_ = 104u,
|
|
||||||
goto_ = 105u,
|
|
||||||
scope_ = 106u,
|
|
||||||
traits = 107u,
|
|
||||||
overloadSet = 108u,
|
|
||||||
line = 109u,
|
|
||||||
file = 110u,
|
|
||||||
fileFullPath = 111u,
|
|
||||||
moduleString = 112u,
|
|
||||||
functionString = 113u,
|
|
||||||
prettyFunction = 114u,
|
|
||||||
pow = 115u,
|
|
||||||
powAssign = 116u,
|
|
||||||
vector = 117u,
|
|
||||||
voidExpression = 118u,
|
|
||||||
cantExpression = 119u,
|
|
||||||
showCtfeContext = 120u,
|
|
||||||
objcClassReference = 121u,
|
|
||||||
vectorArray = 122u,
|
|
||||||
compoundLiteral = 123u,
|
|
||||||
_Generic_ = 124u,
|
|
||||||
interval = 125u,
|
|
||||||
loweredAssignExp = 126u,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef uint64_t dinteger_t;
|
|
||||||
|
|
||||||
struct complex_t final
|
|
||||||
{
|
|
||||||
_d_real re;
|
|
||||||
_d_real im;
|
|
||||||
complex_t() = delete;
|
|
||||||
complex_t(_d_real re);
|
|
||||||
complex_t(_d_real re, _d_real im);
|
|
||||||
int32_t opEquals(complex_t y) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct Optional final
|
|
||||||
{
|
|
||||||
T value;
|
|
||||||
bool present;
|
|
||||||
Optional(T value);
|
|
||||||
static Optional<T > create(T val);
|
|
||||||
bool isPresent() const;
|
|
||||||
bool isEmpty() const;
|
|
||||||
T get();
|
|
||||||
bool hasValue(T exp) const;
|
|
||||||
Optional()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Expression : public ASTNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Type* type;
|
|
||||||
Loc loc;
|
|
||||||
const EXP op;
|
|
||||||
size_t size() const;
|
|
||||||
static void _init();
|
|
||||||
static void deinitialize();
|
|
||||||
virtual Expression* syntaxCopy();
|
|
||||||
DYNCAST dyncast() const final override;
|
|
||||||
const char* toChars() const override;
|
|
||||||
virtual dinteger_t toInteger();
|
|
||||||
virtual uinteger_t toUInteger();
|
|
||||||
virtual _d_real toReal();
|
|
||||||
virtual _d_real toImaginary();
|
|
||||||
virtual complex_t toComplex();
|
|
||||||
virtual StringExp* toStringExp();
|
|
||||||
virtual bool isLvalue();
|
|
||||||
virtual bool checkType();
|
|
||||||
virtual bool checkValue();
|
|
||||||
Expression* addressOf();
|
|
||||||
Expression* deref();
|
|
||||||
Expression* optimize(int32_t result, bool keepLvalue = false);
|
|
||||||
int32_t isConst();
|
|
||||||
virtual bool isIdentical(const Expression* const e) const;
|
|
||||||
virtual Optional<bool > toBool();
|
|
||||||
virtual bool hasCode();
|
|
||||||
IntegerExp* isIntegerExp();
|
|
||||||
ErrorExp* isErrorExp();
|
|
||||||
VoidInitExp* isVoidInitExp();
|
|
||||||
RealExp* isRealExp();
|
|
||||||
ComplexExp* isComplexExp();
|
|
||||||
IdentifierExp* isIdentifierExp();
|
|
||||||
DollarExp* isDollarExp();
|
|
||||||
DsymbolExp* isDsymbolExp();
|
|
||||||
ThisExp* isThisExp();
|
|
||||||
SuperExp* isSuperExp();
|
|
||||||
NullExp* isNullExp();
|
|
||||||
StringExp* isStringExp();
|
|
||||||
TupleExp* isTupleExp();
|
|
||||||
ArrayLiteralExp* isArrayLiteralExp();
|
|
||||||
AssocArrayLiteralExp* isAssocArrayLiteralExp();
|
|
||||||
StructLiteralExp* isStructLiteralExp();
|
|
||||||
CompoundLiteralExp* isCompoundLiteralExp();
|
|
||||||
TypeExp* isTypeExp();
|
|
||||||
ScopeExp* isScopeExp();
|
|
||||||
TemplateExp* isTemplateExp();
|
|
||||||
NewExp* isNewExp();
|
|
||||||
NewAnonClassExp* isNewAnonClassExp();
|
|
||||||
SymOffExp* isSymOffExp();
|
|
||||||
VarExp* isVarExp();
|
|
||||||
OverExp* isOverExp();
|
|
||||||
FuncExp* isFuncExp();
|
|
||||||
DeclarationExp* isDeclarationExp();
|
|
||||||
TypeidExp* isTypeidExp();
|
|
||||||
TraitsExp* isTraitsExp();
|
|
||||||
HaltExp* isHaltExp();
|
|
||||||
IsExp* isExp();
|
|
||||||
MixinExp* isMixinExp();
|
|
||||||
ImportExp* isImportExp();
|
|
||||||
AssertExp* isAssertExp();
|
|
||||||
ThrowExp* isThrowExp();
|
|
||||||
DotIdExp* isDotIdExp();
|
|
||||||
DotTemplateExp* isDotTemplateExp();
|
|
||||||
DotVarExp* isDotVarExp();
|
|
||||||
DotTemplateInstanceExp* isDotTemplateInstanceExp();
|
|
||||||
DelegateExp* isDelegateExp();
|
|
||||||
DotTypeExp* isDotTypeExp();
|
|
||||||
CallExp* isCallExp();
|
|
||||||
AddrExp* isAddrExp();
|
|
||||||
PtrExp* isPtrExp();
|
|
||||||
NegExp* isNegExp();
|
|
||||||
UAddExp* isUAddExp();
|
|
||||||
ComExp* isComExp();
|
|
||||||
NotExp* isNotExp();
|
|
||||||
DeleteExp* isDeleteExp();
|
|
||||||
CastExp* isCastExp();
|
|
||||||
VectorExp* isVectorExp();
|
|
||||||
VectorArrayExp* isVectorArrayExp();
|
|
||||||
SliceExp* isSliceExp();
|
|
||||||
ArrayLengthExp* isArrayLengthExp();
|
|
||||||
ArrayExp* isArrayExp();
|
|
||||||
DotExp* isDotExp();
|
|
||||||
CommaExp* isCommaExp();
|
|
||||||
IntervalExp* isIntervalExp();
|
|
||||||
DelegatePtrExp* isDelegatePtrExp();
|
|
||||||
DelegateFuncptrExp* isDelegateFuncptrExp();
|
|
||||||
IndexExp* isIndexExp();
|
|
||||||
PostExp* isPostExp();
|
|
||||||
PreExp* isPreExp();
|
|
||||||
AssignExp* isAssignExp();
|
|
||||||
LoweredAssignExp* isLoweredAssignExp();
|
|
||||||
ConstructExp* isConstructExp();
|
|
||||||
BlitExp* isBlitExp();
|
|
||||||
AddAssignExp* isAddAssignExp();
|
|
||||||
MinAssignExp* isMinAssignExp();
|
|
||||||
MulAssignExp* isMulAssignExp();
|
|
||||||
DivAssignExp* isDivAssignExp();
|
|
||||||
ModAssignExp* isModAssignExp();
|
|
||||||
AndAssignExp* isAndAssignExp();
|
|
||||||
OrAssignExp* isOrAssignExp();
|
|
||||||
XorAssignExp* isXorAssignExp();
|
|
||||||
PowAssignExp* isPowAssignExp();
|
|
||||||
ShlAssignExp* isShlAssignExp();
|
|
||||||
ShrAssignExp* isShrAssignExp();
|
|
||||||
UshrAssignExp* isUshrAssignExp();
|
|
||||||
CatAssignExp* isCatAssignExp();
|
|
||||||
CatElemAssignExp* isCatElemAssignExp();
|
|
||||||
CatDcharAssignExp* isCatDcharAssignExp();
|
|
||||||
AddExp* isAddExp();
|
|
||||||
MinExp* isMinExp();
|
|
||||||
CatExp* isCatExp();
|
|
||||||
MulExp* isMulExp();
|
|
||||||
DivExp* isDivExp();
|
|
||||||
ModExp* isModExp();
|
|
||||||
PowExp* isPowExp();
|
|
||||||
ShlExp* isShlExp();
|
|
||||||
ShrExp* isShrExp();
|
|
||||||
UshrExp* isUshrExp();
|
|
||||||
AndExp* isAndExp();
|
|
||||||
OrExp* isOrExp();
|
|
||||||
XorExp* isXorExp();
|
|
||||||
LogicalExp* isLogicalExp();
|
|
||||||
InExp* isInExp();
|
|
||||||
RemoveExp* isRemoveExp();
|
|
||||||
EqualExp* isEqualExp();
|
|
||||||
IdentityExp* isIdentityExp();
|
|
||||||
CondExp* isCondExp();
|
|
||||||
GenericExp* isGenericExp();
|
|
||||||
DefaultInitExp* isDefaultInitExp();
|
|
||||||
FileInitExp* isFileInitExp();
|
|
||||||
LineInitExp* isLineInitExp();
|
|
||||||
ModuleInitExp* isModuleInitExp();
|
|
||||||
FuncInitExp* isFuncInitExp();
|
|
||||||
PrettyFuncInitExp* isPrettyFuncInitExp();
|
|
||||||
ObjcClassReferenceExp* isObjcClassReferenceExp();
|
|
||||||
ClassReferenceExp* isClassReferenceExp();
|
|
||||||
ThrownExceptionExp* isThrownExceptionExp();
|
|
||||||
UnaExp* isUnaExp();
|
|
||||||
BinExp* isBinExp();
|
|
||||||
BinAssignExp* isBinAssignExp();
|
|
||||||
void accept(Visitor* v) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class MATCH
|
enum class MATCH
|
||||||
{
|
{
|
||||||
nomatch = 0,
|
nomatch = 0,
|
||||||
|
@ -1328,6 +1024,8 @@ enum class Covariant
|
||||||
fwdref = 3,
|
fwdref = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint64_t dinteger_t;
|
||||||
|
|
||||||
class Type : public ASTNode
|
class Type : public ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1553,6 +1251,163 @@ public:
|
||||||
TypeFunction* toTypeFunction();
|
TypeFunction* toTypeFunction();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EXP : uint8_t
|
||||||
|
{
|
||||||
|
reserved = 0u,
|
||||||
|
negate = 1u,
|
||||||
|
cast_ = 2u,
|
||||||
|
null_ = 3u,
|
||||||
|
assert_ = 4u,
|
||||||
|
array = 5u,
|
||||||
|
call = 6u,
|
||||||
|
address = 7u,
|
||||||
|
type = 8u,
|
||||||
|
throw_ = 9u,
|
||||||
|
new_ = 10u,
|
||||||
|
delete_ = 11u,
|
||||||
|
star = 12u,
|
||||||
|
symbolOffset = 13u,
|
||||||
|
variable = 14u,
|
||||||
|
dotVariable = 15u,
|
||||||
|
dotIdentifier = 16u,
|
||||||
|
dotTemplateInstance = 17u,
|
||||||
|
dotType = 18u,
|
||||||
|
slice = 19u,
|
||||||
|
arrayLength = 20u,
|
||||||
|
dollar = 21u,
|
||||||
|
template_ = 22u,
|
||||||
|
dotTemplateDeclaration = 23u,
|
||||||
|
declaration = 24u,
|
||||||
|
dSymbol = 25u,
|
||||||
|
typeid_ = 26u,
|
||||||
|
uadd = 27u,
|
||||||
|
remove = 28u,
|
||||||
|
newAnonymousClass = 29u,
|
||||||
|
arrayLiteral = 30u,
|
||||||
|
assocArrayLiteral = 31u,
|
||||||
|
structLiteral = 32u,
|
||||||
|
classReference = 33u,
|
||||||
|
thrownException = 34u,
|
||||||
|
delegatePointer = 35u,
|
||||||
|
delegateFunctionPointer = 36u,
|
||||||
|
lessThan = 37u,
|
||||||
|
greaterThan = 38u,
|
||||||
|
lessOrEqual = 39u,
|
||||||
|
greaterOrEqual = 40u,
|
||||||
|
equal = 41u,
|
||||||
|
notEqual = 42u,
|
||||||
|
identity = 43u,
|
||||||
|
notIdentity = 44u,
|
||||||
|
index = 45u,
|
||||||
|
is_ = 46u,
|
||||||
|
leftShift = 47u,
|
||||||
|
rightShift = 48u,
|
||||||
|
leftShiftAssign = 49u,
|
||||||
|
rightShiftAssign = 50u,
|
||||||
|
unsignedRightShift = 51u,
|
||||||
|
unsignedRightShiftAssign = 52u,
|
||||||
|
concatenate = 53u,
|
||||||
|
concatenateAssign = 54u,
|
||||||
|
concatenateElemAssign = 55u,
|
||||||
|
concatenateDcharAssign = 56u,
|
||||||
|
add = 57u,
|
||||||
|
min = 58u,
|
||||||
|
addAssign = 59u,
|
||||||
|
minAssign = 60u,
|
||||||
|
mul = 61u,
|
||||||
|
div = 62u,
|
||||||
|
mod = 63u,
|
||||||
|
mulAssign = 64u,
|
||||||
|
divAssign = 65u,
|
||||||
|
modAssign = 66u,
|
||||||
|
and_ = 67u,
|
||||||
|
or_ = 68u,
|
||||||
|
xor_ = 69u,
|
||||||
|
andAssign = 70u,
|
||||||
|
orAssign = 71u,
|
||||||
|
xorAssign = 72u,
|
||||||
|
assign = 73u,
|
||||||
|
not_ = 74u,
|
||||||
|
tilde = 75u,
|
||||||
|
plusPlus = 76u,
|
||||||
|
minusMinus = 77u,
|
||||||
|
construct = 78u,
|
||||||
|
blit = 79u,
|
||||||
|
dot = 80u,
|
||||||
|
comma = 81u,
|
||||||
|
question = 82u,
|
||||||
|
andAnd = 83u,
|
||||||
|
orOr = 84u,
|
||||||
|
prePlusPlus = 85u,
|
||||||
|
preMinusMinus = 86u,
|
||||||
|
identifier = 87u,
|
||||||
|
string_ = 88u,
|
||||||
|
this_ = 89u,
|
||||||
|
super_ = 90u,
|
||||||
|
halt = 91u,
|
||||||
|
tuple = 92u,
|
||||||
|
error = 93u,
|
||||||
|
void_ = 94u,
|
||||||
|
int64 = 95u,
|
||||||
|
float64 = 96u,
|
||||||
|
complex80 = 97u,
|
||||||
|
import_ = 98u,
|
||||||
|
delegate_ = 99u,
|
||||||
|
function_ = 100u,
|
||||||
|
mixin_ = 101u,
|
||||||
|
in_ = 102u,
|
||||||
|
break_ = 103u,
|
||||||
|
continue_ = 104u,
|
||||||
|
goto_ = 105u,
|
||||||
|
scope_ = 106u,
|
||||||
|
traits = 107u,
|
||||||
|
overloadSet = 108u,
|
||||||
|
line = 109u,
|
||||||
|
file = 110u,
|
||||||
|
fileFullPath = 111u,
|
||||||
|
moduleString = 112u,
|
||||||
|
functionString = 113u,
|
||||||
|
prettyFunction = 114u,
|
||||||
|
pow = 115u,
|
||||||
|
powAssign = 116u,
|
||||||
|
vector = 117u,
|
||||||
|
voidExpression = 118u,
|
||||||
|
cantExpression = 119u,
|
||||||
|
showCtfeContext = 120u,
|
||||||
|
objcClassReference = 121u,
|
||||||
|
vectorArray = 122u,
|
||||||
|
compoundLiteral = 123u,
|
||||||
|
_Generic_ = 124u,
|
||||||
|
interval = 125u,
|
||||||
|
loweredAssignExp = 126u,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct complex_t final
|
||||||
|
{
|
||||||
|
_d_real re;
|
||||||
|
_d_real im;
|
||||||
|
complex_t() = delete;
|
||||||
|
complex_t(_d_real re);
|
||||||
|
complex_t(_d_real re, _d_real im);
|
||||||
|
int32_t opEquals(complex_t y) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Optional final
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
bool present;
|
||||||
|
Optional(T value);
|
||||||
|
static Optional<T > create(T val);
|
||||||
|
bool isPresent() const;
|
||||||
|
bool isEmpty() const;
|
||||||
|
T get();
|
||||||
|
bool hasValue(T exp) const;
|
||||||
|
Optional()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
enum class OwnedBy : uint8_t
|
enum class OwnedBy : uint8_t
|
||||||
{
|
{
|
||||||
code = 0u,
|
code = 0u,
|
||||||
|
@ -2304,41 +2159,6 @@ enum class ModifyFlags
|
||||||
fieldAssign = 2,
|
fieldAssign = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnionExp final
|
|
||||||
{
|
|
||||||
#pragma pack(push, 8)
|
|
||||||
private:
|
|
||||||
union _AnonStruct_u
|
|
||||||
{
|
|
||||||
char exp[29LLU];
|
|
||||||
char integerexp[40LLU];
|
|
||||||
char errorexp[29LLU];
|
|
||||||
char realexp[48LLU];
|
|
||||||
char complexexp[64LLU];
|
|
||||||
char symoffexp[64LLU];
|
|
||||||
char stringexp[51LLU];
|
|
||||||
char arrayliteralexp[48LLU];
|
|
||||||
char assocarrayliteralexp[56LLU];
|
|
||||||
char structliteralexp[76LLU];
|
|
||||||
char compoundliteralexp[40LLU];
|
|
||||||
char nullexp[29LLU];
|
|
||||||
char dotvarexp[49LLU];
|
|
||||||
char addrexp[40LLU];
|
|
||||||
char indexexp[74LLU];
|
|
||||||
char sliceexp[65LLU];
|
|
||||||
char vectorexp[53LLU];
|
|
||||||
};
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
// Ignoring var u alignment 8
|
|
||||||
_AnonStruct_u u;
|
|
||||||
public:
|
|
||||||
UnionExp() :
|
|
||||||
u()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum : int32_t { WANTexpand = 1 };
|
enum : int32_t { WANTexpand = 1 };
|
||||||
|
|
||||||
enum : int32_t { WANTvalue = 0 };
|
enum : int32_t { WANTvalue = 0 };
|
||||||
|
@ -4745,6 +4565,41 @@ extern Type* merge(Type* type);
|
||||||
|
|
||||||
extern Type* typeSemantic(Type* type, const Loc& loc, Scope* sc);
|
extern Type* typeSemantic(Type* type, const Loc& loc, Scope* sc);
|
||||||
|
|
||||||
|
struct UnionExp final
|
||||||
|
{
|
||||||
|
#pragma pack(push, 8)
|
||||||
|
private:
|
||||||
|
union _AnonStruct_u
|
||||||
|
{
|
||||||
|
char exp[29LLU];
|
||||||
|
char integerexp[40LLU];
|
||||||
|
char errorexp[29LLU];
|
||||||
|
char realexp[48LLU];
|
||||||
|
char complexexp[64LLU];
|
||||||
|
char symoffexp[64LLU];
|
||||||
|
char stringexp[51LLU];
|
||||||
|
char arrayliteralexp[48LLU];
|
||||||
|
char assocarrayliteralexp[56LLU];
|
||||||
|
char structliteralexp[76LLU];
|
||||||
|
char compoundliteralexp[40LLU];
|
||||||
|
char nullexp[29LLU];
|
||||||
|
char dotvarexp[49LLU];
|
||||||
|
char addrexp[40LLU];
|
||||||
|
char indexexp[74LLU];
|
||||||
|
char sliceexp[65LLU];
|
||||||
|
char vectorexp[53LLU];
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
// Ignoring var u alignment 8
|
||||||
|
_AnonStruct_u u;
|
||||||
|
public:
|
||||||
|
UnionExp() :
|
||||||
|
u()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
enum class MODFlags
|
enum class MODFlags
|
||||||
{
|
{
|
||||||
none = 0,
|
none = 0,
|
||||||
|
@ -4961,12 +4816,14 @@ struct ASTCodegen final
|
||||||
using BinAssignExp = ::BinAssignExp;
|
using BinAssignExp = ::BinAssignExp;
|
||||||
using BinExp = ::BinExp;
|
using BinExp = ::BinExp;
|
||||||
using BlitExp = ::BlitExp;
|
using BlitExp = ::BlitExp;
|
||||||
|
using CTFEExp = ::CTFEExp;
|
||||||
using CallExp = ::CallExp;
|
using CallExp = ::CallExp;
|
||||||
using CastExp = ::CastExp;
|
using CastExp = ::CastExp;
|
||||||
using CatAssignExp = ::CatAssignExp;
|
using CatAssignExp = ::CatAssignExp;
|
||||||
using CatDcharAssignExp = ::CatDcharAssignExp;
|
using CatDcharAssignExp = ::CatDcharAssignExp;
|
||||||
using CatElemAssignExp = ::CatElemAssignExp;
|
using CatElemAssignExp = ::CatElemAssignExp;
|
||||||
using CatExp = ::CatExp;
|
using CatExp = ::CatExp;
|
||||||
|
using ClassReferenceExp = ::ClassReferenceExp;
|
||||||
using CmpExp = ::CmpExp;
|
using CmpExp = ::CmpExp;
|
||||||
using ComExp = ::ComExp;
|
using ComExp = ::ComExp;
|
||||||
using CommaExp = ::CommaExp;
|
using CommaExp = ::CommaExp;
|
||||||
|
@ -5052,13 +4909,13 @@ struct ASTCodegen final
|
||||||
using TemplateExp = ::TemplateExp;
|
using TemplateExp = ::TemplateExp;
|
||||||
using ThisExp = ::ThisExp;
|
using ThisExp = ::ThisExp;
|
||||||
using ThrowExp = ::ThrowExp;
|
using ThrowExp = ::ThrowExp;
|
||||||
|
using ThrownExceptionExp = ::ThrownExceptionExp;
|
||||||
using TraitsExp = ::TraitsExp;
|
using TraitsExp = ::TraitsExp;
|
||||||
using TupleExp = ::TupleExp;
|
using TupleExp = ::TupleExp;
|
||||||
using TypeExp = ::TypeExp;
|
using TypeExp = ::TypeExp;
|
||||||
using TypeidExp = ::TypeidExp;
|
using TypeidExp = ::TypeidExp;
|
||||||
using UAddExp = ::UAddExp;
|
using UAddExp = ::UAddExp;
|
||||||
using UnaExp = ::UnaExp;
|
using UnaExp = ::UnaExp;
|
||||||
using UnionExp = ::UnionExp;
|
|
||||||
using UshrAssignExp = ::UshrAssignExp;
|
using UshrAssignExp = ::UshrAssignExp;
|
||||||
using UshrExp = ::UshrExp;
|
using UshrExp = ::UshrExp;
|
||||||
using VarExp = ::VarExp;
|
using VarExp = ::VarExp;
|
||||||
|
@ -5067,7 +4924,6 @@ struct ASTCodegen final
|
||||||
using VoidInitExp = ::VoidInitExp;
|
using VoidInitExp = ::VoidInitExp;
|
||||||
using XorAssignExp = ::XorAssignExp;
|
using XorAssignExp = ::XorAssignExp;
|
||||||
using XorExp = ::XorExp;
|
using XorExp = ::XorExp;
|
||||||
using emplaceExp = ::emplaceExp;
|
|
||||||
using AttributeViolation = ::AttributeViolation;
|
using AttributeViolation = ::AttributeViolation;
|
||||||
using BUILTIN = ::BUILTIN;
|
using BUILTIN = ::BUILTIN;
|
||||||
using CtorDeclaration = ::CtorDeclaration;
|
using CtorDeclaration = ::CtorDeclaration;
|
||||||
|
@ -5185,9 +5041,8 @@ struct ASTCodegen final
|
||||||
using WhileStatement = ::WhileStatement;
|
using WhileStatement = ::WhileStatement;
|
||||||
using WithStatement = ::WithStatement;
|
using WithStatement = ::WithStatement;
|
||||||
using StaticAssert = ::StaticAssert;
|
using StaticAssert = ::StaticAssert;
|
||||||
using CTFEExp = ::CTFEExp;
|
using UnionExp = ::UnionExp;
|
||||||
using ClassReferenceExp = ::ClassReferenceExp;
|
using emplaceExp = ::emplaceExp;
|
||||||
using ThrownExceptionExp = ::ThrownExceptionExp;
|
|
||||||
typedef UserAttributeDeclaration* UserAttributeDeclaration;
|
typedef UserAttributeDeclaration* UserAttributeDeclaration;
|
||||||
typedef Ensure Ensure;
|
typedef Ensure Ensure;
|
||||||
typedef ErrorExp* ErrorExp;
|
typedef ErrorExp* ErrorExp;
|
||||||
|
@ -5833,29 +5688,6 @@ extern const char* cppTypeInfoMangleDMC(Dsymbol* s);
|
||||||
|
|
||||||
extern FileName preprocess(FileName csrcfile, const Loc& loc, bool& ifile, OutBuffer* defines);
|
extern FileName preprocess(FileName csrcfile, const Loc& loc, bool& ifile, OutBuffer* defines);
|
||||||
|
|
||||||
class ClassReferenceExp final : public Expression
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
StructLiteralExp* value;
|
|
||||||
ClassDeclaration* originalClass();
|
|
||||||
int32_t findFieldIndexByName(VarDeclaration* v);
|
|
||||||
void accept(Visitor* v) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ThrownExceptionExp final : public Expression
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ClassReferenceExp* thrown;
|
|
||||||
const char* toChars() const override;
|
|
||||||
void accept(Visitor* v) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CTFEExp final : public Expression
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const char* toChars() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern MATCH implicitConvTo(Expression* e, Type* t);
|
extern MATCH implicitConvTo(Expression* e, Type* t);
|
||||||
|
|
||||||
struct BaseClass final
|
struct BaseClass final
|
||||||
|
@ -7017,6 +6849,151 @@ public:
|
||||||
|
|
||||||
extern void expandTuples(Array<Expression* >* exps, Array<Identifier* >* names = nullptr);
|
extern void expandTuples(Array<Expression* >* exps, Array<Identifier* >* names = nullptr);
|
||||||
|
|
||||||
|
class Expression : public ASTNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Type* type;
|
||||||
|
Loc loc;
|
||||||
|
const EXP op;
|
||||||
|
size_t size() const;
|
||||||
|
static void _init();
|
||||||
|
static void deinitialize();
|
||||||
|
virtual Expression* syntaxCopy();
|
||||||
|
DYNCAST dyncast() const final override;
|
||||||
|
const char* toChars() const override;
|
||||||
|
virtual dinteger_t toInteger();
|
||||||
|
virtual uinteger_t toUInteger();
|
||||||
|
virtual _d_real toReal();
|
||||||
|
virtual _d_real toImaginary();
|
||||||
|
virtual complex_t toComplex();
|
||||||
|
virtual StringExp* toStringExp();
|
||||||
|
virtual bool isLvalue();
|
||||||
|
virtual bool checkType();
|
||||||
|
virtual bool checkValue();
|
||||||
|
Expression* addressOf();
|
||||||
|
Expression* deref();
|
||||||
|
Expression* optimize(int32_t result, bool keepLvalue = false);
|
||||||
|
int32_t isConst();
|
||||||
|
virtual bool isIdentical(const Expression* const e) const;
|
||||||
|
virtual Optional<bool > toBool();
|
||||||
|
virtual bool hasCode();
|
||||||
|
IntegerExp* isIntegerExp();
|
||||||
|
ErrorExp* isErrorExp();
|
||||||
|
VoidInitExp* isVoidInitExp();
|
||||||
|
RealExp* isRealExp();
|
||||||
|
ComplexExp* isComplexExp();
|
||||||
|
IdentifierExp* isIdentifierExp();
|
||||||
|
DollarExp* isDollarExp();
|
||||||
|
DsymbolExp* isDsymbolExp();
|
||||||
|
ThisExp* isThisExp();
|
||||||
|
SuperExp* isSuperExp();
|
||||||
|
NullExp* isNullExp();
|
||||||
|
StringExp* isStringExp();
|
||||||
|
TupleExp* isTupleExp();
|
||||||
|
ArrayLiteralExp* isArrayLiteralExp();
|
||||||
|
AssocArrayLiteralExp* isAssocArrayLiteralExp();
|
||||||
|
StructLiteralExp* isStructLiteralExp();
|
||||||
|
CompoundLiteralExp* isCompoundLiteralExp();
|
||||||
|
TypeExp* isTypeExp();
|
||||||
|
ScopeExp* isScopeExp();
|
||||||
|
TemplateExp* isTemplateExp();
|
||||||
|
NewExp* isNewExp();
|
||||||
|
NewAnonClassExp* isNewAnonClassExp();
|
||||||
|
SymOffExp* isSymOffExp();
|
||||||
|
VarExp* isVarExp();
|
||||||
|
OverExp* isOverExp();
|
||||||
|
FuncExp* isFuncExp();
|
||||||
|
DeclarationExp* isDeclarationExp();
|
||||||
|
TypeidExp* isTypeidExp();
|
||||||
|
TraitsExp* isTraitsExp();
|
||||||
|
HaltExp* isHaltExp();
|
||||||
|
IsExp* isExp();
|
||||||
|
MixinExp* isMixinExp();
|
||||||
|
ImportExp* isImportExp();
|
||||||
|
AssertExp* isAssertExp();
|
||||||
|
ThrowExp* isThrowExp();
|
||||||
|
DotIdExp* isDotIdExp();
|
||||||
|
DotTemplateExp* isDotTemplateExp();
|
||||||
|
DotVarExp* isDotVarExp();
|
||||||
|
DotTemplateInstanceExp* isDotTemplateInstanceExp();
|
||||||
|
DelegateExp* isDelegateExp();
|
||||||
|
DotTypeExp* isDotTypeExp();
|
||||||
|
CallExp* isCallExp();
|
||||||
|
AddrExp* isAddrExp();
|
||||||
|
PtrExp* isPtrExp();
|
||||||
|
NegExp* isNegExp();
|
||||||
|
UAddExp* isUAddExp();
|
||||||
|
ComExp* isComExp();
|
||||||
|
NotExp* isNotExp();
|
||||||
|
DeleteExp* isDeleteExp();
|
||||||
|
CastExp* isCastExp();
|
||||||
|
VectorExp* isVectorExp();
|
||||||
|
VectorArrayExp* isVectorArrayExp();
|
||||||
|
SliceExp* isSliceExp();
|
||||||
|
ArrayLengthExp* isArrayLengthExp();
|
||||||
|
ArrayExp* isArrayExp();
|
||||||
|
DotExp* isDotExp();
|
||||||
|
CommaExp* isCommaExp();
|
||||||
|
IntervalExp* isIntervalExp();
|
||||||
|
DelegatePtrExp* isDelegatePtrExp();
|
||||||
|
DelegateFuncptrExp* isDelegateFuncptrExp();
|
||||||
|
IndexExp* isIndexExp();
|
||||||
|
PostExp* isPostExp();
|
||||||
|
PreExp* isPreExp();
|
||||||
|
AssignExp* isAssignExp();
|
||||||
|
LoweredAssignExp* isLoweredAssignExp();
|
||||||
|
ConstructExp* isConstructExp();
|
||||||
|
BlitExp* isBlitExp();
|
||||||
|
AddAssignExp* isAddAssignExp();
|
||||||
|
MinAssignExp* isMinAssignExp();
|
||||||
|
MulAssignExp* isMulAssignExp();
|
||||||
|
DivAssignExp* isDivAssignExp();
|
||||||
|
ModAssignExp* isModAssignExp();
|
||||||
|
AndAssignExp* isAndAssignExp();
|
||||||
|
OrAssignExp* isOrAssignExp();
|
||||||
|
XorAssignExp* isXorAssignExp();
|
||||||
|
PowAssignExp* isPowAssignExp();
|
||||||
|
ShlAssignExp* isShlAssignExp();
|
||||||
|
ShrAssignExp* isShrAssignExp();
|
||||||
|
UshrAssignExp* isUshrAssignExp();
|
||||||
|
CatAssignExp* isCatAssignExp();
|
||||||
|
CatElemAssignExp* isCatElemAssignExp();
|
||||||
|
CatDcharAssignExp* isCatDcharAssignExp();
|
||||||
|
AddExp* isAddExp();
|
||||||
|
MinExp* isMinExp();
|
||||||
|
CatExp* isCatExp();
|
||||||
|
MulExp* isMulExp();
|
||||||
|
DivExp* isDivExp();
|
||||||
|
ModExp* isModExp();
|
||||||
|
PowExp* isPowExp();
|
||||||
|
ShlExp* isShlExp();
|
||||||
|
ShrExp* isShrExp();
|
||||||
|
UshrExp* isUshrExp();
|
||||||
|
AndExp* isAndExp();
|
||||||
|
OrExp* isOrExp();
|
||||||
|
XorExp* isXorExp();
|
||||||
|
LogicalExp* isLogicalExp();
|
||||||
|
InExp* isInExp();
|
||||||
|
RemoveExp* isRemoveExp();
|
||||||
|
EqualExp* isEqualExp();
|
||||||
|
IdentityExp* isIdentityExp();
|
||||||
|
CondExp* isCondExp();
|
||||||
|
GenericExp* isGenericExp();
|
||||||
|
DefaultInitExp* isDefaultInitExp();
|
||||||
|
FileInitExp* isFileInitExp();
|
||||||
|
LineInitExp* isLineInitExp();
|
||||||
|
ModuleInitExp* isModuleInitExp();
|
||||||
|
FuncInitExp* isFuncInitExp();
|
||||||
|
PrettyFuncInitExp* isPrettyFuncInitExp();
|
||||||
|
ObjcClassReferenceExp* isObjcClassReferenceExp();
|
||||||
|
ClassReferenceExp* isClassReferenceExp();
|
||||||
|
ThrownExceptionExp* isThrownExceptionExp();
|
||||||
|
UnaExp* isUnaExp();
|
||||||
|
BinExp* isBinExp();
|
||||||
|
BinAssignExp* isBinAssignExp();
|
||||||
|
void accept(Visitor* v) override;
|
||||||
|
};
|
||||||
|
|
||||||
class IntegerExp final : public Expression
|
class IntegerExp final : public Expression
|
||||||
{
|
{
|
||||||
dinteger_t value;
|
dinteger_t value;
|
||||||
|
@ -7968,6 +7945,30 @@ public:
|
||||||
void accept(Visitor* v) override;
|
void accept(Visitor* v) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ClassReferenceExp final : public Expression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StructLiteralExp* value;
|
||||||
|
ClassDeclaration* originalClass();
|
||||||
|
int32_t getFieldIndex(Type* fieldtype, uint32_t fieldoffset);
|
||||||
|
int32_t findFieldIndexByName(VarDeclaration* v);
|
||||||
|
void accept(Visitor* v) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CTFEExp final : public Expression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char* toChars() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThrownExceptionExp final : public Expression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClassReferenceExp* thrown;
|
||||||
|
const char* toChars() const override;
|
||||||
|
void accept(Visitor* v) override;
|
||||||
|
};
|
||||||
|
|
||||||
class ObjcClassReferenceExp final : public Expression
|
class ObjcClassReferenceExp final : public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -123,8 +123,7 @@ unittest
|
||||||
@("Expression.deinitialize")
|
@("Expression.deinitialize")
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import dmd.ctfeexpr : CTFEExp;
|
import dmd.expression : Expression, CTFEExp;
|
||||||
import dmd.expression : Expression;
|
|
||||||
|
|
||||||
static void assertInitialState()
|
static void assertInitialState()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue