00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_AST_STMT_HDR_GUARD
00010 #define COMMA_AST_STMT_HDR_GUARD
00011
00012 #include "comma/ast/AstBase.h"
00013 #include "comma/ast/DeclRegion.h"
00014 #include "comma/ast/SubroutineCall.h"
00015
00016 namespace comma {
00017
00018 class Pragma;
00019
00020
00021
00022 class Stmt : public Ast {
00023
00024 protected:
00025 Stmt(AstKind kind, Location loc) : Ast(kind), location(loc) { }
00026
00027 public:
00029 Location getLocation() const { return location; }
00030
00032 bool isTerminator() const;
00033
00034
00035 static bool classof(const Stmt *node) { return true; }
00036 static bool classof(const Ast *node) {
00037 return node->denotesStmt();
00038 }
00039
00040 private:
00041 Location location;
00042 };
00043
00044
00045
00046
00047
00048 class StmtSequence : public Stmt {
00049
00050 typedef llvm::SmallVector<Stmt*, 16> StatementVec;
00051 typedef llvm::SmallVector<HandlerStmt*, 2> HandlerVec;
00052 StatementVec statements;
00053 HandlerVec handlers;
00054
00055 protected:
00056 StmtSequence(AstKind kind, Location loc) : Stmt(kind, loc) { }
00057
00058 public:
00059 StmtSequence(Location loc) : Stmt(AST_StmtSequence, loc) { }
00060
00062 template <class Iter>
00063 StmtSequence(Location loc, Iter I, Iter E)
00064 : Stmt(AST_StmtSequence, loc),
00065 statements(I, E) { }
00066
00068 void addStmt(Stmt *stmt) { statements.push_back(stmt); }
00069
00072 template <class Iter>
00073 void addStmts(Iter I, Iter E) {
00074 for ( ; I != E; ++I)
00075 statements.push_back(*I);
00076 }
00077
00079 unsigned numStatements() const { return statements.size(); }
00080
00082 bool isEmpty() const { return numStatements() == 0; }
00083
00085
00086 Stmt *front() { return statements.front(); }
00087 const Stmt *front() const { return statements.front(); }
00089
00091
00092 Stmt *back() { return statements.back(); }
00093 const Stmt *back() const { return statements.back(); }
00095
00097
00098 typedef StatementVec::iterator stmt_iter;
00099 stmt_iter stmt_begin() { return statements.begin(); }
00100 stmt_iter stmt_end() { return statements.end(); }
00101
00102 typedef StatementVec::const_iterator const_stmt_iter;
00103 const_stmt_iter stmt_begin() const { return statements.begin(); }
00104 const_stmt_iter stmt_end() const { return statements.end(); }
00106
00109 bool isHandled() const { return !handlers.empty(); }
00110
00112 unsigned numHandlers() const { return handlers.size(); }
00113
00116 bool hasCatchAll() const;
00117
00123 bool handles(const ExceptionDecl *exception) const;
00124
00129 void addHandler(HandlerStmt *handler) {
00130 assert(!hasCatchAll() && "Catch-all handler already present!");
00131 handlers.push_back(handler);
00132 }
00133
00135
00136 typedef HandlerVec::iterator handler_iter;
00137 handler_iter handler_begin() { return handlers.begin(); }
00138 handler_iter handler_end() { return handlers.end(); }
00139
00140 typedef HandlerVec::const_iterator const_handler_iter;
00141 const_handler_iter handler_begin() const { return handlers.begin(); }
00142 const_handler_iter handler_end() const { return handlers.end(); }
00144
00145
00146 static bool classof(const StmtSequence *node) { return true; }
00147 static bool classof(const Ast *node) {
00148 AstKind kind = node->getKind();
00149 return kind == AST_StmtSequence || kind == AST_BlockStmt ||
00150 kind == AST_HandlerStmt;
00151 }
00152 };
00153
00154
00155
00156
00158 class HandlerStmt : public StmtSequence {
00159
00160 public:
00165 HandlerStmt(Location loc, ExceptionRef **choices, unsigned numChoices);
00166
00168 unsigned getNumChoices() const { return numChoices; }
00169
00171 bool isCatchAll() const { return getNumChoices() == 0; }
00172
00174 bool handles(const ExceptionDecl *exception) const;
00175
00177
00178
00179 typedef ExceptionRef **choice_iterator;
00180 choice_iterator choice_begin() { return choices; }
00181 choice_iterator choice_end() { return choices + numChoices; }
00182
00183 typedef const ExceptionRef *const *const_choice_iterator;
00184 const_choice_iterator choice_begin() const { return choices; }
00185 const_choice_iterator choice_end() const { return choices + numChoices; }
00187
00188
00189 static bool classof(const HandlerStmt *node) { return true; }
00190 static bool classof(const Ast *node) {
00191 return node->getKind() == AST_HandlerStmt;
00192 }
00193
00194 private:
00195 unsigned numChoices;
00196 ExceptionRef **choices;
00197 };
00198
00199
00200
00201
00202
00203
00204 class BlockStmt : public StmtSequence, public DeclRegion {
00205
00206 public:
00207 BlockStmt(Location loc,
00208 DeclRegion *parent,
00209 IdentifierInfo *label = 0)
00210 : StmtSequence(AST_BlockStmt, loc),
00211 DeclRegion(AST_BlockStmt, parent),
00212 label(label) { }
00213
00214
00215 bool hasLabel() const { return label != 0; }
00216
00217
00218
00219 IdentifierInfo *getLabel() { return label; }
00220
00221
00222 static bool classof(const BlockStmt *node) { return true; }
00223 static bool classof(const Ast *node) {
00224 return node->getKind() == AST_BlockStmt;
00225 }
00226
00227 private:
00228 IdentifierInfo *label;
00229 };
00230
00231
00232
00233
00234
00235 class ProcedureCallStmt : public Stmt, public SubroutineCall {
00236
00237 public:
00238 ProcedureCallStmt(SubroutineRef *ref,
00239 Expr **positionalArgs, unsigned numPositional,
00240 KeywordSelector **keyedArgs, unsigned numKeys);
00241
00243 Location getLocation() const {
00244
00245 return Stmt::getLocation();
00246 }
00247
00249
00250 const ProcedureDecl *getConnective() const {
00251 return llvm::cast<ProcedureDecl>(SubroutineCall::getConnective());
00252 }
00253 ProcedureDecl *getConnective() {
00254 return llvm::cast<ProcedureDecl>(SubroutineCall::getConnective());
00255 }
00257
00258
00259 static bool classof(const ProcedureCallStmt *node) { return true; }
00260 static bool classof(const Ast *node) {
00261 return node->getKind() == AST_ProcedureCallStmt;
00262 }
00263 };
00264
00265
00266
00267 class ReturnStmt : public Stmt {
00268
00269 public:
00270 ReturnStmt(Location loc, Expr *expr = 0)
00271 : Stmt(AST_ReturnStmt, loc), returnExpr(expr) { }
00272
00273 ~ReturnStmt();
00274
00275 bool hasReturnExpr() const { return returnExpr != 0; }
00276
00277 const Expr *getReturnExpr() const { return returnExpr; }
00278 Expr *getReturnExpr() { return returnExpr; }
00279
00280 static bool classof(const ReturnStmt *node) { return true; }
00281 static bool classof(const Ast *node) {
00282 return node->getKind() == AST_ReturnStmt;
00283 }
00284
00285 private:
00286 Expr *returnExpr;
00287 };
00288
00289
00290
00291 class AssignmentStmt : public Stmt {
00292
00293 public:
00294 AssignmentStmt(Expr *target, Expr *value);
00295
00296 Expr *getTarget() { return target; }
00297 const Expr *getTarget() const { return target; }
00298
00299 Expr *getAssignedExpr() { return value; }
00300 const Expr *getAssignedExpr() const { return value; }
00301
00302
00303 static bool classof(const AssignmentStmt *node) { return true; }
00304 static bool classof(const Ast *node) {
00305 return node->getKind() == AST_AssignmentStmt;
00306 }
00307
00308 private:
00309 Expr *target;
00310 Expr *value;
00311 };
00312
00313
00314
00315 class IfStmt : public Stmt {
00316
00317 public:
00318
00319
00320
00321
00322 IfStmt(Location loc, Expr *condition, StmtSequence *consequent)
00323 : Stmt(AST_IfStmt, loc),
00324 elseLocation(0),
00325 condition(condition),
00326 consequent(consequent),
00327 alternate(0) { }
00328
00329
00330 Expr *getCondition() { return condition; }
00331 const Expr *getCondition() const { return condition; }
00332
00333
00334 StmtSequence *getConsequent() { return consequent; }
00335 const StmtSequence *getConsequent() const { return consequent; }
00336
00337
00338 void setAlternate(Location loc, StmtSequence *stmt) {
00339 assert(alternate == 0 && "Cannot reset IfStmt alternate!");
00340 elseLocation = loc;
00341 alternate = stmt;
00342 }
00343
00344
00345 bool hasAlternate() const { return alternate != 0; }
00346
00347
00348
00349 StmtSequence *getAlternate() { return alternate; }
00350 const StmtSequence *getAlternate() const { return alternate; }
00351
00352
00353
00354 class Elsif {
00355
00356 public:
00357 Location getLocation() const { return location; }
00358
00359 Expr *getCondition() { return condition; }
00360 const Expr *getCondition() const { return condition; }
00361
00362 StmtSequence *getConsequent() { return consequent; }
00363 const StmtSequence *getConsequent() const { return consequent; }
00364
00365 private:
00366 Elsif(Location loc, Expr *cond, StmtSequence *stmt)
00367 : location(loc), condition(cond), consequent(stmt) { }
00368
00369 friend class IfStmt;
00370
00371 Location location;
00372 Expr *condition;
00373 StmtSequence *consequent;
00374 };
00375
00376 private:
00377
00378 typedef llvm::SmallVector<Elsif, 2> ElsifVector;
00379
00380 public:
00381 typedef ElsifVector::iterator iterator;
00382 typedef ElsifVector::const_iterator const_iterator;
00383
00384 iterator beginElsif() { return elsifs.begin(); }
00385 iterator endElsif() { return elsifs.end(); }
00386
00387 const_iterator beginElsif() const { return elsifs.begin(); }
00388 const_iterator endElsif() const { return elsifs.end(); }
00389
00390
00391
00392 void addElsif(Location loc, Expr *condition, StmtSequence *consequent) {
00393 elsifs.push_back(Elsif(loc, condition, consequent));
00394 }
00395
00396
00397 bool hasElsif() const { return !elsifs.empty(); }
00398
00399
00400 Location getIfLocation() const { return Stmt::getLocation(); }
00401
00402
00403 Location getElseLocation() const { return elseLocation; }
00404
00405 static bool classof(const IfStmt *node) { return true; }
00406 static bool classof(const Ast *node) {
00407 return node->getKind() == AST_IfStmt;
00408 }
00409
00410 private:
00411 Location elseLocation;
00412 Expr *condition;
00413 StmtSequence *consequent;
00414 StmtSequence *alternate;
00415 ElsifVector elsifs;
00416 };
00417
00418
00419
00420
00421
00422 class WhileStmt : public Stmt {
00423
00424 public:
00425 WhileStmt(Location loc, Expr *condition, StmtSequence *body)
00426 : Stmt(AST_WhileStmt, loc),
00427 condition(condition),
00428 body(body) { }
00429
00430
00431 Expr *getCondition() { return condition; }
00432 const Expr *getCondition() const { return condition; }
00433
00434
00435 StmtSequence *getBody() { return body; }
00436 const StmtSequence *getBody() const { return body; }
00437
00438 static bool classof(const WhileStmt *node) { return true; }
00439 static bool classof(const Ast *node) {
00440 return node->getKind() == AST_WhileStmt;
00441 }
00442
00443 private:
00444 Expr *condition;
00445 StmtSequence *body;
00446 };
00447
00448
00449
00450
00452 class ForStmt : public Stmt {
00453
00454 public:
00457 ForStmt(Location loc, LoopDecl *iterationDecl, DSTDefinition *control);
00458
00460
00461 const LoopDecl *getLoopDecl() const { return iterationDecl; }
00462 LoopDecl *getLoopDecl() { return iterationDecl; }
00464
00466
00467 const DSTDefinition *getControl() const { return control; }
00468 DSTDefinition *getControl() { return control; }
00470
00472
00473
00474 const DiscreteType *getControlType() const {
00475 return getLoopDecl()->getType();
00476 }
00477 DiscreteType *getControlType() { return getLoopDecl()->getType(); }
00479
00481 bool isReversed() const { return bits == 1; }
00482
00484 void markAsReversed() { bits = 1; }
00485
00487
00488
00489
00490
00491 const StmtSequence *getBody() const { return &body; }
00492 StmtSequence *getBody() { return &body; }
00494
00495
00496 static bool classof(const ForStmt *node) { return true; }
00497 static bool classof(const Ast *node) {
00498 return node->getKind() == AST_ForStmt;
00499 }
00500
00501 private:
00502 LoopDecl *iterationDecl;
00503 DSTDefinition *control;
00504 StmtSequence body;
00505 };
00506
00507
00508
00509
00511 class LoopStmt : public Stmt {
00512
00513 public:
00514 LoopStmt(Location loc, StmtSequence *body)
00515 : Stmt(AST_LoopStmt, loc),
00516 body(body) { }
00517
00519
00520 const StmtSequence *getBody() const { return body; }
00521 StmtSequence *getBody() { return body; }
00523
00524
00525 static bool classof(const LoopStmt *node) { return true; }
00526 static bool classof(const Ast *node) {
00527 return node->getKind() == AST_LoopStmt;
00528 }
00529
00530 private:
00531 StmtSequence *body;
00532 };
00533
00534
00535
00536
00537
00538
00539 class PragmaStmt : public Stmt {
00540
00541 public:
00542 PragmaStmt(Pragma *pragma);
00543
00544 const Pragma *getPragma() const { return pragma; }
00545 Pragma *getPragma() { return pragma; }
00546
00547
00548 static bool classof(const PragmaStmt *node) { return true; }
00549 static bool classof(const Ast *node) {
00550 return node->getKind() == AST_PragmaStmt;
00551 }
00552
00553 private:
00554 Pragma *pragma;
00555 };
00556
00557
00558
00559 class RaiseStmt : public Stmt {
00560
00561 public:
00570 RaiseStmt(Location loc, ExceptionRef *exception, Expr *message = 0)
00571 : Stmt(AST_RaiseStmt, loc),
00572 ref(exception), message(message) { }
00573
00575
00576 const ExceptionDecl *getExceptionDecl() const;
00577 ExceptionDecl *getExceptionDecl();
00579
00581
00582 const ExceptionRef *getExceptionRef() const { return ref; }
00583 ExceptionRef *getExceptionRef() { return ref; }
00585
00587 bool hasMessage() const { return message != 0; }
00588
00591
00592 const Expr *getMessage() const { return message; }
00593 Expr *getMessage() { return message; }
00595
00597 void setMessage(Expr *message) { this->message = message; }
00598
00600 void setException(ExceptionRef *exception) { ref = exception; }
00601
00602
00603 static bool classof(const RaiseStmt *node) { return true; }
00604 static bool classof(const Ast *node) {
00605 return node->getKind() == AST_RaiseStmt;
00606 }
00607
00608 private:
00609 ExceptionRef *ref;
00610 Expr *message;
00611 };
00612
00613
00614
00615 class NullStmt : public Stmt {
00616
00617 public:
00619 NullStmt(Location loc) : Stmt(AST_NullStmt, loc) { }
00620
00621
00622 static bool classof(const NullStmt *node) { return true; }
00623 static bool classof(const Ast *node) {
00624 return node->getKind() == AST_NullStmt;
00625 }
00626 };
00627
00628 }
00629
00630 #endif