mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-09 20:37:25 +03:00

Applied patch from ticket #129 to compile against latest LLVM. Thanks Frits van Bommel. Fixed implicit return by asm block at the end of a function on x86-32. Other architectures will produce an error at the moment. Adding support for new targets is fairly simple. Fixed return calling convention for complex numbers, ST and ST(1) were switched around. Added some testcases. I've run a dstress test and there are no regressions. However, the runtime does not seem to compile with symbolic debug information. -O3 -release -inline works well and is what I used for the dstress run. Tango does not compile, a small workaround is needed in tango.io.digest.Digest.Digest.hexDigest. See ticket #206 .
951 lines
24 KiB
C++
951 lines
24 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_STATEMENT_H
|
|
#define DMD_STATEMENT_H
|
|
|
|
#ifdef __DMC__
|
|
#pragma once
|
|
#endif /* __DMC__ */
|
|
|
|
#include "root.h"
|
|
|
|
#include "arraytypes.h"
|
|
#include "dsymbol.h"
|
|
#include "lexer.h"
|
|
|
|
struct OutBuffer;
|
|
struct Scope;
|
|
struct Expression;
|
|
struct LabelDsymbol;
|
|
struct Identifier;
|
|
struct IfStatement;
|
|
struct DeclarationStatement;
|
|
struct DefaultStatement;
|
|
struct VarDeclaration;
|
|
struct Condition;
|
|
struct Module;
|
|
struct Token;
|
|
struct InlineCostState;
|
|
struct InlineDoState;
|
|
struct InlineScanState;
|
|
struct ReturnStatement;
|
|
struct CompoundStatement;
|
|
struct Argument;
|
|
struct StaticAssert;
|
|
struct AsmStatement;
|
|
struct AsmBlockStatement;
|
|
struct GotoStatement;
|
|
struct ScopeStatement;
|
|
struct TryCatchStatement;
|
|
struct TryFinallyStatement;
|
|
struct HdrGenState;
|
|
struct InterState;
|
|
struct CaseStatement;
|
|
struct LabelStatement;
|
|
struct VolatileStatement;
|
|
struct SynchronizedStatement;
|
|
|
|
enum TOK;
|
|
|
|
namespace llvm
|
|
{
|
|
class Value;
|
|
class BasicBlock;
|
|
class ConstantInt;
|
|
}
|
|
|
|
// Back end
|
|
struct IRState;
|
|
struct Blockx;
|
|
#if IN_LLVM
|
|
struct DValue;
|
|
typedef DValue elem;
|
|
#endif
|
|
|
|
#if IN_GCC
|
|
union tree_node; typedef union tree_node block;
|
|
//union tree_node; typedef union tree_node elem;
|
|
#else
|
|
struct block;
|
|
//struct elem;
|
|
#endif
|
|
struct code;
|
|
|
|
/* How a statement exits
|
|
*/
|
|
enum BE
|
|
{
|
|
BEnone = 0,
|
|
BEfallthru = 1,
|
|
BEthrow = 2,
|
|
BEreturn = 4,
|
|
BEgoto = 8,
|
|
BEhalt = 0x10,
|
|
BEbreak = 0x20,
|
|
BEcontinue = 0x40,
|
|
BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt),
|
|
};
|
|
|
|
// LDC this is used for tracking try-finally, synchronized and volatile scopes
|
|
// definitions in gen/llvmhelpers.cpp
|
|
struct EnclosingHandler : Object
|
|
{
|
|
virtual void emitCode(IRState* p) = 0;
|
|
virtual EnclosingHandler* getEnclosing() = 0;
|
|
};
|
|
struct EnclosingTryFinally : EnclosingHandler
|
|
{
|
|
TryFinallyStatement* tf;
|
|
void emitCode(IRState* p);
|
|
EnclosingHandler* getEnclosing();
|
|
EnclosingTryFinally(TryFinallyStatement* _tf) : tf(_tf) {}
|
|
};
|
|
struct EnclosingVolatile : EnclosingHandler
|
|
{
|
|
VolatileStatement* v;
|
|
void emitCode(IRState* p);
|
|
EnclosingHandler* getEnclosing();
|
|
EnclosingVolatile(VolatileStatement* _tf) : v(_tf) {}
|
|
};
|
|
struct EnclosingSynchro : EnclosingHandler
|
|
{
|
|
SynchronizedStatement* s;
|
|
void emitCode(IRState* p);
|
|
EnclosingHandler* getEnclosing();
|
|
EnclosingSynchro(SynchronizedStatement* _tf) : s(_tf) {}
|
|
};
|
|
|
|
struct Statement : Object
|
|
{
|
|
Loc loc;
|
|
|
|
Statement(Loc loc);
|
|
virtual Statement *syntaxCopy();
|
|
|
|
void print();
|
|
char *toChars();
|
|
|
|
void error(const char *format, ...);
|
|
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
virtual TryCatchStatement *isTryCatchStatement() { return NULL; }
|
|
virtual GotoStatement *isGotoStatement() { return NULL; }
|
|
virtual AsmStatement *isAsmStatement() { return NULL; }
|
|
virtual AsmBlockStatement *isAsmBlockStatement() { return NULL; }
|
|
#ifdef _DH
|
|
int incontract;
|
|
#endif
|
|
virtual ScopeStatement *isScopeStatement() { return NULL; }
|
|
virtual Statement *semantic(Scope *sc);
|
|
Statement *semanticScope(Scope *sc, Statement *sbreak, Statement *scontinue);
|
|
virtual int hasBreak();
|
|
virtual int hasContinue();
|
|
virtual int usesEH();
|
|
virtual int fallOffEnd();
|
|
virtual int blockExit();
|
|
virtual int comeFrom();
|
|
virtual void scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
virtual Statements *flatten(Scope *sc);
|
|
virtual Expression *interpret(InterState *istate);
|
|
|
|
virtual int inlineCost(InlineCostState *ics);
|
|
virtual Expression *doInline(InlineDoState *ids);
|
|
virtual Statement *inlineScan(InlineScanState *iss);
|
|
|
|
// Back end
|
|
virtual void toIR(IRState *irs);
|
|
|
|
// Avoid dynamic_cast
|
|
virtual DeclarationStatement *isDeclarationStatement() { return NULL; }
|
|
virtual CompoundStatement *isCompoundStatement() { return NULL; }
|
|
virtual ReturnStatement *isReturnStatement() { return NULL; }
|
|
virtual IfStatement *isIfStatement() { return NULL; }
|
|
virtual CaseStatement* isCaseStatement() { return NULL; }
|
|
|
|
// LDC
|
|
virtual void toNakedIR(IRState *irs);
|
|
virtual AsmBlockStatement* endsWithAsm();
|
|
};
|
|
|
|
struct ExpStatement : Statement
|
|
{
|
|
Expression *exp;
|
|
|
|
ExpStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Statement *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
int fallOffEnd();
|
|
int blockExit();
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
|
|
// LDC
|
|
virtual void toNakedIR(IRState *irs);
|
|
};
|
|
|
|
struct CompileStatement : Statement
|
|
{
|
|
Expression *exp;
|
|
|
|
CompileStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Statements *flatten(Scope *sc);
|
|
Statement *semantic(Scope *sc);
|
|
};
|
|
|
|
struct DeclarationStatement : ExpStatement
|
|
{
|
|
// Doing declarations as an expression, rather than a statement,
|
|
// makes inlining functions much easier.
|
|
|
|
DeclarationStatement(Loc loc, Dsymbol *s);
|
|
DeclarationStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
void scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
|
|
DeclarationStatement *isDeclarationStatement() { return this; }
|
|
};
|
|
|
|
struct CompoundStatement : Statement
|
|
{
|
|
Statements *statements;
|
|
|
|
CompoundStatement(Loc loc, Statements *s);
|
|
CompoundStatement(Loc loc, Statement *s1, Statement *s2);
|
|
virtual Statement *syntaxCopy();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
virtual Statement *semantic(Scope *sc);
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
virtual Statements *flatten(Scope *sc);
|
|
ReturnStatement *isReturnStatement();
|
|
Expression *interpret(InterState *istate);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
virtual void toIR(IRState *irs);
|
|
|
|
// LDC
|
|
virtual void toNakedIR(IRState *irs);
|
|
virtual AsmBlockStatement* endsWithAsm();
|
|
|
|
virtual CompoundStatement *isCompoundStatement() { return this; }
|
|
};
|
|
|
|
/* The purpose of this is so that continue will go to the next
|
|
* of the statements, and break will go to the end of the statements.
|
|
*/
|
|
struct UnrolledLoopStatement : Statement
|
|
{
|
|
Statements *statements;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
UnrolledLoopStatement(Loc loc, Statements *statements);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct ScopeStatement : Statement
|
|
{
|
|
Statement *statement;
|
|
|
|
ScopeStatement(Loc loc, Statement *s);
|
|
Statement *syntaxCopy();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
ScopeStatement *isScopeStatement() { return this; }
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct WhileStatement : Statement
|
|
{
|
|
Expression *condition;
|
|
Statement *body;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
WhileStatement(Loc loc, Expression *c, Statement *b);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct DoStatement : Statement
|
|
{
|
|
Statement *body;
|
|
Expression *condition;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
DoStatement(Loc loc, Statement *b, Expression *c);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct ForStatement : Statement
|
|
{
|
|
Statement *init;
|
|
Expression *condition;
|
|
Expression *increment;
|
|
Statement *body;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
void scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct ForeachStatement : Statement
|
|
{
|
|
enum TOK op; // TOKforeach or TOKforeach_reverse
|
|
Arguments *arguments; // array of Argument*'s
|
|
Expression *aggr;
|
|
Statement *body;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
VarDeclaration *key;
|
|
VarDeclaration *value;
|
|
|
|
FuncDeclaration *func; // function we're lexically in
|
|
|
|
Array cases; // put breaks, continues, gotos and returns here
|
|
Array gotos; // forward referenced goto's go here
|
|
|
|
ForeachStatement(Loc loc, enum TOK op, Arguments *arguments, Expression *aggr, Statement *body);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool checkForArgTypes();
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
#if DMDV2
|
|
struct ForeachRangeStatement : Statement
|
|
{
|
|
enum TOK op; // TOKforeach or TOKforeach_reverse
|
|
Argument *arg; // loop index variable
|
|
Expression *lwr;
|
|
Expression *upr;
|
|
Statement *body;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
VarDeclaration *key;
|
|
|
|
ForeachRangeStatement(Loc loc, enum TOK op, Argument *arg,
|
|
Expression *lwr, Expression *upr, Statement *body);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
#endif
|
|
|
|
struct IfStatement : Statement
|
|
{
|
|
Argument *arg;
|
|
Expression *condition;
|
|
Statement *ifbody;
|
|
Statement *elsebody;
|
|
|
|
VarDeclaration *match; // for MatchExpression results
|
|
|
|
IfStatement(Loc loc, Argument *arg, Expression *condition, Statement *ifbody, Statement *elsebody);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
IfStatement *isIfStatement() { return this; }
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct ConditionalStatement : Statement
|
|
{
|
|
Condition *condition;
|
|
Statement *ifbody;
|
|
Statement *elsebody;
|
|
|
|
ConditionalStatement(Loc loc, Condition *condition, Statement *ifbody, Statement *elsebody);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statements *flatten(Scope *sc);
|
|
int usesEH();
|
|
int blockExit();
|
|
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct PragmaStatement : Statement
|
|
{
|
|
Identifier *ident;
|
|
Expressions *args; // array of Expression's
|
|
Statement *body;
|
|
|
|
PragmaStatement(Loc loc, Identifier *ident, Expressions *args, Statement *body);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct StaticAssertStatement : Statement
|
|
{
|
|
StaticAssert *sa;
|
|
|
|
StaticAssertStatement(StaticAssert *sa);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct SwitchStatement : Statement
|
|
{
|
|
Expression *condition;
|
|
Statement *body;
|
|
|
|
DefaultStatement *sdefault;
|
|
TryFinallyStatement *tf;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
Array gotoCases; // array of unresolved GotoCaseStatement's
|
|
Array *cases; // array of CaseStatement's
|
|
int hasNoDefault; // !=0 if no default statement
|
|
int hasVars; // !=0 if has variable case values
|
|
|
|
SwitchStatement(Loc loc, Expression *c, Statement *b);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct CaseStatement : Statement
|
|
{
|
|
Expression *exp;
|
|
Statement *statement;
|
|
int index; // which case it is (since we sort this)
|
|
block *cblock; // back end: label for the block
|
|
|
|
CaseStatement(Loc loc, Expression *exp, Statement *s);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int compare(Object *obj);
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
|
|
CaseStatement* isCaseStatement() { return this; }
|
|
|
|
// LDC
|
|
llvm::BasicBlock* bodyBB;
|
|
llvm::ConstantInt* llvmIdx;
|
|
};
|
|
|
|
struct DefaultStatement : Statement
|
|
{
|
|
Statement *statement;
|
|
#if IN_GCC
|
|
block *cblock; // back end: label for the block
|
|
#endif
|
|
|
|
DefaultStatement(Loc loc, Statement *s);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
|
|
// LDC
|
|
llvm::BasicBlock* bodyBB;
|
|
};
|
|
|
|
struct GotoDefaultStatement : Statement
|
|
{
|
|
SwitchStatement *sw;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
GotoDefaultStatement(Loc loc);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct GotoCaseStatement : Statement
|
|
{
|
|
Expression *exp; // NULL, or which case to goto
|
|
CaseStatement *cs; // case statement it resolves to
|
|
EnclosingHandler* enclosinghandler;
|
|
SwitchStatement *sw;
|
|
|
|
GotoCaseStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct SwitchErrorStatement : Statement
|
|
{
|
|
SwitchErrorStatement(Loc loc);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct ReturnStatement : Statement
|
|
{
|
|
Expression *exp;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
ReturnStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Statement *semantic(Scope *sc);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
Expression *interpret(InterState *istate);
|
|
|
|
int inlineCost(InlineCostState *ics);
|
|
Expression *doInline(InlineDoState *ids);
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
|
|
ReturnStatement *isReturnStatement() { return this; }
|
|
};
|
|
|
|
struct BreakStatement : Statement
|
|
{
|
|
Identifier *ident;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
BreakStatement(Loc loc, Identifier *ident);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
void toIR(IRState *irs);
|
|
|
|
// LDC: only set if ident is set: label statement to jump to
|
|
LabelStatement *target;
|
|
};
|
|
|
|
struct ContinueStatement : Statement
|
|
{
|
|
Identifier *ident;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
ContinueStatement(Loc loc, Identifier *ident);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Expression *interpret(InterState *istate);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
void toIR(IRState *irs);
|
|
|
|
// LDC: only set if ident is set: label statement to jump to
|
|
LabelStatement *target;
|
|
};
|
|
|
|
struct SynchronizedStatement : Statement
|
|
{
|
|
Expression *exp;
|
|
Statement *body;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
SynchronizedStatement(Loc loc, Expression *exp, Statement *body);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
// Back end
|
|
elem *esync;
|
|
SynchronizedStatement(Loc loc, elem *esync, Statement *body);
|
|
void toIR(IRState *irs);
|
|
llvm::Value* llsync;
|
|
};
|
|
|
|
struct WithStatement : Statement
|
|
{
|
|
Expression *exp;
|
|
Statement *body;
|
|
VarDeclaration *wthis;
|
|
|
|
WithStatement(Loc loc, Expression *exp, Statement *body);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct TryCatchStatement : Statement
|
|
{
|
|
Statement *body;
|
|
Array *catches;
|
|
|
|
TryCatchStatement(Loc loc, Statement *body, Array *catches);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
TryCatchStatement *isTryCatchStatement() { return this; }
|
|
};
|
|
|
|
struct Catch : Object
|
|
{
|
|
Loc loc;
|
|
Type *type;
|
|
Identifier *ident;
|
|
VarDeclaration *var;
|
|
Statement *handler;
|
|
|
|
Catch(Loc loc, Type *t, Identifier *id, Statement *handler);
|
|
Catch *syntaxCopy();
|
|
void semantic(Scope *sc);
|
|
int blockExit();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
};
|
|
|
|
struct TryFinallyStatement : Statement
|
|
{
|
|
Statement *body;
|
|
Statement *finalbody;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody);
|
|
Statement *syntaxCopy();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Statement *semantic(Scope *sc);
|
|
int hasBreak();
|
|
int hasContinue();
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct OnScopeStatement : Statement
|
|
{
|
|
TOK tok;
|
|
Statement *statement;
|
|
|
|
OnScopeStatement(Loc loc, TOK tok, Statement *statement);
|
|
Statement *syntaxCopy();
|
|
int blockExit();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
Statement *semantic(Scope *sc);
|
|
int usesEH();
|
|
void scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct ThrowStatement : Statement
|
|
{
|
|
Expression *exp;
|
|
|
|
ThrowStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct VolatileStatement : Statement
|
|
{
|
|
Statement *statement;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
VolatileStatement(Loc loc, Statement *statement);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statements *flatten(Scope *sc);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
};
|
|
|
|
struct GotoStatement : Statement
|
|
{
|
|
Identifier *ident;
|
|
LabelDsymbol *label;
|
|
TryFinallyStatement *tf;
|
|
EnclosingHandler* enclosinghandler;
|
|
|
|
GotoStatement(Loc loc, Identifier *ident);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
Expression *interpret(InterState *istate);
|
|
|
|
void toIR(IRState *irs);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
GotoStatement *isGotoStatement() { return this; }
|
|
};
|
|
|
|
struct LabelStatement : Statement
|
|
{
|
|
Identifier *ident;
|
|
Statement *statement;
|
|
TryFinallyStatement *tf;
|
|
EnclosingHandler* enclosinghandler;
|
|
block *lblock; // back end
|
|
int isReturnLabel;
|
|
|
|
LabelStatement(Loc loc, Identifier *ident, Statement *statement);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statements *flatten(Scope *sc);
|
|
int usesEH();
|
|
int blockExit();
|
|
int fallOffEnd();
|
|
int comeFrom();
|
|
Expression *interpret(InterState *istate);
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
|
|
Statement *inlineScan(InlineScanState *iss);
|
|
|
|
void toIR(IRState *irs);
|
|
|
|
// LDC
|
|
bool asmLabel; // for labels inside inline assembler
|
|
virtual void toNakedIR(IRState *irs);
|
|
};
|
|
|
|
struct LabelDsymbol : Dsymbol
|
|
{
|
|
LabelStatement *statement;
|
|
|
|
LabelDsymbol(Identifier *ident);
|
|
LabelDsymbol *isLabel();
|
|
};
|
|
|
|
struct AsmStatement : Statement
|
|
{
|
|
Token *tokens;
|
|
code *asmcode;
|
|
unsigned asmalign; // alignment of this statement
|
|
unsigned refparam; // !=0 if function parameter is referenced
|
|
unsigned naked; // !=0 if function is to be naked
|
|
unsigned regs; // mask of registers modified
|
|
|
|
AsmStatement(Loc loc, Token *tokens);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int blockExit();
|
|
int comeFrom();
|
|
|
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
|
virtual AsmStatement *isAsmStatement() { return this; }
|
|
|
|
void toIR(IRState *irs);
|
|
|
|
// LDC
|
|
// non-zero if this is a branch, contains the target labels identifier
|
|
Identifier* isBranchToLabel;
|
|
|
|
virtual void toNakedIR(IRState *irs);
|
|
};
|
|
|
|
struct AsmBlockStatement : CompoundStatement
|
|
{
|
|
EnclosingHandler* enclosinghandler;
|
|
TryFinallyStatement* tf;
|
|
|
|
AsmBlockStatement(Loc loc, Statements *s);
|
|
Statements *flatten(Scope *sc);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
CompoundStatement *isCompoundStatement() { return NULL; }
|
|
AsmBlockStatement *isAsmBlockStatement() { return this; }
|
|
|
|
void toIR(IRState *irs);
|
|
virtual void toNakedIR(IRState *irs);
|
|
AsmBlockStatement* endsWithAsm();
|
|
|
|
llvm::Value* abiret;
|
|
};
|
|
|
|
#endif /* DMD_STATEMENT_H */
|