// 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 */