- Timestamp:
- Feb 1, 2022, 12:06:24 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- ab1a9ea
- Parents:
- 3e5db5b4 (diff), 7b2c8c3c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/AST/Stmt.hpp ¶
r3e5db5b4 r34c32f0 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 8 13:00:00 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri May 17 12:45:00 201913 // Update Count : 511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 31 22:38:53 2022 13 // Update Count : 12 14 14 // 15 15 … … 17 17 18 18 #include <list> 19 #include <utility> 19 #include <utility> // for move 20 20 #include <vector> 21 21 22 22 #include "Label.hpp" 23 #include "Node.hpp" 23 #include "Node.hpp" // for node, ptr 24 24 #include "ParseNode.hpp" 25 25 #include "Visitor.hpp" … … 27 27 28 28 // Must be included in *all* AST classes; should be #undef'd at the end of the file 29 #define MUTATE_FRIEND 29 #define MUTATE_FRIEND \ 30 30 template<typename node_t> friend node_t * mutate(const node_t * node); \ 31 31 template<typename node_t> friend node_t * shallowCopy(const node_t * node); 32 32 33 33 namespace ast { 34 35 34 class Expr; 36 35 37 // /Base statement node36 // Base statement node 38 37 class Stmt : public ParseNode { 39 public:38 public: 40 39 std::vector<Label> labels; 41 40 42 41 Stmt( const CodeLocation & loc, std::vector<Label> && labels = {} ) 43 : ParseNode(loc), labels(std::move(labels)) {}42 : ParseNode(loc), labels(std::move(labels)) {} 44 43 45 44 Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {} 46 45 47 46 const Stmt * accept( Visitor & v ) const override = 0; 48 private:47 private: 49 48 Stmt * clone() const override = 0; 50 49 MUTATE_FRIEND 51 50 }; 52 51 53 // / Compound statement `{ ... }`52 // Compound statement: { ... } 54 53 class CompoundStmt final : public Stmt { 55 public:54 public: 56 55 std::list<ptr<Stmt>> kids; 57 56 58 57 CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>> && ks = {}, 59 std::vector<Label>&& labels = {} )60 : Stmt(loc, std::move(labels)), kids(std::move(ks)) {}58 std::vector<Label>&& labels = {} ) 59 : Stmt(loc, std::move(labels)), kids(std::move(ks)) {} 61 60 62 61 CompoundStmt( const CompoundStmt& o ); … … 67 66 68 67 const CompoundStmt * accept( Visitor & v ) const override { return v.visit( this ); } 69 private:68 private: 70 69 CompoundStmt * clone() const override { return new CompoundStmt{ *this }; } 71 70 MUTATE_FRIEND 72 71 }; 73 72 74 // / Empty statment `;`73 // Empty statment: ; 75 74 class NullStmt final : public Stmt { 76 public:75 public: 77 76 NullStmt( const CodeLocation & loc, std::vector<Label> && labels = {} ) 78 : Stmt(loc, std::move(labels)) {}77 : Stmt(loc, std::move(labels)) {} 79 78 80 79 const NullStmt * accept( Visitor & v ) const override { return v.visit( this ); } 81 private:80 private: 82 81 NullStmt * clone() const override { return new NullStmt{ *this }; } 83 82 MUTATE_FRIEND 84 83 }; 85 84 86 // /Expression wrapped by statement85 // Expression wrapped by statement 87 86 class ExprStmt final : public Stmt { 88 public:87 public: 89 88 ptr<Expr> expr; 90 89 91 90 ExprStmt( const CodeLocation& loc, const Expr* e, std::vector<Label>&& labels = {} ) 92 : Stmt(loc, std::move(labels)), expr(e) {}93 94 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 95 private:91 : Stmt(loc, std::move(labels)), expr(e) {} 92 93 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 94 private: 96 95 ExprStmt * clone() const override { return new ExprStmt{ *this }; } 97 96 MUTATE_FRIEND 98 97 }; 99 98 100 // / Assembly statement `asm ... ( "..." : ... )`99 // Assembly statement: asm ... ( "..." : ... ) 101 100 class AsmStmt final : public Stmt { 102 public:101 public: 103 102 bool isVolatile; 104 103 ptr<Expr> instruction; … … 108 107 109 108 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 ); } 118 private:109 std::vector<ptr<Expr>> && output, std::vector<ptr<Expr>> && input, 110 std::vector<ptr<ConstantExpr>> && clobber, std::vector<Label> && gotoLabels, 111 std::vector<Label> && labels = {}) 112 : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction), 113 output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)), 114 gotoLabels(std::move(gotoLabels)) {} 115 116 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 117 private: 119 118 AsmStmt * clone() const override { return new AsmStmt{ *this }; } 120 119 MUTATE_FRIEND 121 120 }; 122 121 123 // / C-preprocessor directive `#...`122 // C-preprocessor directive: #... 124 123 class DirectiveStmt final : public Stmt { 125 public:124 public: 126 125 std::string directive; 127 126 128 127 DirectiveStmt( const CodeLocation & loc, const std::string & directive, 129 std::vector<Label> && labels = {} )130 : Stmt(loc, std::move(labels)), directive(directive) {}131 132 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 133 private:128 std::vector<Label> && labels = {} ) 129 : Stmt(loc, std::move(labels)), directive(directive) {} 130 131 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 132 private: 134 133 DirectiveStmt * clone() const override { return new DirectiveStmt{ *this }; } 135 134 MUTATE_FRIEND 136 135 }; 137 136 138 // / If conditional statement `if (...) ... else ...`137 // If statement: if (...) ... else ... 139 138 class IfStmt final : public Stmt { 140 public:139 public: 141 140 ptr<Expr> cond; 142 141 ptr<Stmt> thenPart; … … 145 144 146 145 IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * thenPart, 147 const Stmt * elsePart = nullptr, std::vector<ptr<Stmt>> && inits = {},148 std::vector<Label> && labels = {} )149 : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart),150 inits(std::move(inits)) {}151 152 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 153 private:146 const Stmt * elsePart = nullptr, std::vector<ptr<Stmt>> && inits = {}, 147 std::vector<Label> && labels = {} ) 148 : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart), 149 inits(std::move(inits)) {} 150 151 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 152 private: 154 153 IfStmt * clone() const override { return new IfStmt{ *this }; } 155 154 MUTATE_FRIEND 156 155 }; 157 156 158 // / Switch or choose conditional statement `switch (...) { ... }`157 // Switch or choose statement: switch (...) { ... } 159 158 class SwitchStmt final : public Stmt { 160 public:159 public: 161 160 ptr<Expr> cond; 162 161 std::vector<ptr<Stmt>> stmts; 163 162 164 163 SwitchStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts, 165 std::vector<Label> && labels = {} )166 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}167 168 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 169 private:164 std::vector<Label> && labels = {} ) 165 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {} 166 167 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 168 private: 170 169 SwitchStmt * clone() const override { return new SwitchStmt{ *this }; } 171 170 MUTATE_FRIEND 172 171 }; 173 172 174 // / Case label `case ...:` `default:`173 // Case label: case ...: or default: 175 174 class CaseStmt final : public Stmt { 176 public:177 // /Null for the default label.175 public: 176 // Null for the default label. 178 177 ptr<Expr> cond; 179 178 std::vector<ptr<Stmt>> stmts; 180 179 181 180 CaseStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts, 182 std::vector<Label> && labels = {} )183 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}181 std::vector<Label> && labels = {} ) 182 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {} 184 183 185 184 bool isDefault() const { return !cond; } 186 185 187 186 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 188 private:187 private: 189 188 CaseStmt * clone() const override { return new CaseStmt{ *this }; } 190 189 MUTATE_FRIEND 191 190 }; 192 191 193 // / While loop `while (...) ...` `do ... while (...);192 // While loop: while (...) ... else ... or do ... while (...) else ...; 194 193 class WhileStmt final : public Stmt { 195 public:194 public: 196 195 ptr<Expr> cond; 197 196 ptr<Stmt> body; 197 ptr<Stmt> elsePart; 198 198 std::vector<ptr<Stmt>> inits; 199 199 bool isDoWhile; 200 200 201 201 WhileStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, 202 std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label> && labels = {} ) 203 : Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)), 204 isDoWhile(isDoWhile) {} 205 206 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 207 private: 202 std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label> && labels = {} ) 203 : Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)), isDoWhile(isDoWhile) {} 204 205 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 206 private: 208 207 WhileStmt * clone() const override { return new WhileStmt{ *this }; } 209 208 MUTATE_FRIEND 210 209 }; 211 210 212 // / For loop `for (... ; ... ; ...) ...`211 // For loop: for (... ; ... ; ...) ... else ... 213 212 class ForStmt final : public Stmt { 214 public:213 public: 215 214 std::vector<ptr<Stmt>> inits; 216 215 ptr<Expr> cond; 217 216 ptr<Expr> inc; 218 217 ptr<Stmt> body; 218 ptr<Stmt> elsePart; 219 219 220 220 ForStmt( const CodeLocation & loc, std::vector<ptr<Stmt>> && inits, const Expr * cond, 221 const Expr * inc, const Stmt * body, std::vector<Label> && labels = {} ) 222 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), 223 body(body) {} 224 225 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 226 private: 221 const Expr * inc, const Stmt * body, std::vector<Label> && labels = {} ) 222 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), body(body) {} 223 224 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 225 private: 227 226 ForStmt * clone() const override { return new ForStmt{ *this }; } 228 227 MUTATE_FRIEND 229 228 }; 230 229 231 // / Branch control flow statement `goto ...` `break` `continue` `fallthru`230 // Branch control flow statement: goto ... or break or continue or fallthru 232 231 class BranchStmt final : public Stmt { 233 public:232 public: 234 233 enum Kind { Goto, Break, Continue, FallThrough, FallThroughDefault }; 235 234 static constexpr size_t kindEnd = 1 + (size_t)FallThroughDefault; … … 241 240 242 241 BranchStmt( const CodeLocation & loc, Kind kind, Label target, 243 std::vector<Label> && labels = {} );242 std::vector<Label> && labels = {} ); 244 243 BranchStmt( const CodeLocation & loc, const Expr * computedTarget, 245 std::vector<Label> && labels = {} )246 : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc),247 computedTarget(computedTarget), kind(Goto) {}244 std::vector<Label> && labels = {} ) 245 : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc), 246 computedTarget(computedTarget), kind(Goto) {} 248 247 249 248 const char * kindName() const { return kindNames[kind]; } 250 249 251 250 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 252 private:251 private: 253 252 BranchStmt * clone() const override { return new BranchStmt{ *this }; } 254 253 MUTATE_FRIEND … … 257 256 }; 258 257 259 // / Return statement `return ...`258 // Return statement: return ... 260 259 class ReturnStmt final : public Stmt { 261 public:260 public: 262 261 ptr<Expr> expr; 263 262 264 263 ReturnStmt( const CodeLocation & loc, const Expr * expr, std::vector<Label> && labels = {} ) 265 : Stmt(loc, std::move(labels)), expr(expr) {}266 267 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 268 private:264 : Stmt(loc, std::move(labels)), expr(expr) {} 265 266 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 267 private: 269 268 ReturnStmt * clone() const override { return new ReturnStmt{ *this }; } 270 269 MUTATE_FRIEND 271 270 }; 272 271 273 // /Kind of exception272 // Kind of exception 274 273 enum ExceptionKind { Terminate, Resume }; 275 274 276 // / Throw statement `throw ...`275 // Throw statement: throw ... 277 276 class ThrowStmt final : public Stmt { 278 public:277 public: 279 278 ptr<Expr> expr; 280 279 ptr<Expr> target; … … 284 283 const CodeLocation & loc, ExceptionKind kind, const Expr * expr, const Expr * target, 285 284 std::vector<Label> && labels = {} ) 286 : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {}287 288 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 289 private:285 : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {} 286 287 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 288 private: 290 289 ThrowStmt * clone() const override { return new ThrowStmt{ *this }; } 291 290 MUTATE_FRIEND 292 291 }; 293 292 294 // / Try statement `try { ... } ...`293 // Try statement: try { ... } ... 295 294 class TryStmt final : public Stmt { 296 public:295 public: 297 296 ptr<CompoundStmt> body; 298 297 std::vector<ptr<CatchStmt>> handlers; … … 303 302 std::vector<ptr<CatchStmt>> && handlers, const FinallyStmt * finally, 304 303 std::vector<Label> && labels = {} ) 305 : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {}306 307 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 308 private:304 : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {} 305 306 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 307 private: 309 308 TryStmt * clone() const override { return new TryStmt{ *this }; } 310 309 MUTATE_FRIEND 311 310 }; 312 311 313 // /Catch clause of try statement312 // Catch clause of try statement 314 313 class CatchStmt final : public Stmt { 315 public:314 public: 316 315 ptr<Decl> decl; 317 316 ptr<Expr> cond; … … 322 321 const CodeLocation & loc, ExceptionKind kind, const Decl * decl, const Expr * cond, 323 322 const Stmt * body, std::vector<Label> && labels = {} ) 324 : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {}325 326 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 327 private:323 : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {} 324 325 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 326 private: 328 327 CatchStmt * clone() const override { return new CatchStmt{ *this }; } 329 328 MUTATE_FRIEND 330 329 }; 331 330 332 // /Finally clause of try statement331 // Finally clause of try statement 333 332 class FinallyStmt final : public Stmt { 334 public:333 public: 335 334 ptr<CompoundStmt> body; 336 335 337 336 FinallyStmt( const CodeLocation & loc, const CompoundStmt * body, 338 std::vector<Label> && labels = {} )339 : Stmt(loc, std::move(labels)), body(body) {}340 341 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 342 private:337 std::vector<Label> && labels = {} ) 338 : Stmt(loc, std::move(labels)), body(body) {} 339 340 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 341 private: 343 342 FinallyStmt * clone() const override { return new FinallyStmt{ *this }; } 344 343 MUTATE_FRIEND 345 344 }; 346 345 347 // /Suspend statement346 // Suspend statement 348 347 class SuspendStmt final : public Stmt { 349 public:348 public: 350 349 ptr<CompoundStmt> then; 351 350 enum Type { None, Coroutine, Generator } type = None; 352 351 353 352 SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Type type, std::vector<Label> && labels = {} ) 354 : Stmt(loc, std::move(labels)), then(then), type(type) {}355 356 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 357 private:353 : Stmt(loc, std::move(labels)), then(then), type(type) {} 354 355 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 356 private: 358 357 SuspendStmt * clone() const override { return new SuspendStmt{ *this }; } 359 358 MUTATE_FRIEND 360 359 }; 361 360 362 // / Wait for concurrency statement `when (...) waitfor (... , ...) ... timeout(...) ... else ...`361 // Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ... 363 362 class WaitForStmt final : public Stmt { 364 public:363 public: 365 364 struct Target { 366 365 ptr<Expr> func; … … 390 389 391 390 WaitForStmt( const CodeLocation & loc, std::vector<Label> && labels = {} ) 392 : Stmt(loc, std::move(labels)) {}393 394 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 395 private:391 : Stmt(loc, std::move(labels)) {} 392 393 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 394 private: 396 395 WaitForStmt * clone() const override { return new WaitForStmt{ *this }; } 397 396 MUTATE_FRIEND 398 397 }; 399 398 400 // /Any declaration in a (compound) statement.399 // Any declaration in a (compound) statement. 401 400 class DeclStmt final : public Stmt { 402 public:401 public: 403 402 ptr<Decl> decl; 404 403 405 404 DeclStmt( const CodeLocation & loc, const Decl * decl, std::vector<Label> && labels = {} ) 406 : Stmt(loc, std::move(labels)), decl(decl) {}407 408 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 409 private:405 : Stmt(loc, std::move(labels)), decl(decl) {} 406 407 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 408 private: 410 409 DeclStmt * clone() const override { return new DeclStmt{ *this }; } 411 410 MUTATE_FRIEND 412 411 }; 413 412 414 // /Represents an implicit application of a constructor or destructor.413 // Represents an implicit application of a constructor or destructor. 415 414 class ImplicitCtorDtorStmt final : public Stmt { 416 public:415 public: 417 416 ptr<Stmt> callStmt; 418 417 419 418 ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt * callStmt, 420 std::vector<Label> && labels = {} )421 : Stmt(loc, std::move(labels)), callStmt(callStmt) {}422 423 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 424 private:419 std::vector<Label> && labels = {} ) 420 : Stmt(loc, std::move(labels)), callStmt(callStmt) {} 421 422 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 423 private: 425 424 ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt{ *this }; } 426 425 MUTATE_FRIEND 427 426 }; 428 427 429 // /Mutex Statement428 // Mutex Statement 430 429 class MutexStmt final : public Stmt { 431 public:430 public: 432 431 ptr<Stmt> stmt; 433 432 std::vector<ptr<Expr>> mutexObjs; 434 433 435 434 MutexStmt( const CodeLocation & loc, const Stmt * stmt, 436 std::vector<ptr<Expr>> && mutexes, std::vector<Label> && labels = {} )437 : Stmt(loc, std::move(labels)), stmt(stmt), mutexObjs(std::move(mutexes)) {}438 439 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 440 private:435 std::vector<ptr<Expr>> && mutexes, std::vector<Label> && labels = {} ) 436 : Stmt(loc, std::move(labels)), stmt(stmt), mutexObjs(std::move(mutexes)) {} 437 438 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 439 private: 441 440 MutexStmt * clone() const override { return new MutexStmt{ *this }; } 442 441 MUTATE_FRIEND 443 442 }; 444 445 } 443 } // namespace ast 446 444 447 445 #undef MUTATE_FRIEND 448 446 449 447 // Local Variables: // 450 // tab-width: 4 //451 448 // mode: c++ // 452 // compile-command: "make install" //453 449 // End: //
Note: See TracChangeset
for help on using the changeset viewer.