mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-09 04:15:58 +03:00
1619 lines
44 KiB
C++
1619 lines
44 KiB
C++
|
|
// Compiler implementation of the D programming language
|
|
// Copyright (c) 1999-2008 by Digital Mars
|
|
// All Rights Reserved
|
|
// written by Walter Bright
|
|
// http://www.digitalmars.com
|
|
// License for redistribution is by either the Artistic License
|
|
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
|
// See the included readme.txt for details.
|
|
|
|
#ifndef DMD_EXPRESSION_H
|
|
#define DMD_EXPRESSION_H
|
|
|
|
#include "mars.h"
|
|
#include "identifier.h"
|
|
#include "lexer.h"
|
|
#include "arraytypes.h"
|
|
|
|
struct Type;
|
|
struct Scope;
|
|
struct TupleDeclaration;
|
|
struct VarDeclaration;
|
|
struct FuncDeclaration;
|
|
struct FuncLiteralDeclaration;
|
|
struct Declaration;
|
|
struct CtorDeclaration;
|
|
struct NewDeclaration;
|
|
struct Dsymbol;
|
|
struct Import;
|
|
struct Module;
|
|
struct ScopeDsymbol;
|
|
struct InlineCostState;
|
|
struct InlineDoState;
|
|
struct InlineScanState;
|
|
struct Expression;
|
|
struct Declaration;
|
|
struct AggregateDeclaration;
|
|
struct StructDeclaration;
|
|
struct TemplateInstance;
|
|
struct TemplateDeclaration;
|
|
struct ClassDeclaration;
|
|
struct HdrGenState;
|
|
struct BinExp;
|
|
struct InterState;
|
|
struct Symbol; // back end symbol
|
|
struct OverloadSet;
|
|
namespace llvm
|
|
{
|
|
class Constant;
|
|
class ConstantInt;
|
|
}
|
|
|
|
enum TOK;
|
|
|
|
// Back end
|
|
struct IRState;
|
|
struct dt_t;
|
|
|
|
#if IN_LLVM
|
|
struct DValue;
|
|
typedef DValue elem;
|
|
#else
|
|
#ifdef IN_GCC
|
|
union tree_node; typedef union tree_node elem;
|
|
#else
|
|
struct elem;
|
|
#endif
|
|
#endif
|
|
|
|
void initPrecedence();
|
|
|
|
Expression *resolveProperties(Scope *sc, Expression *e);
|
|
void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d);
|
|
Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Identifier *id);
|
|
Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid);
|
|
void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr);
|
|
void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs);
|
|
void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs);
|
|
void expandTuples(Expressions *exps);
|
|
FuncDeclaration *hasThis(Scope *sc);
|
|
Expression *fromConstInitializer(int result, Expression *e);
|
|
int arrayExpressionCanThrow(Expressions *exps);
|
|
|
|
struct Expression : Object
|
|
{
|
|
Loc loc; // file location
|
|
enum TOK op; // handy to minimize use of dynamic_cast
|
|
Type *type; // !=NULL means that semantic() has been run
|
|
int size; // # of bytes in Expression so we can copy() it
|
|
|
|
Expression(Loc loc, enum TOK op, int size);
|
|
Expression *copy();
|
|
virtual Expression *syntaxCopy();
|
|
virtual Expression *semantic(Scope *sc);
|
|
|
|
int dyncast() { return DYNCAST_EXPRESSION; } // kludge for template.isExpression()
|
|
|
|
void print();
|
|
char *toChars();
|
|
virtual void dump(int indent);
|
|
void error(const char *format, ...);
|
|
virtual void rvalue();
|
|
|
|
static Expression *combine(Expression *e1, Expression *e2);
|
|
static Expressions *arraySyntaxCopy(Expressions *exps);
|
|
|
|
virtual integer_t toInteger();
|
|
virtual uinteger_t toUInteger();
|
|
virtual real_t toReal();
|
|
virtual real_t toImaginary();
|
|
virtual complex_t toComplex();
|
|
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
virtual void toMangleBuffer(OutBuffer *buf);
|
|
virtual int isLvalue();
|
|
virtual Expression *toLvalue(Scope *sc, Expression *e);
|
|
virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
|
|
Expression *implicitCastTo(Scope *sc, Type *t);
|
|
virtual MATCH implicitConvTo(Type *t);
|
|
virtual Expression *castTo(Scope *sc, Type *t);
|
|
virtual void checkEscape();
|
|
void checkScalar();
|
|
void checkNoBool();
|
|
Expression *checkIntegral();
|
|
Expression *checkArithmetic();
|
|
void checkDeprecated(Scope *sc, Dsymbol *s);
|
|
virtual Expression *checkToBoolean();
|
|
Expression *checkToPointer();
|
|
Expression *addressOf(Scope *sc);
|
|
Expression *deref();
|
|
Expression *integralPromotions(Scope *sc);
|
|
|
|
Expression *toDelegate(Scope *sc, Type *t);
|
|
virtual void scanForNestedRef(Scope *sc);
|
|
|
|
virtual Expression *optimize(int result);
|
|
#define WANTflags 1
|
|
#define WANTvalue 2
|
|
#define WANTinterpret 4
|
|
|
|
virtual Expression *interpret(InterState *istate);
|
|
|
|
virtual int isConst();
|
|
virtual int isBool(int result);
|
|
virtual int isBit();
|
|
virtual int checkSideEffect(int flag);
|
|
virtual int canThrow();
|
|
|
|
virtual int inlineCost(InlineCostState *ics);
|
|
virtual Expression *doInline(InlineDoState *ids);
|
|
virtual Expression *inlineScan(InlineScanState *iss);
|
|
|
|
// For operator overloading
|
|
virtual int isCommutative();
|
|
virtual Identifier *opId();
|
|
virtual Identifier *opId_r();
|
|
|
|
// For array ops
|
|
virtual void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
virtual Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// Back end
|
|
virtual elem *toElem(IRState *irs);
|
|
virtual dt_t **toDt(dt_t **pdt);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct IntegerExp : Expression
|
|
{
|
|
integer_t value;
|
|
|
|
IntegerExp(Loc loc, integer_t value, Type *type);
|
|
IntegerExp(integer_t value);
|
|
int equals(Object *o);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
char *toChars();
|
|
void dump(int indent);
|
|
integer_t toInteger();
|
|
real_t toReal();
|
|
real_t toImaginary();
|
|
complex_t toComplex();
|
|
int isConst();
|
|
int isBool(int result);
|
|
MATCH implicitConvTo(Type *t);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void toMangleBuffer(OutBuffer *buf);
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
elem *toElem(IRState *irs);
|
|
dt_t **toDt(dt_t **pdt);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct RealExp : Expression
|
|
{
|
|
real_t value;
|
|
|
|
RealExp(Loc loc, real_t value, Type *type);
|
|
int equals(Object *o);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
char *toChars();
|
|
integer_t toInteger();
|
|
uinteger_t toUInteger();
|
|
real_t toReal();
|
|
real_t toImaginary();
|
|
complex_t toComplex();
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
int isConst();
|
|
int isBool(int result);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void toMangleBuffer(OutBuffer *buf);
|
|
elem *toElem(IRState *irs);
|
|
dt_t **toDt(dt_t **pdt);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct ComplexExp : Expression
|
|
{
|
|
complex_t value;
|
|
|
|
ComplexExp(Loc loc, complex_t value, Type *type);
|
|
int equals(Object *o);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
char *toChars();
|
|
integer_t toInteger();
|
|
uinteger_t toUInteger();
|
|
real_t toReal();
|
|
real_t toImaginary();
|
|
complex_t toComplex();
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
int isConst();
|
|
int isBool(int result);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void toMangleBuffer(OutBuffer *buf);
|
|
#ifdef _DH
|
|
OutBuffer hexp;
|
|
#endif
|
|
elem *toElem(IRState *irs);
|
|
dt_t **toDt(dt_t **pdt);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct IdentifierExp : Expression
|
|
{
|
|
Identifier *ident;
|
|
Declaration *var;
|
|
|
|
IdentifierExp(Loc loc, Identifier *ident);
|
|
IdentifierExp(Loc loc, Declaration *var);
|
|
Expression *semantic(Scope *sc);
|
|
char *toChars();
|
|
void dump(int indent);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
};
|
|
|
|
struct DollarExp : IdentifierExp
|
|
{
|
|
DollarExp(Loc loc);
|
|
};
|
|
|
|
struct DsymbolExp : Expression
|
|
{
|
|
Dsymbol *s;
|
|
int hasOverloads;
|
|
|
|
DsymbolExp(Loc loc, Dsymbol *s, int hasOverloads = 0);
|
|
Expression *semantic(Scope *sc);
|
|
char *toChars();
|
|
void dump(int indent);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
};
|
|
|
|
struct ThisExp : Expression
|
|
{
|
|
Declaration *var;
|
|
|
|
ThisExp(Loc loc);
|
|
Expression *semantic(Scope *sc);
|
|
int isBool(int result);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
void scanForNestedRef(Scope *sc);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
//Expression *inlineScan(InlineScanState *iss);
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct SuperExp : ThisExp
|
|
{
|
|
SuperExp(Loc loc);
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void scanForNestedRef(Scope *sc);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
//Expression *inlineScan(InlineScanState *iss);
|
|
};
|
|
|
|
struct NullExp : Expression
|
|
{
|
|
unsigned char committed; // !=0 if type is committed
|
|
|
|
NullExp(Loc loc);
|
|
Expression *semantic(Scope *sc);
|
|
int isBool(int result);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void toMangleBuffer(OutBuffer *buf);
|
|
MATCH implicitConvTo(Type *t);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
Expression *interpret(InterState *istate);
|
|
elem *toElem(IRState *irs);
|
|
dt_t **toDt(dt_t **pdt);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct StringExp : Expression
|
|
{
|
|
void *string; // char, wchar, or dchar data
|
|
size_t len; // number of chars, wchars, or dchars
|
|
unsigned char sz; // 1: char, 2: wchar, 4: dchar
|
|
unsigned char committed; // !=0 if type is committed
|
|
unsigned char postfix; // 'c', 'w', 'd'
|
|
|
|
StringExp(Loc loc, char *s);
|
|
StringExp(Loc loc, void *s, size_t len);
|
|
StringExp(Loc loc, void *s, size_t len, unsigned char postfix);
|
|
//Expression *syntaxCopy();
|
|
int equals(Object *o);
|
|
char *toChars();
|
|
Expression *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
StringExp *toUTF8(Scope *sc);
|
|
MATCH implicitConvTo(Type *t);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
int compare(Object *obj);
|
|
int isBool(int result);
|
|
unsigned charAt(size_t i);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void toMangleBuffer(OutBuffer *buf);
|
|
elem *toElem(IRState *irs);
|
|
dt_t **toDt(dt_t **pdt);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
// Tuple
|
|
|
|
struct TupleExp : Expression
|
|
{
|
|
Expressions *exps;
|
|
|
|
TupleExp(Loc loc, Expressions *exps);
|
|
TupleExp(Loc loc, TupleDeclaration *tup);
|
|
Expression *syntaxCopy();
|
|
int equals(Object *o);
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void scanForNestedRef(Scope *sc);
|
|
void checkEscape();
|
|
int checkSideEffect(int flag);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
elem *toElem(IRState *irs);
|
|
int canThrow();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
};
|
|
|
|
struct ArrayLiteralExp : Expression
|
|
{
|
|
Expressions *elements;
|
|
|
|
ArrayLiteralExp(Loc loc, Expressions *elements);
|
|
ArrayLiteralExp(Loc loc, Expression *e);
|
|
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
int isBool(int result);
|
|
elem *toElem(IRState *irs);
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void toMangleBuffer(OutBuffer *buf);
|
|
void scanForNestedRef(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
MATCH implicitConvTo(Type *t);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
dt_t **toDt(dt_t **pdt);
|
|
int canThrow();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct AssocArrayLiteralExp : Expression
|
|
{
|
|
Expressions *keys;
|
|
Expressions *values;
|
|
|
|
AssocArrayLiteralExp(Loc loc, Expressions *keys, Expressions *values);
|
|
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
int isBool(int result);
|
|
elem *toElem(IRState *irs);
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void toMangleBuffer(OutBuffer *buf);
|
|
void scanForNestedRef(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
MATCH implicitConvTo(Type *t);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
int canThrow();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct StructLiteralExp : Expression
|
|
{
|
|
StructDeclaration *sd; // which aggregate this is for
|
|
Expressions *elements; // parallels sd->fields[] with
|
|
// NULL entries for fields to skip
|
|
|
|
Symbol *sym; // back end symbol to initialize with literal
|
|
size_t soffset; // offset from start of s
|
|
int fillHoles; // fill alignment 'holes' with zero
|
|
|
|
StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements);
|
|
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
Expression *getField(Type *type, unsigned offset);
|
|
int getFieldIndex(Type *type, unsigned offset);
|
|
elem *toElem(IRState *irs);
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void toMangleBuffer(OutBuffer *buf);
|
|
void scanForNestedRef(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
dt_t **toDt(dt_t **pdt);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
int canThrow();
|
|
MATCH implicitConvTo(Type *t);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct TypeDotIdExp : Expression
|
|
{
|
|
Identifier *ident;
|
|
|
|
TypeDotIdExp(Loc loc, Type *type, Identifier *ident);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct TypeExp : Expression
|
|
{
|
|
TypeExp(Loc loc, Type *type);
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Expression *optimize(int result);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct ScopeExp : Expression
|
|
{
|
|
ScopeDsymbol *sds;
|
|
|
|
ScopeExp(Loc loc, ScopeDsymbol *sds);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
elem *toElem(IRState *irs);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct TemplateExp : Expression
|
|
{
|
|
TemplateDeclaration *td;
|
|
|
|
TemplateExp(Loc loc, TemplateDeclaration *td);
|
|
void rvalue();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct NewExp : Expression
|
|
{
|
|
/* thisexp.new(newargs) newtype(arguments)
|
|
*/
|
|
Expression *thisexp; // if !NULL, 'this' for class being allocated
|
|
Expressions *newargs; // Array of Expression's to call new operator
|
|
Type *newtype;
|
|
Expressions *arguments; // Array of Expression's
|
|
|
|
CtorDeclaration *member; // constructor function
|
|
NewDeclaration *allocator; // allocator function
|
|
int onstack; // allocate on stack
|
|
|
|
NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
|
|
Type *newtype, Expressions *arguments);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
elem *toElem(IRState *irs);
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void scanForNestedRef(Scope *sc);
|
|
int canThrow();
|
|
|
|
//int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
//Expression *inlineScan(InlineScanState *iss);
|
|
};
|
|
|
|
struct NewAnonClassExp : Expression
|
|
{
|
|
/* thisexp.new(newargs) class baseclasses { } (arguments)
|
|
*/
|
|
Expression *thisexp; // if !NULL, 'this' for class being allocated
|
|
Expressions *newargs; // Array of Expression's to call new operator
|
|
ClassDeclaration *cd; // class being instantiated
|
|
Expressions *arguments; // Array of Expression's to call class constructor
|
|
|
|
NewAnonClassExp(Loc loc, Expression *thisexp, Expressions *newargs,
|
|
ClassDeclaration *cd, Expressions *arguments);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int canThrow();
|
|
};
|
|
|
|
struct SymbolExp : Expression
|
|
{
|
|
Declaration *var;
|
|
int hasOverloads;
|
|
|
|
SymbolExp(Loc loc, enum TOK op, int size, Declaration *var, int hasOverloads);
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
// Offset from symbol
|
|
|
|
struct SymOffExp : SymbolExp
|
|
{
|
|
unsigned offset;
|
|
|
|
SymOffExp(Loc loc, Declaration *var, unsigned offset, int hasOverloads = 0);
|
|
Expression *semantic(Scope *sc);
|
|
void checkEscape();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int isConst();
|
|
int isBool(int result);
|
|
Expression *doInline(InlineDoState *ids);
|
|
MATCH implicitConvTo(Type *t);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
void scanForNestedRef(Scope *sc);
|
|
|
|
dt_t **toDt(dt_t **pdt);
|
|
|
|
// LDC
|
|
elem *toElem(IRState* irs);
|
|
};
|
|
|
|
// Variable
|
|
|
|
struct VarExp : SymbolExp
|
|
{
|
|
VarExp(Loc loc, Declaration *var, int hasOverloads = 0);
|
|
int equals(Object *o);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void dump(int indent);
|
|
char *toChars();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void checkEscape();
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
Expression *modifiableLvalue(Scope *sc, Expression *e);
|
|
dt_t **toDt(dt_t **pdt);
|
|
void scanForNestedRef(Scope *sc);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
//Expression *inlineScan(InlineScanState *iss);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
virtual elem *toElem(IRState* irs);
|
|
};
|
|
|
|
#if DMDV2
|
|
// Overload Set
|
|
|
|
struct OverExp : Expression
|
|
{
|
|
OverloadSet *vars;
|
|
|
|
OverExp(OverloadSet *s);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
};
|
|
#endif
|
|
|
|
// Function/Delegate literal
|
|
|
|
struct FuncExp : Expression
|
|
{
|
|
FuncLiteralDeclaration *fd;
|
|
|
|
FuncExp(Loc loc, FuncLiteralDeclaration *fd);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
void scanForNestedRef(Scope *sc);
|
|
char *toChars();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
elem *toElem(IRState *irs);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
//Expression *doInline(InlineDoState *ids);
|
|
//Expression *inlineScan(InlineScanState *iss);
|
|
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
// Declaration of a symbol
|
|
|
|
struct DeclarationExp : Expression
|
|
{
|
|
Dsymbol *declaration;
|
|
|
|
DeclarationExp(Loc loc, Dsymbol *declaration);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
elem *toElem(IRState *irs);
|
|
void scanForNestedRef(Scope *sc);
|
|
int canThrow();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
};
|
|
|
|
struct TypeidExp : Expression
|
|
{
|
|
Type *typeidType;
|
|
|
|
TypeidExp(Loc loc, Type *typeidType);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
#if DMDV2
|
|
struct TraitsExp : Expression
|
|
{
|
|
Identifier *ident;
|
|
Objects *args;
|
|
|
|
TraitsExp(Loc loc, Identifier *ident, Objects *args);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
#endif
|
|
|
|
struct HaltExp : Expression
|
|
{
|
|
HaltExp(Loc loc);
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int checkSideEffect(int flag);
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct IsExp : Expression
|
|
{
|
|
/* is(targ id tok tspec)
|
|
* is(targ id == tok2)
|
|
*/
|
|
Type *targ;
|
|
Identifier *id; // can be NULL
|
|
enum TOK tok; // ':' or '=='
|
|
Type *tspec; // can be NULL
|
|
enum TOK tok2; // 'struct', 'union', 'typedef', etc.
|
|
TemplateParameters *parameters;
|
|
|
|
IsExp(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec,
|
|
enum TOK tok2, TemplateParameters *parameters);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
/****************************************************************/
|
|
|
|
struct UnaExp : Expression
|
|
{
|
|
Expression *e1;
|
|
|
|
UnaExp(Loc loc, enum TOK op, int size, Expression *e1);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Expression *optimize(int result);
|
|
void dump(int indent);
|
|
void scanForNestedRef(Scope *sc);
|
|
Expression *interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *));
|
|
int canThrow();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
|
|
Expression *op_overload(Scope *sc); // doesn't need to be virtual
|
|
};
|
|
|
|
struct BinExp : Expression
|
|
{
|
|
Expression *e1;
|
|
Expression *e2;
|
|
|
|
BinExp(Loc loc, enum TOK op, int size, Expression *e1, Expression *e2);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
Expression *semanticp(Scope *sc);
|
|
Expression *commonSemanticAssign(Scope *sc);
|
|
Expression *commonSemanticAssignIntegral(Scope *sc);
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Expression *scaleFactor(Scope *sc);
|
|
Expression *typeCombine(Scope *sc);
|
|
Expression *optimize(int result);
|
|
int isunsigned();
|
|
void incompatibleTypes();
|
|
void dump(int indent);
|
|
void scanForNestedRef(Scope *sc);
|
|
Expression *interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *, Expression *));
|
|
Expression *interpretCommon2(InterState *istate, Expression *(*fp)(TOK, Type *, Expression *, Expression *));
|
|
Expression *interpretAssignCommon(InterState *istate, Expression *(*fp)(Type *, Expression *, Expression *), int post = 0);
|
|
int canThrow();
|
|
Expression *arrayOp(Scope *sc);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
|
|
Expression *op_overload(Scope *sc);
|
|
|
|
elem *toElemBin(IRState *irs, int op);
|
|
};
|
|
|
|
struct BinAssignExp : BinExp
|
|
{
|
|
BinAssignExp(Loc loc, enum TOK op, int size, Expression *e1, Expression *e2);
|
|
int checkSideEffect(int flag);
|
|
};
|
|
|
|
/****************************************************************/
|
|
|
|
struct CompileExp : UnaExp
|
|
{
|
|
CompileExp(Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct FileExp : UnaExp
|
|
{
|
|
FileExp(Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct AssertExp : UnaExp
|
|
{
|
|
Expression *msg;
|
|
|
|
AssertExp(Loc loc, Expression *e, Expression *msg = NULL);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
int checkSideEffect(int flag);
|
|
int canThrow();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct DotIdExp : UnaExp
|
|
{
|
|
Identifier *ident;
|
|
|
|
DotIdExp(Loc loc, Expression *e, Identifier *ident);
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void dump(int i);
|
|
};
|
|
|
|
struct DotTemplateExp : UnaExp
|
|
{
|
|
TemplateDeclaration *td;
|
|
|
|
DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct DotVarExp : UnaExp
|
|
{
|
|
Declaration *var;
|
|
int hasOverloads;
|
|
|
|
DotVarExp(Loc loc, Expression *e, Declaration *var, int hasOverloads = 0);
|
|
Expression *semantic(Scope *sc);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
Expression *modifiableLvalue(Scope *sc, Expression *e);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void dump(int indent);
|
|
elem *toElem(IRState *irs);
|
|
|
|
//LDC: since we don't convert abc.def -> *(&abc + ABC.def.offsetof)
|
|
// these are needed
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
};
|
|
|
|
struct DotTemplateInstanceExp : UnaExp
|
|
{
|
|
TemplateInstance *ti;
|
|
|
|
DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void dump(int indent);
|
|
};
|
|
|
|
struct DelegateExp : UnaExp
|
|
{
|
|
FuncDeclaration *func;
|
|
int hasOverloads;
|
|
|
|
DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, int hasOverloads = 0);
|
|
Expression *semantic(Scope *sc);
|
|
MATCH implicitConvTo(Type *t);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void dump(int indent);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct DotTypeExp : UnaExp
|
|
{
|
|
Dsymbol *sym; // symbol that represents a type
|
|
|
|
DotTypeExp(Loc loc, Expression *e, Dsymbol *sym);
|
|
Expression *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct CallExp : UnaExp
|
|
{
|
|
Expressions *arguments; // function arguments
|
|
|
|
CallExp(Loc loc, Expression *e, Expressions *exps);
|
|
CallExp(Loc loc, Expression *e);
|
|
CallExp(Loc loc, Expression *e, Expression *earg1);
|
|
CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2);
|
|
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void dump(int indent);
|
|
elem *toElem(IRState *irs);
|
|
void scanForNestedRef(Scope *sc);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
int canThrow();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
};
|
|
|
|
struct AddrExp : UnaExp
|
|
{
|
|
AddrExp(Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
elem *toElem(IRState *irs);
|
|
MATCH implicitConvTo(Type *t);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
Expression *optimize(int result);
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct PtrExp : UnaExp
|
|
{
|
|
PtrExp(Loc loc, Expression *e);
|
|
PtrExp(Loc loc, Expression *e, Type *t);
|
|
Expression *semantic(Scope *sc);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
Expression *modifiableLvalue(Scope *sc, Expression *e);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
elem *toElem(IRState *irs);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
};
|
|
|
|
struct NegExp : UnaExp
|
|
{
|
|
NegExp(Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct UAddExp : UnaExp
|
|
{
|
|
UAddExp(Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
};
|
|
|
|
struct ComExp : UnaExp
|
|
{
|
|
ComExp(Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct NotExp : UnaExp
|
|
{
|
|
NotExp(Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
int isBit();
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct BoolExp : UnaExp
|
|
{
|
|
BoolExp(Loc loc, Expression *e, Type *type);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
int isBit();
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct DeleteExp : UnaExp
|
|
{
|
|
DeleteExp(Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *checkToBoolean();
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct CastExp : UnaExp
|
|
{
|
|
// Possible to cast to one type while painting to another type
|
|
Type *to; // type to cast to
|
|
enum TOK tok; // TOKconst or TOKinvariant
|
|
|
|
CastExp(Loc loc, Expression *e, Type *t);
|
|
CastExp(Loc loc, Expression *e, enum TOK tok);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
int checkSideEffect(int flag);
|
|
void checkEscape();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
elem *toElem(IRState *irs);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
|
|
struct SliceExp : UnaExp
|
|
{
|
|
Expression *upr; // NULL if implicit 0
|
|
Expression *lwr; // NULL if implicit [length - 1]
|
|
VarDeclaration *lengthVar;
|
|
|
|
SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
void checkEscape();
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
Expression *modifiableLvalue(Scope *sc, Expression *e);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void dump(int indent);
|
|
elem *toElem(IRState *irs);
|
|
void scanForNestedRef(Scope *sc);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
struct ArrayLengthExp : UnaExp
|
|
{
|
|
ArrayLengthExp(Loc loc, Expression *e1);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
// e1[a0,a1,a2,a3,...]
|
|
|
|
struct ArrayExp : UnaExp
|
|
{
|
|
Expressions *arguments; // Array of Expression's
|
|
|
|
ArrayExp(Loc loc, Expression *e1, Expressions *arguments);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void scanForNestedRef(Scope *sc);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
};
|
|
|
|
/****************************************************************/
|
|
|
|
struct DotExp : BinExp
|
|
{
|
|
DotExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
};
|
|
|
|
struct CommaExp : BinExp
|
|
{
|
|
CommaExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
void checkEscape();
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
Expression *modifiableLvalue(Scope *sc, Expression *e);
|
|
int isBool(int result);
|
|
int checkSideEffect(int flag);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct IndexExp : BinExp
|
|
{
|
|
VarDeclaration *lengthVar;
|
|
int modifiable;
|
|
|
|
IndexExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
Expression *modifiableLvalue(Scope *sc, Expression *e);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
Expression *doInline(InlineDoState *ids);
|
|
void scanForNestedRef(Scope *sc);
|
|
|
|
elem *toElem(IRState *irs);
|
|
|
|
// LDC
|
|
virtual llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
/* For both i++ and i--
|
|
*/
|
|
struct PostExp : BinExp
|
|
{
|
|
PostExp(enum TOK op, Loc loc, Expression *e);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Identifier *opId(); // For operator overloading
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct AssignExp : BinExp
|
|
{ int ismemset; // !=0 if setting the contents of an array
|
|
|
|
AssignExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *checkToBoolean();
|
|
Expression *interpret(InterState *istate);
|
|
Identifier *opId(); // For operator overloading
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
#define ASSIGNEXP(op) \
|
|
struct op##AssignExp : BinExp \
|
|
{ \
|
|
op##AssignExp(Loc loc, Expression *e1, Expression *e2); \
|
|
Expression *semantic(Scope *sc); \
|
|
Expression *interpret(InterState *istate); \
|
|
X(void buildArrayIdent(OutBuffer *buf, Expressions *arguments);) \
|
|
X(Expression *buildArrayLoop(Arguments *fparams);) \
|
|
\
|
|
Identifier *opId(); /* For operator overloading */ \
|
|
\
|
|
elem *toElem(IRState *irs); \
|
|
};
|
|
|
|
#define X(a) a
|
|
ASSIGNEXP(Add)
|
|
ASSIGNEXP(Min)
|
|
ASSIGNEXP(Mul)
|
|
ASSIGNEXP(Div)
|
|
ASSIGNEXP(Mod)
|
|
ASSIGNEXP(And)
|
|
ASSIGNEXP(Or)
|
|
ASSIGNEXP(Xor)
|
|
#undef X
|
|
|
|
#define X(a)
|
|
|
|
ASSIGNEXP(Shl)
|
|
ASSIGNEXP(Shr)
|
|
ASSIGNEXP(Ushr)
|
|
ASSIGNEXP(Cat)
|
|
|
|
#undef X
|
|
#undef ASSIGNEXP
|
|
|
|
struct AddExp : BinExp
|
|
{
|
|
AddExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
int isCommutative();
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct MinExp : BinExp
|
|
{
|
|
MinExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct CatExp : BinExp
|
|
{
|
|
CatExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct MulExp : BinExp
|
|
{
|
|
MulExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
int isCommutative();
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct DivExp : BinExp
|
|
{
|
|
DivExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct ModExp : BinExp
|
|
{
|
|
ModExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct ShlExp : BinExp
|
|
{
|
|
ShlExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct ShrExp : BinExp
|
|
{
|
|
ShrExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct UshrExp : BinExp
|
|
{
|
|
UshrExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct AndExp : BinExp
|
|
{
|
|
AndExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
int isCommutative();
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct OrExp : BinExp
|
|
{
|
|
OrExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
int isCommutative();
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct XorExp : BinExp
|
|
{
|
|
XorExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
|
|
Expression *buildArrayLoop(Arguments *fparams);
|
|
|
|
// For operator overloading
|
|
int isCommutative();
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct OrOrExp : BinExp
|
|
{
|
|
OrOrExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *checkToBoolean();
|
|
int isBit();
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
int checkSideEffect(int flag);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct AndAndExp : BinExp
|
|
{
|
|
AndAndExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *checkToBoolean();
|
|
int isBit();
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
int checkSideEffect(int flag);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct CmpExp : BinExp
|
|
{
|
|
CmpExp(enum TOK op, Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
int isBit();
|
|
|
|
// For operator overloading
|
|
int isCommutative();
|
|
Identifier *opId();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct InExp : BinExp
|
|
{
|
|
InExp(Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
int isBit();
|
|
|
|
// For operator overloading
|
|
Identifier *opId();
|
|
Identifier *opId_r();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
struct RemoveExp : BinExp
|
|
{
|
|
RemoveExp(Loc loc, Expression *e1, Expression *e2);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
// == and !=
|
|
|
|
struct EqualExp : BinExp
|
|
{
|
|
EqualExp(enum TOK op, Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
int isBit();
|
|
|
|
// For operator overloading
|
|
int isCommutative();
|
|
Identifier *opId();
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
// === and !===
|
|
|
|
struct IdentityExp : BinExp
|
|
{
|
|
IdentityExp(enum TOK op, Loc loc, Expression *e1, Expression *e2);
|
|
Expression *semantic(Scope *sc);
|
|
int isBit();
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
/****************************************************************/
|
|
|
|
struct CondExp : BinExp
|
|
{
|
|
Expression *econd;
|
|
|
|
CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2);
|
|
Expression *syntaxCopy();
|
|
Expression *semantic(Scope *sc);
|
|
Expression *optimize(int result);
|
|
Expression *interpret(InterState *istate);
|
|
void checkEscape();
|
|
int isLvalue();
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
Expression *modifiableLvalue(Scope *sc, Expression *e);
|
|
Expression *checkToBoolean();
|
|
int checkSideEffect(int flag);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
MATCH implicitConvTo(Type *t);
|
|
Expression *castTo(Scope *sc, Type *t);
|
|
void scanForNestedRef(Scope *sc);
|
|
int canThrow();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Expression *inlineScan(InlineScanState *iss);
|
|
|
|
elem *toElem(IRState *irs);
|
|
};
|
|
|
|
#if DMDV2
|
|
/****************************************************************/
|
|
|
|
struct DefaultInitExp : Expression
|
|
{
|
|
enum TOK subop; // which of the derived classes this is
|
|
|
|
DefaultInitExp(Loc loc, enum TOK subop, int size);
|
|
virtual Expression *resolve(Loc loc, Scope *sc) = 0;
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct FileInitExp : DefaultInitExp
|
|
{
|
|
FileInitExp(Loc loc);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *resolve(Loc loc, Scope *sc);
|
|
};
|
|
|
|
struct LineInitExp : DefaultInitExp
|
|
{
|
|
LineInitExp(Loc loc);
|
|
Expression *semantic(Scope *sc);
|
|
Expression *resolve(Loc loc, Scope *sc);
|
|
};
|
|
#endif
|
|
|
|
/****************************************************************/
|
|
|
|
#if IN_LLVM
|
|
|
|
// this stuff is strictly LDC
|
|
|
|
struct GEPExp : UnaExp
|
|
{
|
|
unsigned index;
|
|
Identifier* ident;
|
|
|
|
GEPExp(Loc loc, Expression* e, Identifier* id, unsigned idx);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Expression *toLvalue(Scope *sc, Expression *e);
|
|
|
|
elem *toElem(IRState *irs);
|
|
llvm::Constant *toConstElem(IRState *irs);
|
|
};
|
|
|
|
#endif
|
|
|
|
/****************************************************************/
|
|
|
|
/* Special values used by the interpreter
|
|
*/
|
|
#define EXP_CANT_INTERPRET ((Expression *)1)
|
|
#define EXP_CONTINUE_INTERPRET ((Expression *)2)
|
|
#define EXP_BREAK_INTERPRET ((Expression *)3)
|
|
#define EXP_GOTO_INTERPRET ((Expression *)4)
|
|
#define EXP_VOID_INTERPRET ((Expression *)5)
|
|
|
|
Expression *expType(Type *type, Expression *e);
|
|
|
|
Expression *Neg(Type *type, Expression *e1);
|
|
Expression *Com(Type *type, Expression *e1);
|
|
Expression *Not(Type *type, Expression *e1);
|
|
Expression *Bool(Type *type, Expression *e1);
|
|
Expression *Cast(Type *type, Type *to, Expression *e1);
|
|
Expression *ArrayLength(Type *type, Expression *e1);
|
|
Expression *Ptr(Type *type, Expression *e1);
|
|
|
|
Expression *Add(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Min(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Mul(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Div(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Mod(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Shl(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Shr(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Ushr(Type *type, Expression *e1, Expression *e2);
|
|
Expression *And(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Or(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Xor(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Index(Type *type, Expression *e1, Expression *e2);
|
|
Expression *Cat(Type *type, Expression *e1, Expression *e2);
|
|
|
|
Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2);
|
|
Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2);
|
|
Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2);
|
|
|
|
Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr);
|
|
|
|
#endif /* DMD_EXPRESSION_H */
|