source: src/AST/Stmt.hpp @ 3d9d017

Last change on this file since 3d9d017 was 3d9d017, checked in by caparson <caparson@…>, 8 months ago

added cofor implementation

  • Property mode set to 100644
File size: 18.6 KB
RevLine 
[2bb4a01]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Stmt.hpp --
8//
9// Author           : Aaron B. Moss
[1e97287]10// Created On       : Wed May  8 13:00:00 2019
[400b8be]11// Last Modified By : Andrew Beach
[3e94a23]12// Last Modified On : Wed Apr  5 10:34:00 2023
13// Update Count     : 37
[2bb4a01]14//
15
16#pragma once
17
18#include <list>
[89a5a1f]19#include <utility>                                                                              // for move
[2bb4a01]20#include <vector>
21
22#include "Label.hpp"
[89a5a1f]23#include "Node.hpp"                                                                             // for node, ptr
[2bb4a01]24#include "ParseNode.hpp"
25#include "Visitor.hpp"
26#include "Common/CodeLocation.h"
27
[f3cc5b6]28// Must be included in *all* AST classes; should be #undef'd at the end of the file
[89a5a1f]29#define MUTATE_FRIEND                                                                                                   \
[a1da039]30        template<typename node_t> friend node_t * mutate(const node_t * node); \
[99da267]31        template<typename node_t> friend node_t * shallowCopy(const node_t * node);
[f3cc5b6]32
[2bb4a01]33namespace ast {
34class Expr;
35
[89a5a1f]36// Base statement node
[2bb4a01]37class Stmt : public ParseNode {
[89a5a1f]38  public:
[2bb4a01]39        std::vector<Label> labels;
40
[6180274]41        Stmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
[89a5a1f]42                : ParseNode(loc), labels(std::move(labels)) {}
[2bb4a01]43
[3b0bc16]44        Stmt(const Stmt & o) : ParseNode(o), labels(o.labels) {}
[2bb4a01]45
[f3cc5b6]46        const Stmt * accept( Visitor & v ) const override = 0;
[89a5a1f]47  private:
[f3cc5b6]48        Stmt * clone() const override = 0;
49        MUTATE_FRIEND
[2bb4a01]50};
51
[400b8be]52// Base statement component node (only serves to group them).
53class StmtClause : public ParseNode {
54  public:
55        // This is for non-statements that still belong with the statements,
56        // but are not statements, usually some sort of clause. Often these can
57        // (and should) be folded into the approprate parent node, but if they
58        // cannot be, they are sub-types of this type, for organization.
59
[491bb81]60        StmtClause( const CodeLocation & loc )
[400b8be]61                : ParseNode(loc) {}
62
63  private:
64        StmtClause * clone() const override = 0;
65        MUTATE_FRIEND
66};
67
[89a5a1f]68// Compound statement: { ... }
[2bb4a01]69class CompoundStmt final : public Stmt {
[89a5a1f]70  public:
[2bb4a01]71        std::list<ptr<Stmt>> kids;
72
[6180274]73        CompoundStmt(const CodeLocation & loc, const std::list<ptr<Stmt>> && ks = {}, const std::vector<Label> && labels = {} )
[89a5a1f]74                : Stmt(loc, std::move(labels)), kids(std::move(ks)) {}
[2bb4a01]75
[3b0bc16]76        CompoundStmt( const CompoundStmt & o );
77        CompoundStmt( CompoundStmt && o ) = default;
[2bb4a01]78
[b8524ca]79        void push_back( const Stmt * s ) { kids.emplace_back( s ); }
80        void push_front( const Stmt * s ) { kids.emplace_front( s ); }
[2bb4a01]81
[f3cc5b6]82        const CompoundStmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]83  private:
[f3cc5b6]84        CompoundStmt * clone() const override { return new CompoundStmt{ *this }; }
85        MUTATE_FRIEND
[2bb4a01]86};
87
[89a5a1f]88// Empty statment: ;
[2bb4a01]89class NullStmt final : public Stmt {
[89a5a1f]90  public:
[6180274]91        NullStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
[89a5a1f]92                : Stmt(loc, std::move(labels)) {}
[2bb4a01]93
[f3cc5b6]94        const NullStmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]95  private:
[f3cc5b6]96        NullStmt * clone() const override { return new NullStmt{ *this }; }
97        MUTATE_FRIEND
[2bb4a01]98};
99
[89a5a1f]100// Expression wrapped by statement
[2bb4a01]101class ExprStmt final : public Stmt {
[89a5a1f]102  public:
[2bb4a01]103        ptr<Expr> expr;
104
[6180274]105        ExprStmt( const CodeLocation & loc, const Expr* e, const std::vector<Label> && labels = {} )
[89a5a1f]106                : Stmt(loc, std::move(labels)), expr(e) {}
[2bb4a01]107
[f3cc5b6]108        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]109  private:
[23f99e1]110        ExprStmt * clone() const override { return new ExprStmt{ *this }; }
[f3cc5b6]111        MUTATE_FRIEND
[2bb4a01]112};
113
[89a5a1f]114// Assembly statement: asm ... ( "..." : ... )
[1e97287]115class AsmStmt final : public Stmt {
[89a5a1f]116  public:
[1e97287]117        bool isVolatile;
118        ptr<Expr> instruction;
119        std::vector<ptr<Expr>> output, input;
120        std::vector<ptr<ConstantExpr>> clobber;
121        std::vector<Label> gotoLabels;
122
[f3cc5b6]123        AsmStmt( const CodeLocation & loc, bool isVolatile, const Expr * instruction,
[6180274]124                         const std::vector<ptr<Expr>> && output, const std::vector<ptr<Expr>> && input,
125                         const std::vector<ptr<ConstantExpr>> && clobber, const std::vector<Label> && gotoLabels,
126                         const std::vector<Label> && labels = {})
[89a5a1f]127                : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction),
128                  output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)),
129                  gotoLabels(std::move(gotoLabels)) {}
[1e97287]130
[f3cc5b6]131        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]132  private:
[f3cc5b6]133        AsmStmt * clone() const override { return new AsmStmt{ *this }; }
134        MUTATE_FRIEND
[1e97287]135};
136
[89a5a1f]137// C-preprocessor directive: #...
[1e97287]138class DirectiveStmt final : public Stmt {
[89a5a1f]139  public:
[1e97287]140        std::string directive;
141
[f3cc5b6]142        DirectiveStmt( const CodeLocation & loc, const std::string & directive,
[89a5a1f]143                                   std::vector<Label> && labels = {} )
144                : Stmt(loc, std::move(labels)), directive(directive) {}
[1e97287]145
[f3cc5b6]146        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]147  private:
[f3cc5b6]148        DirectiveStmt * clone() const override { return new DirectiveStmt{ *this }; }
149        MUTATE_FRIEND
[1e97287]150};
151
[89a5a1f]152// If statement: if (...) ... else ...
[1e97287]153class IfStmt final : public Stmt {
[89a5a1f]154  public:
[1e97287]155        ptr<Expr> cond;
[3b0bc16]156        ptr<Stmt> then;
157        ptr<Stmt> else_;
[1e97287]158        std::vector<ptr<Stmt>> inits;
159
[3b0bc16]160        IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * then,
[6180274]161                        const Stmt * else_ = nullptr, const std::vector<ptr<Stmt>> && inits = {},
162                        const std::vector<Label> && labels = {} )
[3b0bc16]163                : Stmt(loc, std::move(labels)), cond(cond), then(then), else_(else_),
[89a5a1f]164                  inits(std::move(inits)) {}
[1e97287]165
[f3cc5b6]166        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]167  private:
[f3cc5b6]168        IfStmt * clone() const override { return new IfStmt{ *this }; }
169        MUTATE_FRIEND
[1e97287]170};
171
[89a5a1f]172// Switch or choose statement: switch (...) { ... }
[1e97287]173class SwitchStmt final : public Stmt {
[89a5a1f]174  public:
[1e97287]175        ptr<Expr> cond;
[400b8be]176        std::vector<ptr<CaseClause>> cases;
[1e97287]177
[400b8be]178        SwitchStmt( const CodeLocation & loc, const Expr * cond,
179                                const std::vector<ptr<CaseClause>> && cases,
[6180274]180                                const std::vector<Label> && labels = {} )
[400b8be]181                : Stmt(loc, std::move(labels)), cond(cond), cases(std::move(cases)) {}
[1e97287]182
[f3cc5b6]183        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]184  private:
[f3cc5b6]185        SwitchStmt * clone() const override { return new SwitchStmt{ *this }; }
186        MUTATE_FRIEND
[1e97287]187};
188
[89a5a1f]189// Case label: case ...: or default:
[400b8be]190class CaseClause final : public StmtClause {
[89a5a1f]191  public:
192        // Null for the default label.
[1e97287]193        ptr<Expr> cond;
194        std::vector<ptr<Stmt>> stmts;
195
[400b8be]196        CaseClause( const CodeLocation & loc, const Expr * cond, const std::vector<ptr<Stmt>> && stmts )
197                : StmtClause(loc), cond(cond), stmts(std::move(stmts)) {}
[1e97287]198
[675d816]199        bool isDefault() const { return !cond; }
[1e97287]200
[400b8be]201        const CaseClause * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]202  private:
[400b8be]203        CaseClause * clone() const override { return new CaseClause{ *this }; }
[f3cc5b6]204        MUTATE_FRIEND
[1e97287]205};
206
[3e94a23]207// A while loop or a do-while loop:
208enum WhileDoKind { While, DoWhile };
209
[89a5a1f]210// While loop: while (...) ... else ... or do ... while (...) else ...;
[3b0bc16]211class WhileDoStmt final : public Stmt {
[89a5a1f]212  public:
[1e97287]213        ptr<Expr> cond;
214        ptr<Stmt> body;
[3b0bc16]215        ptr<Stmt> else_;
[1e97287]216        std::vector<ptr<Stmt>> inits;
[3e94a23]217        WhileDoKind isDoWhile;
[1e97287]218
[3b0bc16]219        WhileDoStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body,
[3e94a23]220                                 const std::vector<ptr<Stmt>> && inits, WhileDoKind isDoWhile = While, const std::vector<Label> && labels = {} )
[3b0bc16]221                : Stmt(loc, std::move(labels)), cond(cond), body(body), else_(nullptr), inits(std::move(inits)), isDoWhile(isDoWhile) {}
222
223        WhileDoStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, const Stmt * else_,
[3e94a23]224                                 const std::vector<ptr<Stmt>> && inits, WhileDoKind isDoWhile = While, const std::vector<Label> && labels = {} )
[3b0bc16]225                : Stmt(loc, std::move(labels)), cond(cond), body(body), else_(else_), inits(std::move(inits)), isDoWhile(isDoWhile) {}
[1e97287]226
[f3cc5b6]227        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]228  private:
[3b0bc16]229        WhileDoStmt * clone() const override { return new WhileDoStmt{ *this }; }
[f3cc5b6]230        MUTATE_FRIEND
[1e97287]231};
232
[89a5a1f]233// For loop: for (... ; ... ; ...) ... else ...
[1e97287]234class ForStmt final : public Stmt {
[89a5a1f]235  public:
[1e97287]236        std::vector<ptr<Stmt>> inits;
237        ptr<Expr> cond;
[8a5530c]238        ptr<Expr> inc;
[1e97287]239        ptr<Stmt> body;
[3b0bc16]240        ptr<Stmt> else_;
241
[6180274]242        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
243                         const Expr * inc, const Stmt * body, const std::vector<Label> && label = {} )
[3b0bc16]244                : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc), body(body), else_(nullptr) {}
[1e97287]245
[6180274]246        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
247                         const Expr * inc, const Stmt * body, const Stmt * else_, const std::vector<Label> && labels = {} )
[3b0bc16]248                : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), body(body), else_(else_) {}
[1e97287]249
[f3cc5b6]250        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]251  private:
[f3cc5b6]252        ForStmt * clone() const override { return new ForStmt{ *this }; }
253        MUTATE_FRIEND
[1e97287]254};
255
[89a5a1f]256// Branch control flow statement: goto ... or break or continue or fallthru
[1e97287]257class BranchStmt final : public Stmt {
[89a5a1f]258  public:
[1e97287]259        enum Kind { Goto, Break, Continue, FallThrough, FallThroughDefault };
260        static constexpr size_t kindEnd = 1 + (size_t)FallThroughDefault;
261
262        const Label originalTarget;
263        Label target;
264        ptr<Expr> computedTarget;
265        Kind kind;
266
[6180274]267        BranchStmt( const CodeLocation & loc, Kind kind, Label target, const std::vector<Label> && labels = {} );
268        BranchStmt( const CodeLocation & loc, const Expr * computedTarget, const std::vector<Label> && labels = {} )
269                : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc), computedTarget(computedTarget), kind(Goto) {}
[1e97287]270
[94b1f718]271        const char * kindName() const { return kindNames[kind]; }
[1e97287]272
[f3cc5b6]273        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]274  private:
[f3cc5b6]275        BranchStmt * clone() const override { return new BranchStmt{ *this }; }
276        MUTATE_FRIEND
[8a5530c]277
[1e97287]278        static const char * kindNames[kindEnd];
279};
280
[89a5a1f]281// Return statement: return ...
[1e97287]282class ReturnStmt final : public Stmt {
[89a5a1f]283  public:
[1e97287]284        ptr<Expr> expr;
285
[6180274]286        ReturnStmt( const CodeLocation & loc, const Expr * expr, const std::vector<Label> && labels = {} )
[89a5a1f]287                : Stmt(loc, std::move(labels)), expr(expr) {}
[1e97287]288
[f3cc5b6]289        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]290  private:
[f3cc5b6]291        ReturnStmt * clone() const override { return new ReturnStmt{ *this }; }
292        MUTATE_FRIEND
[1e97287]293};
294
[89a5a1f]295// Kind of exception
[6f4b7f2]296enum ExceptionKind { Terminate, Resume };
297
[89a5a1f]298// Throw statement: throw ...
[1e97287]299class ThrowStmt final : public Stmt {
[89a5a1f]300  public:
[1e97287]301        ptr<Expr> expr;
302        ptr<Expr> target;
[6f4b7f2]303        ExceptionKind kind;
[1e97287]304
[6180274]305        ThrowStmt( const CodeLocation & loc, ExceptionKind kind, const Expr * expr,
306                           const Expr * target, const std::vector<Label> && labels = {} )
[89a5a1f]307                : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {}
[1e97287]308
[f3cc5b6]309        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]310  private:
[f3cc5b6]311        ThrowStmt * clone() const override { return new ThrowStmt{ *this }; }
312        MUTATE_FRIEND
[1e97287]313};
314
[89a5a1f]315// Try statement: try { ... } ...
[1e97287]316class TryStmt final : public Stmt {
[89a5a1f]317  public:
[1e97287]318        ptr<CompoundStmt> body;
[400b8be]319        std::vector<ptr<CatchClause>> handlers;
320        ptr<FinallyClause> finally;
[1e97287]321
[6180274]322        TryStmt( const CodeLocation & loc, const CompoundStmt * body,
[400b8be]323                         const std::vector<ptr<CatchClause>> && handlers, const FinallyClause * finally,
[6180274]324                         const std::vector<Label> && labels = {} )
[89a5a1f]325                : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {}
[1e97287]326
[f3cc5b6]327        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]328  private:
[f3cc5b6]329        TryStmt * clone() const override { return new TryStmt{ *this }; }
330        MUTATE_FRIEND
[1e97287]331};
332
[89a5a1f]333// Catch clause of try statement
[400b8be]334class CatchClause final : public StmtClause {
[89a5a1f]335  public:
[1e97287]336        ptr<Decl> decl;
337        ptr<Expr> cond;
338        ptr<Stmt> body;
[6f4b7f2]339        ExceptionKind kind;
[1e97287]340
[400b8be]341        CatchClause( const CodeLocation & loc, ExceptionKind kind, const Decl * decl, const Expr * cond,
[a1da039]342                        const Stmt * body )
[400b8be]343                : StmtClause(loc), decl(decl), cond(cond), body(body), kind(kind) {}
[1e97287]344
[400b8be]345        const CatchClause * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]346  private:
[400b8be]347        CatchClause * clone() const override { return new CatchClause{ *this }; }
[f3cc5b6]348        MUTATE_FRIEND
[1e97287]349};
350
[89a5a1f]351// Finally clause of try statement
[400b8be]352class FinallyClause final : public StmtClause {
[89a5a1f]353  public:
[1e97287]354        ptr<CompoundStmt> body;
355
[400b8be]356        FinallyClause( const CodeLocation & loc, const CompoundStmt * body )
357                : StmtClause(loc), body(body) {}
[1e97287]358
[400b8be]359        const FinallyClause * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]360  private:
[400b8be]361        FinallyClause * clone() const override { return new FinallyClause{ *this }; }
[f3cc5b6]362        MUTATE_FRIEND
[1e97287]363};
[2bb4a01]364
[89a5a1f]365// Suspend statement
[37cdd97]366class SuspendStmt final : public Stmt {
[89a5a1f]367  public:
[37cdd97]368        ptr<CompoundStmt> then;
[835d6e8]369        enum Kind { None, Coroutine, Generator } kind = None;
[37cdd97]370
[835d6e8]371        SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Kind kind, const std::vector<Label> && labels = {} )
372                : Stmt(loc, std::move(labels)), then(then), kind(kind) {}
[37cdd97]373
374        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]375  private:
[37cdd97]376        SuspendStmt * clone() const override { return new SuspendStmt{ *this }; }
377        MUTATE_FRIEND
378};
379
[c86b08d]380// Base class of WaitFor/WaitUntil statements
381// form: KEYWORD(...) ... timeout(...) ... else ...
[a1da039]382class WaitStmt : public Stmt {
[89a5a1f]383  public:
[a1da039]384        ptr<Expr> timeout_time;
[f6e6a55]385        ptr<Stmt> timeout_stmt;
386        ptr<Expr> timeout_cond;
387        ptr<Stmt> else_stmt;
388        ptr<Expr> else_cond;
[1e97287]389
[a1da039]390        WaitStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
[89a5a1f]391                : Stmt(loc, std::move(labels)) {}
[1e97287]392
[c86b08d]393  private:
[a1da039]394        WaitStmt * clone() const override = 0;
[c86b08d]395        MUTATE_FRIEND
396};
397
398// Base class for WaitFor/WaitUntil clauses
399// form: when( when_cond ) KEYWORD( target ) stmt
400class WhenClause : public StmtClause {
401  public:
402        ptr<Expr> target;
403        ptr<Stmt> stmt;
404        ptr<Expr> when_cond;
405
406        WhenClause( const CodeLocation & loc )
407                : StmtClause( loc ) {}
408
409        const WhenClause * accept( Visitor & v ) const override { return v.visit( this ); }
410  private:
411        WhenClause * clone() const override { return new WhenClause{ *this }; }
412        MUTATE_FRIEND
413};
414
415// Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...
416class WaitForStmt final : public WaitStmt {
417  public:
418        std::vector<ptr<WaitForClause>> clauses;
419
420        WaitForStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
421                : WaitStmt(loc, std::move(labels)) {}
422
[f3cc5b6]423        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]424  private:
[f3cc5b6]425        WaitForStmt * clone() const override { return new WaitForStmt{ *this }; }
426        MUTATE_FRIEND
[1e97287]427};
428
[94c98f0e]429// Clause in a waitfor statement: waitfor (..., ...) ...
[c86b08d]430class WaitForClause final : public WhenClause {
[f6e6a55]431  public:
[491bb81]432        std::vector<ptr<Expr>> target_args;
[f6e6a55]433
[491bb81]434        WaitForClause( const CodeLocation & loc )
[c86b08d]435                : WhenClause( loc ) {}
[f6e6a55]436
437        const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); }
438  private:
[491bb81]439        WaitForClause * clone() const override { return new WaitForClause{ *this }; }
440        MUTATE_FRIEND
[f6e6a55]441};
442
[c86b08d]443// waituntil statement: when (...) waituntil (...) ... timeout(...) ... else ...
444class WaitUntilStmt final : public WaitStmt {
445  public:
[a1da039]446        // Non-ast node used during compilation to store data needed to generate predicates
447        //    and set initial status values for clauses
448        // Used to create a tree corresponding to the structure of the clauses in a WaitUntil
449        struct ClauseNode {
450                enum Op { AND, OR, LEFT_OR, LEAF, ELSE, TIMEOUT } op; // operation/type tag
451                // LEFT_OR used with TIMEOUT/ELSE to indicate that we ignore right hand side after parsing
452
453                ClauseNode * left;
454                ClauseNode * right;
455                WhenClause * leaf;  // only set if this node is a leaf (points into vector of clauses)
456
457                bool ambiguousWhen; // used to paint nodes of predicate tree based on when() clauses
458                bool whenState;     // used to track if when_cond is toggled on or off for generating init values
459                bool childOfAnd;      // true on leaf nodes that are children of AND, false otherwise
460
461                ClauseNode( Op op, ClauseNode * left, ClauseNode * right )
462                        : op(op), left(left), right(right), leaf(nullptr),
463                        ambiguousWhen(false), whenState(true), childOfAnd(false) {}
464                ClauseNode( Op op, WhenClause * leaf )
465                        : op(op), left(nullptr), right(nullptr), leaf(leaf),
466                        ambiguousWhen(false), whenState(true), childOfAnd(false) {}
467                ClauseNode( WhenClause * leaf ) : ClauseNode(LEAF, leaf) {}
468
469                ~ClauseNode() {
470                        if ( left ) delete left;
471                        if ( right ) delete right;
472                }
473        };
[c86b08d]474
475        std::vector<ptr<WhenClause>> clauses;
[a1da039]476        ClauseNode * predicateTree;
[c86b08d]477
478        WaitUntilStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
479                : WaitStmt(loc, std::move(labels)) {}
480
[a1da039]481        ~WaitUntilStmt() { delete predicateTree; }
[c86b08d]482
483        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
484  private:
485        WaitUntilStmt * clone() const override { return new WaitUntilStmt{ *this }; }
486        MUTATE_FRIEND
487};
488
[89a5a1f]489// Any declaration in a (compound) statement.
[1e97287]490class DeclStmt final : public Stmt {
[89a5a1f]491  public:
[1e97287]492        ptr<Decl> decl;
493
[6180274]494        DeclStmt( const CodeLocation & loc, const Decl * decl, const std::vector<Label> && labels = {} )
[89a5a1f]495                : Stmt(loc, std::move(labels)), decl(decl) {}
[1e97287]496
[f3cc5b6]497        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]498  private:
[f3cc5b6]499        DeclStmt * clone() const override { return new DeclStmt{ *this }; }
500        MUTATE_FRIEND
[1e97287]501};
502
[89a5a1f]503// Represents an implicit application of a constructor or destructor.
[1e97287]504class ImplicitCtorDtorStmt final : public Stmt {
[89a5a1f]505  public:
[c570806]506        ptr<Stmt> callStmt;
[1e97287]507
[f3cc5b6]508        ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt * callStmt,
[89a5a1f]509                                                  std::vector<Label> && labels = {} )
510                : Stmt(loc, std::move(labels)), callStmt(callStmt) {}
[1e97287]511
[f3cc5b6]512        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]513  private:
[f3cc5b6]514        ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt{ *this }; }
515        MUTATE_FRIEND
[1e97287]516};
[2bb4a01]517
[89a5a1f]518// Mutex Statement
[6cebfef]519class MutexStmt final : public Stmt {
[89a5a1f]520  public:
[6cebfef]521        ptr<Stmt> stmt;
522        std::vector<ptr<Expr>> mutexObjs;
523
[a1da039]524        MutexStmt( const CodeLocation & loc, const Stmt * stmt,
[6180274]525                           const std::vector<ptr<Expr>> && mutexes, const std::vector<Label> && labels = {} )
[89a5a1f]526                : Stmt(loc, std::move(labels)), stmt(stmt), mutexObjs(std::move(mutexes)) {}
[6cebfef]527
528        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]529  private:
[6cebfef]530        MutexStmt * clone() const override { return new MutexStmt{ *this }; }
531        MUTATE_FRIEND
532};
[94c98f0e]533
[eb779d5]534// Corun Statement
535class CorunStmt final : public Stmt {
536  public:
537        ptr<Stmt> stmt;
538
539        CorunStmt( const CodeLocation & loc, const Stmt * stmt, const std::vector<Label> && labels = {} )
540                : Stmt(loc, std::move(labels)), stmt(stmt) {}
541
542        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
543  private:
544        CorunStmt * clone() const override { return new CorunStmt{ *this }; }
545        MUTATE_FRIEND
546};
547
[3d9d017]548// Corun Statement
549class CoforStmt final : public Stmt {
550  public:
551        std::vector<ptr<Stmt>> inits;
552        ptr<Expr> cond;
553        ptr<Expr> inc;
554        ptr<Stmt> body;
555
556        CoforStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
557                         const Expr * inc, const Stmt * body, const std::vector<Label> && label = {} )
558                : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc), body(body) {}
559
560        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
561  private:
562        CoforStmt * clone() const override { return new CoforStmt{ *this }; }
563        MUTATE_FRIEND
564};
565
[89a5a1f]566} // namespace ast
[2bb4a01]567
[f3cc5b6]568#undef MUTATE_FRIEND
569
[2bb4a01]570// Local Variables: //
571// mode: c++ //
[1e97287]572// End: //
Note: See TracBrowser for help on using the repository browser.