Mercurial > hg > CbC > CbC_gcc
diff gcc/d/dmd/statement.h @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/d/dmd/statement.h Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,783 @@ + +/* Compiler implementation of the D programming language + * Copyright (C) 1999-2019 by The D Language Foundation, 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/dlang/dmd/blob/master/src/dmd/statement.h + */ + +#pragma once + +#include "root/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; +class StaticForeach; + +// Back end +struct code; + +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; + + Statement(Loc loc); + virtual Statement *syntaxCopy(); + + void print(); + const char *toChars(); + + void error(const char *format, ...); + void warning(const char *format, ...); + void deprecation(const char *format, ...); + virtual Statement *getRelatedLabeled() { return this; } + virtual bool hasBreak(); + virtual bool hasContinue(); + bool usesEH(); + 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 GotoDefaultStatement *isGotoDefaultStatement() { return NULL; } + virtual GotoCaseStatement *isGotoCaseStatement() { return NULL; } + virtual BreakStatement *isBreakStatement() { return NULL; } + virtual DtorExpStatement *isDtorExpStatement() { return NULL; } + virtual ForwardingStatement *isForwardingStatement() { return NULL; } + virtual void accept(Visitor *v) { v->visit(this); } +}; + +/** 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(); + + ErrorStatement *isErrorStatement() { return this; } + void accept(Visitor *v) { v->visit(this); } +}; + +class PeelStatement : public Statement +{ +public: + Statement *s; + + PeelStatement(Statement *s); + 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 *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); + Statements *flatten(Scope *sc); + + 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); + 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(); + Statements *flatten(Scope *sc); + ReturnStatement *isReturnStatement(); + Statement *last(); + + CompoundStatement *isCompoundStatement() { return this; } + void accept(Visitor *v) { v->visit(this); } +}; + +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(); + bool hasBreak(); + bool hasContinue(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class ScopeStatement : public Statement +{ +public: + Statement *statement; + Loc endloc; // location of closing curly bracket + + ScopeStatement(Loc loc, Statement *s, Loc endloc); + Statement *syntaxCopy(); + ScopeStatement *isScopeStatement() { return this; } + ReturnStatement *isReturnStatement(); + bool hasBreak(); + bool hasContinue(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class ForwardingStatement : public Statement +{ + ForwardingScopeDsymbol *sym; + Statement *statement; + + Statement *syntaxCopy(); + Statement *getRelatedLabeled(); + bool hasBreak(); + bool hasContinue(); + Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally); + Statement *last(); + Statements *flatten(Scope *sc); + ForwardingStatement *isForwardingStatement() { return this; } + 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(); + bool hasBreak(); + bool hasContinue(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class DoStatement : public Statement +{ +public: + Statement *_body; + Expression *condition; + Loc endloc; // location of ';' after while + + DoStatement(Loc loc, Statement *b, Expression *c, Loc endloc); + Statement *syntaxCopy(); + 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 *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(); + 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(); + bool hasBreak(); + bool hasContinue(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class IfStatement : public Statement +{ +public: + Parameter *prm; + Expression *condition; + Statement *ifbody; + Statement *elsebody; + Loc endloc; // location of closing curly bracket + + VarDeclaration *match; // for MatchExpression results + + IfStatement(Loc loc, Parameter *prm, Expression *condition, Statement *ifbody, Statement *elsebody, Loc endloc); + Statement *syntaxCopy(); + 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(); + Statements *flatten(Scope *sc); + + void accept(Visitor *v) { v->visit(this); } +}; + +class StaticForeachStatement : public Statement +{ +public: + StaticForeach *sfe; + + Statement *syntaxCopy(); + 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(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class StaticAssertStatement : public Statement +{ +public: + StaticAssert *sa; + + StaticAssertStatement(StaticAssert *sa); + Statement *syntaxCopy(); + + 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 + VarDeclaration *lastVar; + + SwitchStatement(Loc loc, Expression *c, Statement *b, bool isFinal); + Statement *syntaxCopy(); + bool hasBreak(); + bool checkLabel(); + + 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) + VarDeclaration *lastVar; + + CaseStatement(Loc loc, Expression *exp, Statement *s); + Statement *syntaxCopy(); + int compare(RootObject *obj); + CaseStatement *isCaseStatement() { return this; } + + void accept(Visitor *v) { v->visit(this); } +}; + + +class CaseRangeStatement : public Statement +{ +public: + Expression *first; + Expression *last; + Statement *statement; + + CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s); + Statement *syntaxCopy(); + void accept(Visitor *v) { v->visit(this); } +}; + + +class DefaultStatement : public Statement +{ +public: + Statement *statement; + VarDeclaration *lastVar; + + DefaultStatement(Loc loc, Statement *s); + Statement *syntaxCopy(); + DefaultStatement *isDefaultStatement() { return this; } + + void accept(Visitor *v) { v->visit(this); } +}; + +class GotoDefaultStatement : public Statement +{ +public: + SwitchStatement *sw; + + GotoDefaultStatement(Loc loc); + Statement *syntaxCopy(); + GotoDefaultStatement *isGotoDefaultStatement() { return this; } + + 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 + + GotoCaseStatement(Loc loc, Expression *exp); + Statement *syntaxCopy(); + GotoCaseStatement *isGotoCaseStatement() { return this; } + + 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(); + + 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(); + + BreakStatement *isBreakStatement() { return this; } + void accept(Visitor *v) { v->visit(this); } +}; + +class ContinueStatement : public Statement +{ +public: + Identifier *ident; + + ContinueStatement(Loc loc, Identifier *ident); + Statement *syntaxCopy(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class SynchronizedStatement : public Statement +{ +public: + Expression *exp; + Statement *_body; + + SynchronizedStatement(Loc loc, Expression *exp, Statement *body); + Statement *syntaxCopy(); + bool hasBreak(); + bool hasContinue(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class WithStatement : public Statement +{ +public: + Expression *exp; + Statement *_body; + VarDeclaration *wthis; + Loc endloc; + + WithStatement(Loc loc, Expression *exp, Statement *body, Loc endloc); + Statement *syntaxCopy(); + + 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(); + bool hasBreak(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class Catch : public RootObject +{ +public: + Loc loc; + Type *type; + Identifier *ident; + VarDeclaration *var; + Statement *handler; + + // set if semantic processing errors + bool errors; + + // was generated by the compiler, + // wasn't present in source code + bool internalCatch; + + Catch(Loc loc, Type *t, Identifier *id, Statement *handler); + Catch *syntaxCopy(); +}; + +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(); + 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 *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(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class DebugStatement : public Statement +{ +public: + Statement *statement; + + DebugStatement(Loc loc, Statement *statement); + Statement *syntaxCopy(); + Statements *flatten(Scope *sc); + void accept(Visitor *v) { v->visit(this); } +}; + +class GotoStatement : public Statement +{ +public: + Identifier *ident; + LabelDsymbol *label; + TryFinallyStatement *tf; + OnScopeStatement *os; + VarDeclaration *lastVar; + + GotoStatement(Loc loc, Identifier *ident); + Statement *syntaxCopy(); + bool checkLabel(); + + void accept(Visitor *v) { v->visit(this); } +}; + +class LabelStatement : public Statement +{ +public: + Identifier *ident; + Statement *statement; + TryFinallyStatement *tf; + OnScopeStatement *os; + VarDeclaration *lastVar; + Statement *gotoTarget; // interpret + + bool breaks; // someone did a 'break ident' + + LabelStatement(Loc loc, Identifier *ident, Statement *statement); + Statement *syntaxCopy(); + 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; + + AsmStatement(Loc loc, Token *tokens); + Statement *syntaxCopy(); + void accept(Visitor *v) { v->visit(this); } +}; + +class InlineAsmStatement : public AsmStatement +{ +public: + 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 + + InlineAsmStatement(Loc loc, Token *tokens); + Statement *syntaxCopy(); + void accept(Visitor *v) { v->visit(this); } +}; + +// A GCC asm statement - assembler instructions with D expression operands +class GccAsmStatement : public AsmStatement +{ +public: + StorageClass stc; // attributes of the asm {} block + Expression *insn; // string expression that is the template for assembler code + Expressions *args; // input and output operands of the statement + unsigned outputargs; // of the operands in 'args', the number of output operands + Identifiers *names; // list of symbolic names for the operands + Expressions *constraints; // list of string constants specifying constraints on operands + Expressions *clobbers; // list of string constants specifying clobbers and scratch registers + Identifiers *labels; // list of goto labels + GotoStatements *gotos; // of the goto labels, the equivalent statements they represent + + GccAsmStatement(Loc loc, Token *tokens); + Statement *syntaxCopy(); + void accept(Visitor *v) { v->visit(this); } +}; + +// a complete asm {} block +class CompoundAsmStatement : public CompoundStatement +{ +public: + StorageClass stc; // postfix attributes like nothrow/pure/@trusted + + CompoundAsmStatement(Loc loc, Statements *s, StorageClass stc); + CompoundAsmStatement *syntaxCopy(); + Statements *flatten(Scope *sc); + + void accept(Visitor *v) { v->visit(this); } +}; + +class ImportStatement : public Statement +{ +public: + Dsymbols *imports; // Array of Import's + + ImportStatement(Loc loc, Dsymbols *imports); + Statement *syntaxCopy(); + + void accept(Visitor *v) { v->visit(this); } +};