source: src/AST/Stmt.hpp@ c671112

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since c671112 was f3cc5b6, checked in by Aaron Moss <a3moss@…>, 6 years ago

Ensure all node types have mutate() as friend

  • Property mode set to 100644
File size: 16.3 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
11// Last Modified By : Andrew Beach
12// Last Modified On : Wed May 15 16:01:00 2019
13// Update Count : 2
[2bb4a01]14//
15
16#pragma once
17
18#include <list>
19#include <utility> // for move
20#include <vector>
21
22#include "Label.hpp"
23#include "Node.hpp" // for node, ptr
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
29#define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node);
30
[2bb4a01]31namespace ast {
32
33class Expr;
34
35/// Base statement node
36class Stmt : public ParseNode {
37public:
38 std::vector<Label> labels;
39
[f3cc5b6]40 Stmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
[2bb4a01]41 : ParseNode(loc), labels(std::move(labels)) {}
42
43 Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {}
44
[f3cc5b6]45 const Stmt * accept( Visitor & v ) const override = 0;
[2bb4a01]46private:
[f3cc5b6]47 Stmt * clone() const override = 0;
48 MUTATE_FRIEND
[2bb4a01]49};
50
51/// Compound statement `{ ... }`
52class CompoundStmt final : public Stmt {
53public:
54 std::list<ptr<Stmt>> kids;
55
[f3cc5b6]56 CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>> && ks = {} )
[2bb4a01]57 : Stmt(loc), kids(std::move(ks)) {}
58
59 CompoundStmt( const CompoundStmt& o );
60 CompoundStmt( CompoundStmt&& o ) = default;
61
[f3cc5b6]62 void push_back( Stmt * s ) { kids.emplace_back( s ); }
63 void push_front( Stmt * s ) { kids.emplace_front( s ); }
[2bb4a01]64
[f3cc5b6]65 const CompoundStmt * accept( Visitor & v ) const override { return v.visit( this ); }
[2bb4a01]66private:
[f3cc5b6]67 CompoundStmt * clone() const override { return new CompoundStmt{ *this }; }
68 MUTATE_FRIEND
[2bb4a01]69};
70
71/// Empty statment `;`
72class NullStmt final : public Stmt {
73public:
[f3cc5b6]74 NullStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
[2bb4a01]75 : Stmt(loc, std::move(labels)) {}
76
[f3cc5b6]77 const NullStmt * accept( Visitor & v ) const override { return v.visit( this ); }
[2bb4a01]78private:
[f3cc5b6]79 NullStmt * clone() const override { return new NullStmt{ *this }; }
80 MUTATE_FRIEND
[2bb4a01]81};
82
83/// Expression wrapped by statement
84class ExprStmt final : public Stmt {
85public:
86 ptr<Expr> expr;
87
[8a5530c]88 ExprStmt( const CodeLocation & loc, const Expr * e ) : Stmt(loc), expr(e) {}
[2bb4a01]89
[f3cc5b6]90 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[2bb4a01]91private:
[23f99e1]92 ExprStmt * clone() const override { return new ExprStmt{ *this }; }
[f3cc5b6]93 MUTATE_FRIEND
[2bb4a01]94};
95
[1e97287]96class AsmStmt final : public Stmt {
97public:
98 bool isVolatile;
99 ptr<Expr> instruction;
100 std::vector<ptr<Expr>> output, input;
101 std::vector<ptr<ConstantExpr>> clobber;
102 std::vector<Label> gotoLabels;
103
[f3cc5b6]104 AsmStmt( const CodeLocation & loc, bool isVolatile, const Expr * instruction,
105 std::vector<ptr<Expr>> && output, std::vector<ptr<Expr>> && input,
106 std::vector<ptr<ConstantExpr>> && clobber, std::vector<Label> && gotoLabels,
107 std::vector<Label> && labels = {})
[1e97287]108 : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction),
109 output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)),
110 gotoLabels(std::move(gotoLabels)) {}
111
[f3cc5b6]112 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]113private:
[f3cc5b6]114 AsmStmt * clone() const override { return new AsmStmt{ *this }; }
115 MUTATE_FRIEND
[1e97287]116};
117
118class DirectiveStmt final : public Stmt {
119public:
120 std::string directive;
121
[f3cc5b6]122 DirectiveStmt( const CodeLocation & loc, const std::string & directive,
123 std::vector<Label> && labels = {} )
[1e97287]124 : Stmt(loc, std::move(labels)), directive(directive) {}
125
[f3cc5b6]126 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]127private:
[f3cc5b6]128 DirectiveStmt * clone() const override { return new DirectiveStmt{ *this }; }
129 MUTATE_FRIEND
[1e97287]130};
131
132class IfStmt final : public Stmt {
133public:
134 ptr<Expr> cond;
135 ptr<Stmt> thenPart;
136 ptr<Stmt> elsePart;
137 std::vector<ptr<Stmt>> inits;
138
[f3cc5b6]139 IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * thenPart,
140 Stmt * const elsePart, std::vector<ptr<Stmt>> && inits,
141 std::vector<Label> && labels = {} )
[1e97287]142 : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart),
143 inits(std::move(inits)) {}
144
[f3cc5b6]145 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]146private:
[f3cc5b6]147 IfStmt * clone() const override { return new IfStmt{ *this }; }
148 MUTATE_FRIEND
[1e97287]149};
150
151class SwitchStmt final : public Stmt {
152public:
153 ptr<Expr> cond;
154 std::vector<ptr<Stmt>> stmts;
155
[f3cc5b6]156 SwitchStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts,
157 std::vector<Label> && labels = {} )
[1e97287]158 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}
159
[f3cc5b6]160 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]161private:
[f3cc5b6]162 SwitchStmt * clone() const override { return new SwitchStmt{ *this }; }
163 MUTATE_FRIEND
[1e97287]164};
165
166class CaseStmt final : public Stmt {
167public:
168 ptr<Expr> cond;
169 std::vector<ptr<Stmt>> stmts;
170
[f3cc5b6]171 CaseStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts,
172 std::vector<Label> && labels = {} )
173 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}
[1e97287]174
175 bool isDefault() { return !cond; }
176
[f3cc5b6]177 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]178private:
[f3cc5b6]179 CaseStmt * clone() const override { return new CaseStmt{ *this }; }
180 MUTATE_FRIEND
[1e97287]181};
182
183class WhileStmt final : public Stmt {
184public:
185 ptr<Expr> cond;
186 ptr<Stmt> body;
187 std::vector<ptr<Stmt>> inits;
188 bool isDoWhile;
189
[f3cc5b6]190 WhileStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body,
191 std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label> && labels = {} )
[1e97287]192 : Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)),
193 isDoWhile(isDoWhile) {}
194
[f3cc5b6]195 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]196private:
[f3cc5b6]197 WhileStmt * clone() const override { return new WhileStmt{ *this }; }
198 MUTATE_FRIEND
[1e97287]199};
200
201class ForStmt final : public Stmt {
202public:
203 std::vector<ptr<Stmt>> inits;
204 ptr<Expr> cond;
[8a5530c]205 ptr<Expr> inc;
[1e97287]206 ptr<Stmt> body;
207
[f3cc5b6]208 ForStmt( const CodeLocation & loc, std::vector<ptr<Stmt>> && inits, const Expr * cond,
209 const Expr * inc, const Stmt * body, std::vector<Label> && labels = {} )
[8a5530c]210 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc),
[1e97287]211 body(body) {}
212
[f3cc5b6]213 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]214private:
[f3cc5b6]215 ForStmt * clone() const override { return new ForStmt{ *this }; }
216 MUTATE_FRIEND
[1e97287]217};
218
219class BranchStmt final : public Stmt {
220public:
221 enum Kind { Goto, Break, Continue, FallThrough, FallThroughDefault };
222 static constexpr size_t kindEnd = 1 + (size_t)FallThroughDefault;
223
224 const Label originalTarget;
225 Label target;
226 ptr<Expr> computedTarget;
227 Kind kind;
228
[f3cc5b6]229 BranchStmt( const CodeLocation & loc, Kind kind, Label target,
230 std::vector<Label> && labels = {} );
231 BranchStmt( const CodeLocation & loc, const Expr * computedTarget,
232 std::vector<Label> && labels = {} )
[1e97287]233 : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc),
234 computedTarget(computedTarget), kind(Goto) {}
235
236 const char * kindName() { return kindNames[kind]; }
237
[f3cc5b6]238 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]239private:
[f3cc5b6]240 BranchStmt * clone() const override { return new BranchStmt{ *this }; }
241 MUTATE_FRIEND
[8a5530c]242
[1e97287]243 static const char * kindNames[kindEnd];
244};
245
246class ReturnStmt final : public Stmt {
247public:
248 ptr<Expr> expr;
249
[f3cc5b6]250 ReturnStmt( const CodeLocation & loc, const Expr * expr, std::vector<Label> && labels = {} )
[1e97287]251 : Stmt(loc, std::move(labels)), expr(expr) {}
252
[f3cc5b6]253 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]254private:
[f3cc5b6]255 ReturnStmt * clone() const override { return new ReturnStmt{ *this }; }
256 MUTATE_FRIEND
[1e97287]257};
258
259class ThrowStmt final : public Stmt {
260public:
261 enum Kind { Terminate, Resume };
262
263 ptr<Expr> expr;
264 ptr<Expr> target;
265 Kind kind;
266
[f3cc5b6]267 ThrowStmt( const CodeLocation & loc, Kind kind, const Expr * expr, const Expr * target,
268 std::vector<Label> && labels = {} )
[1e97287]269 : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {}
270
[f3cc5b6]271 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]272private:
[f3cc5b6]273 ThrowStmt * clone() const override { return new ThrowStmt{ *this }; }
274 MUTATE_FRIEND
[1e97287]275};
276
277class TryStmt final : public Stmt {
278public:
279 ptr<CompoundStmt> body;
280 std::vector<ptr<CatchStmt>> handlers;
281 ptr<FinallyStmt> finally;
282
[f3cc5b6]283 TryStmt( const CodeLocation & loc, const CompoundStmt * body,
284 std::vector<ptr<CatchStmt>> && handlers, const FinallyStmt * finally,
285 std::vector<Label> && labels = {} )
[1e97287]286 : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {}
287
[f3cc5b6]288 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]289private:
[f3cc5b6]290 TryStmt * clone() const override { return new TryStmt{ *this }; }
291 MUTATE_FRIEND
[1e97287]292};
293
294class CatchStmt final : public Stmt {
295public:
296 enum Kind { Terminate, Resume };
297
298 ptr<Decl> decl;
299 ptr<Expr> cond;
300 ptr<Stmt> body;
301 Kind kind;
302
[f3cc5b6]303 CatchStmt( const CodeLocation & loc, Kind kind, const Decl * decl, const Expr * cond,
304 const Stmt * body, std::vector<Label> && labels = {} )
[1e97287]305 : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {}
306
[f3cc5b6]307 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]308private:
[f3cc5b6]309 CatchStmt * clone() const override { return new CatchStmt{ *this }; }
310 MUTATE_FRIEND
[1e97287]311};
312
313class FinallyStmt final : public Stmt {
314public:
315 ptr<CompoundStmt> body;
316
[f3cc5b6]317 FinallyStmt( const CodeLocation & loc, const CompoundStmt * body,
318 std::vector<Label> && labels = {} )
[1e97287]319 : Stmt(loc, std::move(labels)), body(body) {}
320
[f3cc5b6]321 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]322private:
[f3cc5b6]323 FinallyStmt * clone() const override { return new FinallyStmt{ *this }; }
324 MUTATE_FRIEND
[1e97287]325};
[2bb4a01]326
[1e97287]327class WaitForStmt final : public Stmt {
328public:
329 struct Target {
330 ptr<Expr> function;
331 std::vector<ptr<Expr>> arguments;
332 };
333
334 struct Clause {
335 Target target;
336 ptr<Stmt> stmt;
337 ptr<Expr> cond;
338 };
339
340 struct Timeout {
341 ptr<Expr> time;
342 ptr<Stmt> stmt;
343 ptr<Expr> cond;
344 };
345
346 struct OrElse {
347 ptr<Stmt> stmt;
348 ptr<Expr> cond;
349 };
350
351 std::vector<Clause> clauses;
352 Timeout timeout;
353 OrElse orElse;
354
[f3cc5b6]355 WaitForStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
[1e97287]356 : Stmt(loc, std::move(labels)) {}
357
[f3cc5b6]358 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]359private:
[f3cc5b6]360 WaitForStmt * clone() const override { return new WaitForStmt{ *this }; }
361 MUTATE_FRIEND
[1e97287]362};
363
364class WithStmt final : public Stmt {
365public:
366 std::vector<ptr<Expr>> exprs;
367 ptr<Stmt> stmt;
368
[f3cc5b6]369 WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt,
370 std::vector<Label> && labels = {} )
[1e97287]371 : Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {}
372
[f3cc5b6]373 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]374private:
[f3cc5b6]375 WithStmt * clone() const override { return new WithStmt{ *this }; }
376 MUTATE_FRIEND
[1e97287]377};
378
379class DeclStmt final : public Stmt {
380public:
381 ptr<Decl> decl;
382
[f3cc5b6]383 DeclStmt( const CodeLocation & loc, const Decl * decl, std::vector<Label> && labels = {} )
[1e97287]384 : Stmt(loc, std::move(labels)), decl(decl) {}
385
[f3cc5b6]386 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]387private:
[f3cc5b6]388 DeclStmt * clone() const override { return new DeclStmt{ *this }; }
389 MUTATE_FRIEND
[1e97287]390};
391
392class ImplicitCtorDtorStmt final : public Stmt {
393public:
394 readonly<Stmt> callStmt;
395
[f3cc5b6]396 ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt * callStmt,
397 std::vector<Label> && labels = {} )
[1e97287]398 : Stmt(loc, std::move(labels)), callStmt(callStmt) {}
399
[f3cc5b6]400 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
[1e97287]401private:
[f3cc5b6]402 ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt{ *this }; }
403 MUTATE_FRIEND
[1e97287]404};
[2bb4a01]405
[e0115286]406//=================================================================================================
407/// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency
408/// remove only if there is a better solution
409/// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with
410/// forward declarations
411inline void increment( const class Stmt * node, Node::ref_type ref ) { node->increment( ref ); }
412inline void decrement( const class Stmt * node, Node::ref_type ref ) { node->decrement( ref ); }
413inline void increment( const class CompoundStmt * node, Node::ref_type ref ) { node->increment( ref ); }
414inline void decrement( const class CompoundStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
415inline void increment( const class ExprStmt * node, Node::ref_type ref ) { node->increment( ref ); }
416inline void decrement( const class ExprStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
[8a5530c]417inline void increment( const class AsmStmt * node, Node::ref_type ref ) { node->increment( ref ); }
418inline void decrement( const class AsmStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
419inline void increment( const class DirectiveStmt * node, Node::ref_type ref ) { node->increment( ref ); }
420inline void decrement( const class DirectiveStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
421inline void increment( const class IfStmt * node, Node::ref_type ref ) { node->increment( ref ); }
422inline void decrement( const class IfStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
423inline void increment( const class WhileStmt * node, Node::ref_type ref ) { node->increment( ref ); }
424inline void decrement( const class WhileStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
425inline void increment( const class ForStmt * node, Node::ref_type ref ) { node->increment( ref ); }
426inline void decrement( const class ForStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
427inline void increment( const class SwitchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
428inline void decrement( const class SwitchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
429inline void increment( const class CaseStmt * node, Node::ref_type ref ) { node->increment( ref ); }
430inline void decrement( const class CaseStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
431inline void increment( const class BranchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
432inline void decrement( const class BranchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
433inline void increment( const class ReturnStmt * node, Node::ref_type ref ) { node->increment( ref ); }
434inline void decrement( const class ReturnStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
435inline void increment( const class ThrowStmt * node, Node::ref_type ref ) { node->increment( ref ); }
436inline void decrement( const class ThrowStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
437inline void increment( const class TryStmt * node, Node::ref_type ref ) { node->increment( ref ); }
438inline void decrement( const class TryStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
439inline void increment( const class CatchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
440inline void decrement( const class CatchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
441inline void increment( const class FinallyStmt * node, Node::ref_type ref ) { node->increment( ref ); }
442inline void decrement( const class FinallyStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
443inline void increment( const class WaitForStmt * node, Node::ref_type ref ) { node->increment( ref ); }
444inline void decrement( const class WaitForStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
445inline void increment( const class WithStmt * node, Node::ref_type ref ) { node->increment( ref ); }
446inline void decrement( const class WithStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
447inline void increment( const class DeclStmt * node, Node::ref_type ref ) { node->increment( ref ); }
448inline void decrement( const class DeclStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
[e0115286]449inline void increment( const class NullStmt * node, Node::ref_type ref ) { node->increment( ref ); }
450inline void decrement( const class NullStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
[8a5530c]451inline void increment( const class ImplicitCtorDtorStmt * node, Node::ref_type ref ) { node->increment( ref ); }
452inline void decrement( const class ImplicitCtorDtorStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
[e0115286]453
[2bb4a01]454}
455
[f3cc5b6]456#undef MUTATE_FRIEND
457
[2bb4a01]458// Local Variables: //
459// tab-width: 4 //
460// mode: c++ //
461// compile-command: "make install" //
[1e97287]462// End: //
Note: See TracBrowser for help on using the repository browser.