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