source: src/AST/Stmt.hpp @ 1e97287

arm-ehcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 1e97287 was 1e97287, checked in by Andrew Beach <ajbeach@…>, 4 years ago

Re-created the statement section of the AST.

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