source: src/AST/Stmt.hpp@ b28ce93

Last change on this file since b28ce93 was d96f7c4, checked in by Peter A. Buhr <pabuhr@…>, 8 months ago

expunge fallthru keyword and replace its usages with fallthrough

  • Property mode set to 100644
File size: 19.5 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
[d96f7c4]11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri Jan 17 14:18:56 2025
13// Update Count : 38
[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"
[c92bdcc]26#include "Common/CodeLocation.hpp"
[2bb4a01]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 = {} )
[525f7ad]244 : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc),
[fca78f1]245 body(body), else_(nullptr) {}
[1e97287]246
[6180274]247 ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
248 const Expr * inc, const Stmt * body, const Stmt * else_, const std::vector<Label> && labels = {} )
[525f7ad]249 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc),
[d3aa55e9]250 body(body), else_(else_) {}
[1e97287]251
[f3cc5b6]252 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]253 private:
[f3cc5b6]254 ForStmt * clone() const override { return new ForStmt{ *this }; }
255 MUTATE_FRIEND
[1e97287]256};
257
[fca78f1]258enum RangeDirection { DecreasingRange, IncreasingRange };
259
260// For-each loop: for (... : ...) ... else ...
261class ForeachStmt final : public Stmt {
262 public:
263 std::vector<ptr<Stmt>> inits;
264 ptr<Expr> range;
265 ptr<Stmt> body;
266 ptr<Stmt> else_;
267 // This is a property of the range, but there is no place to store it.
268 RangeDirection isIncreasing;
269
270 ForeachStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits,
[2d6add4]271 const Expr * range_over, RangeDirection isInc, const Stmt * body,
272 const Stmt * else_, const std::vector<Label> && labels = {} )
[fca78f1]273 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range(range_over),
274 body(body), else_(else_), isIncreasing(isInc) {}
275
276 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
277 private:
278 ForeachStmt * clone() const override { return new ForeachStmt{ *this }; }
279 MUTATE_FRIEND
280};
281
[d96f7c4]282// Branch control flow statement: goto ... or break or continue or fallthrough
[1e97287]283class BranchStmt final : public Stmt {
[89a5a1f]284 public:
[1e97287]285 enum Kind { Goto, Break, Continue, FallThrough, FallThroughDefault };
286 static constexpr size_t kindEnd = 1 + (size_t)FallThroughDefault;
287
288 const Label originalTarget;
289 Label target;
290 ptr<Expr> computedTarget;
291 Kind kind;
292
[6180274]293 BranchStmt( const CodeLocation & loc, Kind kind, Label target, const std::vector<Label> && labels = {} );
294 BranchStmt( const CodeLocation & loc, const Expr * computedTarget, const std::vector<Label> && labels = {} )
295 : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc), computedTarget(computedTarget), kind(Goto) {}
[1e97287]296
[94b1f718]297 const char * kindName() const { return kindNames[kind]; }
[1e97287]298
[f3cc5b6]299 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]300 private:
[f3cc5b6]301 BranchStmt * clone() const override { return new BranchStmt{ *this }; }
302 MUTATE_FRIEND
[8a5530c]303
[1e97287]304 static const char * kindNames[kindEnd];
305};
306
[89a5a1f]307// Return statement: return ...
[1e97287]308class ReturnStmt final : public Stmt {
[89a5a1f]309 public:
[1e97287]310 ptr<Expr> expr;
311
[6180274]312 ReturnStmt( const CodeLocation & loc, const Expr * expr, const std::vector<Label> && labels = {} )
[89a5a1f]313 : Stmt(loc, std::move(labels)), expr(expr) {}
[1e97287]314
[f3cc5b6]315 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]316 private:
[f3cc5b6]317 ReturnStmt * clone() const override { return new ReturnStmt{ *this }; }
318 MUTATE_FRIEND
[1e97287]319};
320
[89a5a1f]321// Kind of exception
[6f4b7f2]322enum ExceptionKind { Terminate, Resume };
323
[89a5a1f]324// Throw statement: throw ...
[1e97287]325class ThrowStmt final : public Stmt {
[89a5a1f]326 public:
[1e97287]327 ptr<Expr> expr;
328 ptr<Expr> target;
[6f4b7f2]329 ExceptionKind kind;
[1e97287]330
[6180274]331 ThrowStmt( const CodeLocation & loc, ExceptionKind kind, const Expr * expr,
332 const Expr * target, const std::vector<Label> && labels = {} )
[89a5a1f]333 : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {}
[1e97287]334
[f3cc5b6]335 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]336 private:
[f3cc5b6]337 ThrowStmt * clone() const override { return new ThrowStmt{ *this }; }
338 MUTATE_FRIEND
[1e97287]339};
340
[89a5a1f]341// Try statement: try { ... } ...
[1e97287]342class TryStmt final : public Stmt {
[89a5a1f]343 public:
[1e97287]344 ptr<CompoundStmt> body;
[400b8be]345 std::vector<ptr<CatchClause>> handlers;
346 ptr<FinallyClause> finally;
[1e97287]347
[6180274]348 TryStmt( const CodeLocation & loc, const CompoundStmt * body,
[400b8be]349 const std::vector<ptr<CatchClause>> && handlers, const FinallyClause * finally,
[6180274]350 const std::vector<Label> && labels = {} )
[89a5a1f]351 : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {}
[1e97287]352
[f3cc5b6]353 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]354 private:
[f3cc5b6]355 TryStmt * clone() const override { return new TryStmt{ *this }; }
356 MUTATE_FRIEND
[1e97287]357};
358
[89a5a1f]359// Catch clause of try statement
[400b8be]360class CatchClause final : public StmtClause {
[89a5a1f]361 public:
[1e97287]362 ptr<Decl> decl;
363 ptr<Expr> cond;
364 ptr<Stmt> body;
[6f4b7f2]365 ExceptionKind kind;
[1e97287]366
[400b8be]367 CatchClause( const CodeLocation & loc, ExceptionKind kind, const Decl * decl, const Expr * cond,
[a1da039]368 const Stmt * body )
[400b8be]369 : StmtClause(loc), decl(decl), cond(cond), body(body), kind(kind) {}
[1e97287]370
[400b8be]371 const CatchClause * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]372 private:
[400b8be]373 CatchClause * clone() const override { return new CatchClause{ *this }; }
[f3cc5b6]374 MUTATE_FRIEND
[1e97287]375};
376
[89a5a1f]377// Finally clause of try statement
[400b8be]378class FinallyClause final : public StmtClause {
[89a5a1f]379 public:
[1e97287]380 ptr<CompoundStmt> body;
381
[400b8be]382 FinallyClause( const CodeLocation & loc, const CompoundStmt * body )
383 : StmtClause(loc), body(body) {}
[1e97287]384
[400b8be]385 const FinallyClause * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]386 private:
[400b8be]387 FinallyClause * clone() const override { return new FinallyClause{ *this }; }
[f3cc5b6]388 MUTATE_FRIEND
[1e97287]389};
[2bb4a01]390
[89a5a1f]391// Suspend statement
[37cdd97]392class SuspendStmt final : public Stmt {
[89a5a1f]393 public:
[37cdd97]394 ptr<CompoundStmt> then;
[835d6e8]395 enum Kind { None, Coroutine, Generator } kind = None;
[37cdd97]396
[835d6e8]397 SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Kind kind, const std::vector<Label> && labels = {} )
398 : Stmt(loc, std::move(labels)), then(then), kind(kind) {}
[37cdd97]399
400 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]401 private:
[37cdd97]402 SuspendStmt * clone() const override { return new SuspendStmt{ *this }; }
403 MUTATE_FRIEND
404};
405
[c86b08d]406// Base class of WaitFor/WaitUntil statements
407// form: KEYWORD(...) ... timeout(...) ... else ...
[a1da039]408class WaitStmt : public Stmt {
[89a5a1f]409 public:
[a1da039]410 ptr<Expr> timeout_time;
[f6e6a55]411 ptr<Stmt> timeout_stmt;
412 ptr<Expr> timeout_cond;
413 ptr<Stmt> else_stmt;
414 ptr<Expr> else_cond;
[1e97287]415
[a1da039]416 WaitStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
[89a5a1f]417 : Stmt(loc, std::move(labels)) {}
[1e97287]418
[c86b08d]419 private:
[a1da039]420 WaitStmt * clone() const override = 0;
[c86b08d]421 MUTATE_FRIEND
422};
423
424// Base class for WaitFor/WaitUntil clauses
425// form: when( when_cond ) KEYWORD( target ) stmt
426class WhenClause : public StmtClause {
427 public:
428 ptr<Expr> target;
429 ptr<Stmt> stmt;
430 ptr<Expr> when_cond;
431
432 WhenClause( const CodeLocation & loc )
433 : StmtClause( loc ) {}
434
435 const WhenClause * accept( Visitor & v ) const override { return v.visit( this ); }
436 private:
437 WhenClause * clone() const override { return new WhenClause{ *this }; }
438 MUTATE_FRIEND
439};
440
441// Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...
442class WaitForStmt final : public WaitStmt {
443 public:
444 std::vector<ptr<WaitForClause>> clauses;
445
446 WaitForStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
447 : WaitStmt(loc, std::move(labels)) {}
448
[f3cc5b6]449 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]450 private:
[f3cc5b6]451 WaitForStmt * clone() const override { return new WaitForStmt{ *this }; }
452 MUTATE_FRIEND
[1e97287]453};
454
[94c98f0e]455// Clause in a waitfor statement: waitfor (..., ...) ...
[c86b08d]456class WaitForClause final : public WhenClause {
[f6e6a55]457 public:
[491bb81]458 std::vector<ptr<Expr>> target_args;
[f6e6a55]459
[491bb81]460 WaitForClause( const CodeLocation & loc )
[c86b08d]461 : WhenClause( loc ) {}
[f6e6a55]462
463 const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); }
464 private:
[491bb81]465 WaitForClause * clone() const override { return new WaitForClause{ *this }; }
466 MUTATE_FRIEND
[f6e6a55]467};
468
[c86b08d]469// waituntil statement: when (...) waituntil (...) ... timeout(...) ... else ...
470class WaitUntilStmt final : public WaitStmt {
471 public:
[a1da039]472 // Non-ast node used during compilation to store data needed to generate predicates
473 // and set initial status values for clauses
474 // Used to create a tree corresponding to the structure of the clauses in a WaitUntil
475 struct ClauseNode {
476 enum Op { AND, OR, LEFT_OR, LEAF, ELSE, TIMEOUT } op; // operation/type tag
477 // LEFT_OR used with TIMEOUT/ELSE to indicate that we ignore right hand side after parsing
478
479 ClauseNode * left;
480 ClauseNode * right;
481 WhenClause * leaf; // only set if this node is a leaf (points into vector of clauses)
482
483 bool ambiguousWhen; // used to paint nodes of predicate tree based on when() clauses
484 bool whenState; // used to track if when_cond is toggled on or off for generating init values
485 bool childOfAnd; // true on leaf nodes that are children of AND, false otherwise
486
487 ClauseNode( Op op, ClauseNode * left, ClauseNode * right )
488 : op(op), left(left), right(right), leaf(nullptr),
489 ambiguousWhen(false), whenState(true), childOfAnd(false) {}
490 ClauseNode( Op op, WhenClause * leaf )
491 : op(op), left(nullptr), right(nullptr), leaf(leaf),
492 ambiguousWhen(false), whenState(true), childOfAnd(false) {}
493 ClauseNode( WhenClause * leaf ) : ClauseNode(LEAF, leaf) {}
494
495 ~ClauseNode() {
496 if ( left ) delete left;
497 if ( right ) delete right;
498 }
499 };
[c86b08d]500
501 std::vector<ptr<WhenClause>> clauses;
[a1da039]502 ClauseNode * predicateTree;
[c86b08d]503
504 WaitUntilStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
505 : WaitStmt(loc, std::move(labels)) {}
506
[a1da039]507 ~WaitUntilStmt() { delete predicateTree; }
[c86b08d]508
509 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
510 private:
511 WaitUntilStmt * clone() const override { return new WaitUntilStmt{ *this }; }
512 MUTATE_FRIEND
513};
514
[89a5a1f]515// Any declaration in a (compound) statement.
[1e97287]516class DeclStmt final : public Stmt {
[89a5a1f]517 public:
[1e97287]518 ptr<Decl> decl;
519
[6180274]520 DeclStmt( const CodeLocation & loc, const Decl * decl, const std::vector<Label> && labels = {} )
[89a5a1f]521 : Stmt(loc, std::move(labels)), decl(decl) {}
[1e97287]522
[f3cc5b6]523 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]524 private:
[f3cc5b6]525 DeclStmt * clone() const override { return new DeclStmt{ *this }; }
526 MUTATE_FRIEND
[1e97287]527};
528
[89a5a1f]529// Represents an implicit application of a constructor or destructor.
[1e97287]530class ImplicitCtorDtorStmt final : public Stmt {
[89a5a1f]531 public:
[c570806]532 ptr<Stmt> callStmt;
[1e97287]533
[f3cc5b6]534 ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt * callStmt,
[89a5a1f]535 std::vector<Label> && labels = {} )
536 : Stmt(loc, std::move(labels)), callStmt(callStmt) {}
[1e97287]537
[f3cc5b6]538 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]539 private:
[f3cc5b6]540 ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt{ *this }; }
541 MUTATE_FRIEND
[1e97287]542};
[2bb4a01]543
[89a5a1f]544// Mutex Statement
[6cebfef]545class MutexStmt final : public Stmt {
[89a5a1f]546 public:
[6cebfef]547 ptr<Stmt> stmt;
548 std::vector<ptr<Expr>> mutexObjs;
549
[a1da039]550 MutexStmt( const CodeLocation & loc, const Stmt * stmt,
[6180274]551 const std::vector<ptr<Expr>> && mutexes, const std::vector<Label> && labels = {} )
[89a5a1f]552 : Stmt(loc, std::move(labels)), stmt(stmt), mutexObjs(std::move(mutexes)) {}
[6cebfef]553
554 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[89a5a1f]555 private:
[6cebfef]556 MutexStmt * clone() const override { return new MutexStmt{ *this }; }
557 MUTATE_FRIEND
558};
[94c98f0e]559
[eb779d5]560// Corun Statement
561class CorunStmt final : public Stmt {
562 public:
563 ptr<Stmt> stmt;
564
565 CorunStmt( const CodeLocation & loc, const Stmt * stmt, const std::vector<Label> && labels = {} )
566 : Stmt(loc, std::move(labels)), stmt(stmt) {}
567
568 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
569 private:
570 CorunStmt * clone() const override { return new CorunStmt{ *this }; }
571 MUTATE_FRIEND
572};
573
[3d9d017]574// Corun Statement
575class CoforStmt final : public Stmt {
576 public:
577 std::vector<ptr<Stmt>> inits;
578 ptr<Expr> cond;
579 ptr<Expr> inc;
580 ptr<Stmt> body;
581
582 CoforStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
583 const Expr * inc, const Stmt * body, const std::vector<Label> && label = {} )
584 : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc), body(body) {}
585
586 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
587 private:
588 CoforStmt * clone() const override { return new CoforStmt{ *this }; }
589 MUTATE_FRIEND
590};
591
[89a5a1f]592} // namespace ast
[2bb4a01]593
[f3cc5b6]594#undef MUTATE_FRIEND
595
[2bb4a01]596// Local Variables: //
597// mode: c++ //
[1e97287]598// End: //
Note: See TracBrowser for help on using the repository browser.