This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- ast/Stmt.h -------------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008-2010, Stephen Wilson 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 // Stmt 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 // Support isa/dyn_cast. 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 // StmtSequence 00046 // 00047 // Represents a sequence of statements. 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 // Support isa/dyn_cast 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 // HandlerStmt 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 // Support isa/dyn_cast. 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 // BlockStmt 00201 // 00202 // Represents a block statement consisting of an optional identifier, a possibly 00203 // empty declarative region, and a sequence of statements constituting the body. 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 // Returns true if this block has an associated label. 00215 bool hasLabel() const { return label != 0; } 00216 00217 // Returns the label associated with this block, or 0 if there is no such 00218 // label. 00219 IdentifierInfo *getLabel() { return label; } 00220 00221 // Support isa/dyn_cast. 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 // ProcedureCallStmt 00233 // 00234 // Representation of a procedure call statement. 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 // Required since SubroutineCall::getLocation is pure virtual. 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 // Support isa and dyn_cast. 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 // ReturnStmt. 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 // AssignmentStmt 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 // Support isa/dyn_cast. 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 // IfStmt 00315 class IfStmt : public Stmt { 00316 00317 public: 00318 // IfStmt's are always constructed with a condition and a consequent. If 00319 // the statement contains "elsif" components, one must call addElsif for 00320 // each component. Similarly, one must call setAlternate to define the 00321 // "else" component. 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 // Returns the predicate expression controlling this IfStmt. 00330 Expr *getCondition() { return condition; } 00331 const Expr *getCondition() const { return condition; } 00332 00333 // Returns the statement associated with the "then" branch of this IfStmt. 00334 StmtSequence *getConsequent() { return consequent; } 00335 const StmtSequence *getConsequent() const { return consequent; } 00336 00337 // Sets the statement associated with the "else" branch of this IfStmt. 00338 void setAlternate(Location loc, StmtSequence *stmt) { 00339 assert(alternate == 0 && "Cannot reset IfStmt alternate!"); 00340 elseLocation = loc; 00341 alternate = stmt; 00342 } 00343 00344 // Returns true if this IfStmt has been supplied with an "else" clause. 00345 bool hasAlternate() const { return alternate != 0; } 00346 00347 // Returns the statement associated with the "else" clause, or 0 if no such 00348 // component exists. 00349 StmtSequence *getAlternate() { return alternate; } 00350 const StmtSequence *getAlternate() const { return alternate; } 00351 00352 // The following class is used to represent "elsif" components of a 00353 // conditional. 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 // The type used to store Elsif components. 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 // Adds an "elsif" branch to this IfStmt. The order in which this function 00391 // is called determines the order of the elsif branches. 00392 void addElsif(Location loc, Expr *condition, StmtSequence *consequent) { 00393 elsifs.push_back(Elsif(loc, condition, consequent)); 00394 } 00395 00396 // Returns true if this if statement contains elsif clauses. 00397 bool hasElsif() const { return !elsifs.empty(); } 00398 00399 // Returns the location of the "if" token. 00400 Location getIfLocation() const { return Stmt::getLocation(); } 00401 00402 // Returns the location of the "else" token if an alternate branch exists. 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 // WhileStmt 00420 // 00421 // Ast nodes representing the 'while' loop construct. 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 // Returns the condition expression controlling this loop. 00431 Expr *getCondition() { return condition; } 00432 const Expr *getCondition() const { return condition; } 00433 00434 // Returns the body of this loop. 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 // ForStmt 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 // Support isa/dyn_cast. 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 // LoopStmt 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 // Support isa/dyn_cast. 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 // PragmaStmt 00536 // 00537 // This is a simple Stmt node which wraps a pragma so that it can appear within 00538 // a sequence of statements. 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 // Support isa/dyn_cast. 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 // RaiseStmt 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 // Support isa/dyn_cast. 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 // NullStmt 00615 class NullStmt : public Stmt { 00616 00617 public: 00619 NullStmt(Location loc) : Stmt(AST_NullStmt, loc) { } 00620 00621 // Support isa/dyn_cast. 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 } // End comma namespace. 00629 00630 #endif