source: src/AST/Stmt.hpp @ 8a5530c

arm-ehcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 8a5530c was 8a5530c, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Fixed FunctionType? cast, fixed maybe_accept, implemented statement visitation and fixed several nodes

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