00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/ast/AstBase.h"
00010 #include "comma/ast/DeclRegion.h"
00011 #include "llvm/ADT/SmallVector.h"
00012
00013 #ifndef COMMA_AST_STMT_HDR_GUARD
00014 #define COMMA_AST_STMT_HDR_GUARD
00015
00016 namespace comma {
00017
00018
00019
00020 class Stmt : public Ast {
00021
00022 protected:
00023 Stmt(AstKind kind) : Ast(kind) { }
00024
00025 public:
00026 static bool classof(const Stmt *node) { return true; }
00027 static bool classof(const Ast *node) {
00028 return node->denotesStmt();
00029 }
00030 };
00031
00032
00033
00034
00035
00036 class StmtSequence : public Stmt {
00037
00038 llvm::SmallVector<Stmt*, 16> statements;
00039
00040 protected:
00041 StmtSequence(AstKind kind) : Stmt(kind) { }
00042
00043 public:
00044 StmtSequence() : Stmt(AST_StmtSequence) { }
00045
00046 void addStmt(Stmt *stmt) { statements.push_back(stmt); }
00047
00048 typedef llvm::SmallVector<Stmt*, 16>::iterator StmtIter;
00049 StmtIter beginStatements() { return statements.begin(); }
00050 StmtIter endStatements() { return statements.end(); }
00051
00052 typedef llvm::SmallVector<Stmt*, 16>::const_iterator ConstStmtIter;
00053 ConstStmtIter beginStatements() const { return statements.begin(); }
00054 ConstStmtIter endStatements() const { return statements.end(); }
00055
00056 static bool classof(const StmtSequence *node) { return true; }
00057 static bool classof(const Ast *node) {
00058 return node->getKind() == AST_StmtSequence ||
00059 node->getKind() == AST_BlockStmt;
00060 }
00061 };
00062
00063
00064
00065
00066
00067
00068 class BlockStmt : public StmtSequence, public DeclRegion {
00069
00070 public:
00071 BlockStmt(Location loc,
00072 DeclRegion *parent,
00073 IdentifierInfo *label = 0)
00074 : StmtSequence(AST_BlockStmt),
00075 DeclRegion(AST_BlockStmt, parent),
00076 location(loc),
00077 label(label) { }
00078
00079
00080 bool hasLabel() const { return label != 0; }
00081
00082
00083
00084 IdentifierInfo *getLabel() { return label; }
00085
00086 Location getLocation() { return location; }
00087
00088 static bool classof(const BlockStmt *node) { return true; }
00089 static bool classof(const Ast *node) {
00090 return node->getKind() == AST_BlockStmt;
00091 }
00092
00093 private:
00094 Location location;
00095 IdentifierInfo *label;
00096 };
00097
00098
00099
00100
00101
00102 class ProcedureCallStmt : public Stmt {
00103
00104 public:
00105 ProcedureCallStmt(ProcedureDecl *connective,
00106 Expr **arguments,
00107 unsigned numArgs,
00108 Location loc);
00109
00110 ~ProcedureCallStmt();
00111
00112 ProcedureDecl *getConnective() const { return connective; }
00113
00114 unsigned getNumArgs() const { return numArgs; }
00115
00116 Expr *getArg(unsigned i) {
00117 assert(i < numArgs && "Index out of range!");
00118 return arguments[i];
00119 }
00120
00121 Location getLocation() const { return location; }
00122
00123 static bool classof(const ProcedureCallStmt *node) { return true; }
00124 static bool classof(const Ast *node) {
00125 return node->getKind() == AST_ProcedureCallStmt;
00126 }
00127
00128 private:
00129 ProcedureDecl *connective;
00130 Expr **arguments;
00131 unsigned numArgs;
00132 Location location;
00133 };
00134
00135
00136
00137 class ReturnStmt : public Stmt {
00138
00139 Expr *returnExpr;
00140 Location location;
00141
00142 public:
00143 ReturnStmt(Location loc, Expr *expr = 0)
00144 : Stmt(AST_ReturnStmt), returnExpr(expr), location(loc) { }
00145
00146 ~ReturnStmt();
00147
00148 bool hasReturnExpr() const { return returnExpr != 0; }
00149
00150 const Expr *getReturnExpr() const { return returnExpr; }
00151 Expr *getReturnExpr() { return returnExpr; }
00152
00153
00154 Location getLocation() const { return location; }
00155
00156 static bool classof(const ReturnStmt *node) { return true; }
00157 static bool classof(const Ast *node) {
00158 return node->getKind() == AST_ReturnStmt;
00159 }
00160 };
00161
00162
00163
00164 class AssignmentStmt : public Stmt {
00165
00166 DeclRefExpr *target;
00167 Expr *value;
00168
00169 public:
00170 AssignmentStmt(DeclRefExpr *target, Expr *value)
00171 : Stmt(AST_AssignmentStmt), target(target), value(value) { }
00172
00173 DeclRefExpr *getTarget() { return target; }
00174 const DeclRefExpr *getTarget() const { return target; }
00175
00176 Expr *getAssignedExpr() { return value; }
00177 const Expr *getAssignmentExpr() const { return value; }
00178
00179 static bool classof(const AssignmentStmt *node) { return true; }
00180 static bool classof(const Ast *node) {
00181 return node->getKind() == AST_AssignmentStmt;
00182 }
00183 };
00184
00185
00186
00187 class IfStmt : public Stmt {
00188
00189 public:
00190
00191
00192
00193
00194 IfStmt(Location loc, Expr *condition, StmtSequence *consequent)
00195 : Stmt(AST_IfStmt),
00196 ifLocation(loc),
00197 elseLocation(0),
00198 condition(condition),
00199 consequent(consequent),
00200 alternate(0) { }
00201
00202
00203 Expr *getCondition() { return condition; }
00204 const Expr *getCondition() const { return condition; }
00205
00206
00207 Stmt *getConsequent() { return consequent; }
00208 const Stmt *getConsequent() const { return consequent; }
00209
00210
00211 void setAlternate(Location loc, StmtSequence *stmt) {
00212 assert(alternate == 0 && "Cannot reset IfStmt alternate!");
00213 elseLocation = loc;
00214 alternate = stmt;
00215 }
00216
00217
00218 bool hasAlternate() const { return alternate != 0; }
00219
00220
00221
00222 StmtSequence *getAlternate() { return alternate; }
00223 const StmtSequence *getAlternate() const { return alternate; }
00224
00225
00226
00227 class Elsif {
00228
00229 public:
00230 Location getLocation() const { return location; }
00231
00232 Expr *getCondition() { return condition; }
00233 const Expr *getCondition() const { return condition; }
00234
00235 StmtSequence *getConsequent() { return consequent; }
00236 const StmtSequence *getConsequent() const { return consequent; }
00237
00238 private:
00239 Elsif(Location loc, Expr *cond, StmtSequence *stmt)
00240 : location(loc), condition(cond), consequent(stmt) { }
00241
00242 friend class IfStmt;
00243
00244 Location location;
00245 Expr *condition;
00246 StmtSequence *consequent;
00247 };
00248
00249 private:
00250
00251 typedef llvm::SmallVector<Elsif, 2> ElsifVector;
00252
00253 public:
00254 typedef ElsifVector::iterator iterator;
00255 typedef ElsifVector::const_iterator const_iterator;
00256
00257 iterator beginElsif() { return elsifs.begin(); }
00258 iterator endElsif() { return elsifs.end(); }
00259
00260 const_iterator beginElsif() const { return elsifs.begin(); }
00261 const_iterator endElsif() const { return elsifs.end(); }
00262
00263
00264
00265 void addElsif(Location loc, Expr *condition, StmtSequence *consequent) {
00266 elsifs.push_back(Elsif(loc, condition, consequent));
00267 }
00268
00269
00270 bool hasElsif() const { return !elsifs.empty(); }
00271
00272
00273 Location getIfLocation() const { return ifLocation; }
00274
00275
00276 Location getElseLocation() const { return elseLocation; }
00277
00278
00279 void dump(unsigned depth = 0);
00280
00281 static bool classof(const IfStmt *node) { return true; }
00282 static bool classof(const Ast *node) {
00283 return node->getKind() == AST_IfStmt;
00284 }
00285
00286 private:
00287 Location ifLocation;
00288 Location elseLocation;
00289 Expr *condition;
00290 StmtSequence *consequent;
00291 StmtSequence *alternate;
00292 ElsifVector elsifs;
00293 };
00294
00295 }
00296
00297 #endif