mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 02:45:25 +03:00
856 lines
21 KiB
C++
856 lines
21 KiB
C++
|
|
/* Compiler implementation of the D programming language
|
|
* Copyright (c) 1999-2014 by Digital Mars
|
|
* All Rights Reserved
|
|
* written by Walter Bright
|
|
* http://www.digitalmars.com
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* http://www.boost.org/LICENSE_1_0.txt
|
|
* https://github.com/D-Programming-Language/dmd/blob/master/src/statement.h
|
|
*/
|
|
|
|
#ifndef DMD_STATEMENT_H
|
|
#define DMD_STATEMENT_H
|
|
|
|
#ifdef __DMC__
|
|
#pragma once
|
|
#endif /* __DMC__ */
|
|
|
|
#include "root.h"
|
|
|
|
#include "arraytypes.h"
|
|
#include "dsymbol.h"
|
|
#include "visitor.h"
|
|
#include "tokens.h"
|
|
|
|
struct OutBuffer;
|
|
struct Scope;
|
|
class Expression;
|
|
class LabelDsymbol;
|
|
class Identifier;
|
|
class IfStatement;
|
|
class ExpStatement;
|
|
class DefaultStatement;
|
|
class VarDeclaration;
|
|
class Condition;
|
|
class Module;
|
|
struct Token;
|
|
class ErrorStatement;
|
|
class ReturnStatement;
|
|
class CompoundStatement;
|
|
class Parameter;
|
|
class StaticAssert;
|
|
class AsmStatement;
|
|
class GotoStatement;
|
|
class ScopeStatement;
|
|
class TryCatchStatement;
|
|
class TryFinallyStatement;
|
|
class CaseStatement;
|
|
class DefaultStatement;
|
|
class LabelStatement;
|
|
#if IN_LLVM
|
|
class CaseStatement;
|
|
class LabelStatement;
|
|
class SynchronizedStatement;
|
|
#endif
|
|
|
|
#if IN_LLVM
|
|
namespace llvm
|
|
{
|
|
class Value;
|
|
class BasicBlock;
|
|
class ConstantInt;
|
|
}
|
|
#endif
|
|
|
|
// Back end
|
|
|
|
#ifdef IN_GCC
|
|
typedef union tree_node block;
|
|
#elif IN_LLVM
|
|
class DValue;
|
|
typedef DValue elem;
|
|
struct AsmCode;
|
|
typedef AsmCode code;
|
|
#else
|
|
struct block;
|
|
struct code;
|
|
#endif
|
|
|
|
bool inferAggregate(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);
|
|
bool inferApplyArgTypes(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);
|
|
|
|
/* How a statement exits; this is returned by blockExit()
|
|
*/
|
|
enum BE
|
|
{
|
|
BEnone = 0,
|
|
BEfallthru = 1,
|
|
BEthrow = 2,
|
|
BEreturn = 4,
|
|
BEgoto = 8,
|
|
BEhalt = 0x10,
|
|
BEbreak = 0x20,
|
|
BEcontinue = 0x40,
|
|
BEerrthrow = 0x80,
|
|
BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt),
|
|
};
|
|
|
|
class Statement : public RootObject
|
|
{
|
|
public:
|
|
Loc loc;
|
|
virtual ~Statement() {}
|
|
|
|
Statement(Loc loc);
|
|
virtual Statement *syntaxCopy();
|
|
|
|
void print();
|
|
char *toChars();
|
|
|
|
void error(const char *format, ...);
|
|
void warning(const char *format, ...);
|
|
void deprecation(const char *format, ...);
|
|
virtual Statement *semantic(Scope *sc);
|
|
Statement *semanticScope(Scope *sc, Statement *sbreak, Statement *scontinue);
|
|
Statement *semanticNoScope(Scope *sc);
|
|
virtual Statement *getRelatedLabeled() { return this; }
|
|
virtual bool hasBreak();
|
|
virtual bool hasContinue();
|
|
bool usesEH();
|
|
int blockExit(FuncDeclaration *func, bool mustNotThrow);
|
|
bool comeFrom();
|
|
bool hasCode();
|
|
virtual Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
virtual Statements *flatten(Scope *sc);
|
|
virtual Statement *last();
|
|
|
|
// Avoid dynamic_cast
|
|
virtual ErrorStatement *isErrorStatement() { return NULL; }
|
|
virtual ScopeStatement *isScopeStatement() { return NULL; }
|
|
virtual ExpStatement *isExpStatement() { return NULL; }
|
|
virtual CompoundStatement *isCompoundStatement() { return NULL; }
|
|
virtual ReturnStatement *isReturnStatement() { return NULL; }
|
|
virtual IfStatement *isIfStatement() { return NULL; }
|
|
virtual CaseStatement *isCaseStatement() { return NULL; }
|
|
virtual DefaultStatement *isDefaultStatement() { return NULL; }
|
|
virtual LabelStatement *isLabelStatement() { return NULL; }
|
|
virtual DtorExpStatement *isDtorExpStatement() { return NULL; }
|
|
virtual void accept(Visitor *v) { v->visit(this); }
|
|
|
|
#if IN_LLVM
|
|
virtual CompoundAsmStatement *isCompoundAsmBlockStatement() { return NULL; }
|
|
virtual CompoundAsmStatement* endsWithAsm();
|
|
#endif
|
|
};
|
|
|
|
/** Any Statement that fails semantic() or has a component that is an ErrorExp or
|
|
* a TypeError should return an ErrorStatement from semantic().
|
|
*/
|
|
class ErrorStatement : public Statement
|
|
{
|
|
public:
|
|
ErrorStatement();
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
ErrorStatement *isErrorStatement() { return this; }
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class PeelStatement : public Statement
|
|
{
|
|
public:
|
|
Statement *s;
|
|
|
|
PeelStatement(Statement *s);
|
|
Statement *semantic(Scope *sc);
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class ExpStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *exp;
|
|
|
|
ExpStatement(Loc loc, Expression *exp);
|
|
ExpStatement(Loc loc, Dsymbol *s);
|
|
static ExpStatement *create(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
|
|
ExpStatement *isExpStatement() { return this; }
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class DtorExpStatement : public ExpStatement
|
|
{
|
|
public:
|
|
/* Wraps an expression that is the destruction of 'var'
|
|
*/
|
|
|
|
VarDeclaration *var;
|
|
|
|
DtorExpStatement(Loc loc, Expression *exp, VarDeclaration *v);
|
|
Statement *syntaxCopy();
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
|
|
DtorExpStatement *isDtorExpStatement() { return this; }
|
|
};
|
|
|
|
class CompileStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *exp;
|
|
|
|
CompileStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
Statements *flatten(Scope *sc);
|
|
Statement *semantic(Scope *sc);
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class CompoundStatement : public Statement
|
|
{
|
|
public:
|
|
Statements *statements;
|
|
|
|
CompoundStatement(Loc loc, Statements *s);
|
|
CompoundStatement(Loc loc, Statement *s1);
|
|
CompoundStatement(Loc loc, Statement *s1, Statement *s2);
|
|
static CompoundStatement *create(Loc loc, Statement *s1, Statement *s2);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statements *flatten(Scope *sc);
|
|
ReturnStatement *isReturnStatement();
|
|
Statement *last();
|
|
|
|
CompoundStatement *isCompoundStatement() { return this; }
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
|
|
#if IN_LLVM
|
|
virtual CompoundAsmStatement* endsWithAsm();
|
|
#endif
|
|
};
|
|
|
|
class CompoundDeclarationStatement : public CompoundStatement
|
|
{
|
|
public:
|
|
CompoundDeclarationStatement(Loc loc, Statements *s);
|
|
Statement *syntaxCopy();
|
|
void accept(Visitor *v) { v->visit(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.
|
|
*/
|
|
class UnrolledLoopStatement : public Statement
|
|
{
|
|
public:
|
|
Statements *statements;
|
|
|
|
UnrolledLoopStatement(Loc loc, Statements *statements);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class ScopeStatement : public Statement
|
|
{
|
|
public:
|
|
Statement *statement;
|
|
|
|
ScopeStatement(Loc loc, Statement *s);
|
|
Statement *syntaxCopy();
|
|
ScopeStatement *isScopeStatement() { return this; }
|
|
ReturnStatement *isReturnStatement();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class WhileStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *condition;
|
|
Statement *body;
|
|
Loc endloc; // location of closing curly bracket
|
|
|
|
WhileStatement(Loc loc, Expression *c, Statement *b, Loc endloc);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class DoStatement : public Statement
|
|
{
|
|
public:
|
|
Statement *body;
|
|
Expression *condition;
|
|
|
|
DoStatement(Loc loc, Statement *b, Expression *c);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class ForStatement : public Statement
|
|
{
|
|
public:
|
|
Statement *init;
|
|
Expression *condition;
|
|
Expression *increment;
|
|
Statement *body;
|
|
Loc endloc; // location of closing curly bracket
|
|
|
|
// When wrapped in try/finally clauses, this points to the outermost one,
|
|
// which may have an associated label. Internal break/continue statements
|
|
// treat that label as referring to this loop.
|
|
Statement *relatedLabeled;
|
|
|
|
ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body, Loc endloc);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; }
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class ForeachStatement : public Statement
|
|
{
|
|
public:
|
|
TOK op; // TOKforeach or TOKforeach_reverse
|
|
Parameters *parameters; // array of Parameter*'s
|
|
Expression *aggr;
|
|
Statement *body;
|
|
Loc endloc; // location of closing curly bracket
|
|
|
|
VarDeclaration *key;
|
|
VarDeclaration *value;
|
|
|
|
FuncDeclaration *func; // function we're lexically in
|
|
|
|
Statements *cases; // put breaks, continues, gotos and returns here
|
|
ScopeStatements *gotos; // forward referenced goto's go here
|
|
|
|
ForeachStatement(Loc loc, TOK op, Parameters *parameters, Expression *aggr, Statement *body, Loc endloc);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool checkForArgTypes();
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class ForeachRangeStatement : public Statement
|
|
{
|
|
public:
|
|
TOK op; // TOKforeach or TOKforeach_reverse
|
|
Parameter *prm; // loop index variable
|
|
Expression *lwr;
|
|
Expression *upr;
|
|
Statement *body;
|
|
Loc endloc; // location of closing curly bracket
|
|
|
|
VarDeclaration *key;
|
|
|
|
ForeachRangeStatement(Loc loc, TOK op, Parameter *prm,
|
|
Expression *lwr, Expression *upr, Statement *body, Loc endloc);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class IfStatement : public Statement
|
|
{
|
|
public:
|
|
Parameter *prm;
|
|
Expression *condition;
|
|
Statement *ifbody;
|
|
Statement *elsebody;
|
|
|
|
VarDeclaration *match; // for MatchExpression results
|
|
|
|
IfStatement(Loc loc, Parameter *prm, Expression *condition, Statement *ifbody, Statement *elsebody);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
IfStatement *isIfStatement() { return this; }
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class ConditionalStatement : public Statement
|
|
{
|
|
public:
|
|
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);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class PragmaStatement : public Statement
|
|
{
|
|
public:
|
|
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);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class StaticAssertStatement : public Statement
|
|
{
|
|
public:
|
|
StaticAssert *sa;
|
|
|
|
StaticAssertStatement(StaticAssert *sa);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class SwitchStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *condition;
|
|
Statement *body;
|
|
bool isFinal;
|
|
|
|
DefaultStatement *sdefault;
|
|
TryFinallyStatement *tf;
|
|
GotoCaseStatements gotoCases; // array of unresolved GotoCaseStatement's
|
|
CaseStatements *cases; // array of CaseStatement's
|
|
int hasNoDefault; // !=0 if no default statement
|
|
int hasVars; // !=0 if has variable case values
|
|
|
|
#if IN_LLVM
|
|
Statement *enclosingScopeExit;
|
|
#endif
|
|
|
|
SwitchStatement(Loc loc, Expression *c, Statement *b, bool isFinal);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class CaseStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *exp;
|
|
Statement *statement;
|
|
|
|
int index; // which case it is (since we sort this)
|
|
block *cblock; // back end: label for the block
|
|
|
|
#if IN_LLVM
|
|
Statement *enclosingScopeExit;
|
|
#endif
|
|
|
|
CaseStatement(Loc loc, Expression *exp, Statement *s);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
int compare(RootObject *obj);
|
|
CaseStatement *isCaseStatement() { return this; }
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
|
|
#if IN_LLVM
|
|
llvm::BasicBlock* bodyBB;
|
|
llvm::Value* llvmIdx;
|
|
#endif
|
|
};
|
|
|
|
|
|
class CaseRangeStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *first;
|
|
Expression *last;
|
|
Statement *statement;
|
|
|
|
CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
|
|
class DefaultStatement : public Statement
|
|
{
|
|
public:
|
|
Statement *statement;
|
|
#ifdef IN_GCC
|
|
block *cblock; // back end: label for the block
|
|
#endif
|
|
|
|
#if IN_LLVM
|
|
Statement *enclosingScopeExit;
|
|
#endif
|
|
|
|
DefaultStatement(Loc loc, Statement *s);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
DefaultStatement *isDefaultStatement() { return this; }
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
|
|
#if IN_LLVM
|
|
llvm::BasicBlock* bodyBB;
|
|
#endif
|
|
};
|
|
|
|
class GotoDefaultStatement : public Statement
|
|
{
|
|
public:
|
|
SwitchStatement *sw;
|
|
|
|
GotoDefaultStatement(Loc loc);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class GotoCaseStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *exp; // NULL, or which case to goto
|
|
CaseStatement *cs; // case statement it resolves to
|
|
SwitchStatement *sw;
|
|
|
|
GotoCaseStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class SwitchErrorStatement : public Statement
|
|
{
|
|
public:
|
|
SwitchErrorStatement(Loc loc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class ReturnStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *exp;
|
|
size_t caseDim;
|
|
|
|
ReturnStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
ReturnStatement *isReturnStatement() { return this; }
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class BreakStatement : public Statement
|
|
{
|
|
public:
|
|
Identifier *ident;
|
|
|
|
BreakStatement(Loc loc, Identifier *ident);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
|
|
#if IN_LLVM
|
|
// LDC: only set if ident is set: label statement to jump to
|
|
LabelStatement *target;
|
|
#endif
|
|
};
|
|
|
|
class ContinueStatement : public Statement
|
|
{
|
|
public:
|
|
Identifier *ident;
|
|
|
|
ContinueStatement(Loc loc, Identifier *ident);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
|
|
#if IN_LLVM
|
|
// LDC: only set if ident is set: label statement to jump to
|
|
LabelStatement *target;
|
|
#endif
|
|
};
|
|
|
|
class SynchronizedStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *exp;
|
|
Statement *body;
|
|
|
|
SynchronizedStatement(Loc loc, Expression *exp, Statement *body);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class WithStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *exp;
|
|
Statement *body;
|
|
VarDeclaration *wthis;
|
|
|
|
WithStatement(Loc loc, Expression *exp, Statement *body);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class TryCatchStatement : public Statement
|
|
{
|
|
public:
|
|
Statement *body;
|
|
Catches *catches;
|
|
|
|
TryCatchStatement(Loc loc, Statement *body, Catches *catches);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class Catch : public RootObject
|
|
{
|
|
public:
|
|
Loc loc;
|
|
Type *type;
|
|
Identifier *ident;
|
|
VarDeclaration *var;
|
|
Statement *handler;
|
|
// was generated by the compiler,
|
|
// wasn't present in source code
|
|
bool internalCatch;
|
|
|
|
Catch(Loc loc, Type *t, Identifier *id, Statement *handler);
|
|
Catch *syntaxCopy();
|
|
void semantic(Scope *sc);
|
|
};
|
|
|
|
class TryFinallyStatement : public Statement
|
|
{
|
|
public:
|
|
Statement *body;
|
|
Statement *finalbody;
|
|
|
|
TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody);
|
|
static TryFinallyStatement *create(Loc loc, Statement *body, Statement *finalbody);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool hasBreak();
|
|
bool hasContinue();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class OnScopeStatement : public Statement
|
|
{
|
|
public:
|
|
TOK tok;
|
|
Statement *statement;
|
|
|
|
OnScopeStatement(Loc loc, TOK tok, Statement *statement);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class ThrowStatement : public Statement
|
|
{
|
|
public:
|
|
Expression *exp;
|
|
// was generated by the compiler,
|
|
// wasn't present in source code
|
|
bool internalThrow;
|
|
|
|
ThrowStatement(Loc loc, Expression *exp);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class DebugStatement : public Statement
|
|
{
|
|
public:
|
|
Statement *statement;
|
|
|
|
DebugStatement(Loc loc, Statement *statement);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statements *flatten(Scope *sc);
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class GotoStatement : public Statement
|
|
{
|
|
public:
|
|
Identifier *ident;
|
|
LabelDsymbol *label;
|
|
TryFinallyStatement *tf;
|
|
OnScopeStatement *os;
|
|
#if IN_LLVM
|
|
Statement* enclosingScopeExit;
|
|
#endif
|
|
VarDeclaration *lastVar;
|
|
|
|
GotoStatement(Loc loc, Identifier *ident);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
bool checkLabel();
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class LabelStatement : public Statement
|
|
{
|
|
public:
|
|
Identifier *ident;
|
|
Statement *statement;
|
|
TryFinallyStatement *tf;
|
|
OnScopeStatement *os;
|
|
#if IN_LLVM
|
|
Statement* enclosingScopeExit;
|
|
#endif
|
|
VarDeclaration *lastVar;
|
|
Statement *gotoTarget; // interpret
|
|
|
|
bool breaks; // someone did a 'break ident'
|
|
block *lblock; // back end
|
|
Blocks *fwdrefs; // forward references to this LabelStatement
|
|
|
|
LabelStatement(Loc loc, Identifier *ident, Statement *statement);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
Statements *flatten(Scope *sc);
|
|
Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
|
|
|
|
LabelStatement *isLabelStatement() { return this; }
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
class LabelDsymbol : public Dsymbol
|
|
{
|
|
public:
|
|
LabelStatement *statement;
|
|
|
|
LabelDsymbol(Identifier *ident);
|
|
static LabelDsymbol *create(Identifier *ident);
|
|
LabelDsymbol *isLabel();
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
Statement* asmSemantic(AsmStatement *s, Scope *sc);
|
|
|
|
class AsmStatement : public Statement
|
|
{
|
|
public:
|
|
Token *tokens;
|
|
code *asmcode;
|
|
unsigned asmalign; // alignment of this statement
|
|
unsigned regs; // mask of registers modified (must match regm_t in back end)
|
|
bool refparam; // true if function parameter is referenced
|
|
bool naked; // true if function is to be naked
|
|
|
|
AsmStatement(Loc loc, Token *tokens);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc)
|
|
{
|
|
return asmSemantic(this, sc);
|
|
}
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
|
|
#if IN_LLVM
|
|
// non-zero if this is a branch, contains the target label
|
|
LabelDsymbol* isBranchToLabel;
|
|
#endif
|
|
};
|
|
|
|
// a complete asm {} block
|
|
class CompoundAsmStatement : public CompoundStatement
|
|
{
|
|
public:
|
|
StorageClass stc; // postfix attributes like nothrow/pure/@trusted
|
|
#if IN_LLVM
|
|
TryFinallyStatement* enclosingFinally;
|
|
Statement* enclosingScopeExit;
|
|
#endif
|
|
|
|
CompoundAsmStatement(Loc loc, Statements *s, StorageClass stc);
|
|
CompoundAsmStatement *syntaxCopy();
|
|
CompoundAsmStatement *semantic(Scope *sc);
|
|
Statements *flatten(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
#if IN_LLVM
|
|
CompoundStatement *isCompoundStatement() { return NULL; }
|
|
CompoundAsmStatement *isCompoundAsmBlockStatement() { return this; }
|
|
|
|
CompoundAsmStatement* endsWithAsm();
|
|
llvm::Value* abiret;
|
|
#endif
|
|
};
|
|
|
|
class ImportStatement : public Statement
|
|
{
|
|
public:
|
|
Dsymbols *imports; // Array of Import's
|
|
|
|
ImportStatement(Loc loc, Dsymbols *imports);
|
|
Statement *syntaxCopy();
|
|
Statement *semantic(Scope *sc);
|
|
|
|
void accept(Visitor *v) { v->visit(this); }
|
|
};
|
|
|
|
#endif /* DMD_STATEMENT_H */
|