00001
00002
00003
00004
00005
00006
00007
00008
00009
00013
00014
00015 #ifndef COMMA_AST_ATTRIBEXPR_HDR_GUARD
00016 #define COMMA_AST_ATTRIBEXPR_HDR_GUARD
00017
00018 #include "comma/ast/Expr.h"
00019 #include "comma/basic/Attributes.h"
00020
00021 namespace comma {
00022
00023
00024
00025
00027 class AttribExpr : public Expr {
00028
00029 public:
00033 const Ast *getPrefix() const { return prefix; }
00034 Ast *getPrefix() { return prefix; }
00035
00037 attrib::AttributeID getAttributeID() const {
00038
00039 return static_cast<attrib::AttributeID>(bits);
00040 }
00041
00042
00043 static bool classof(const AttribExpr *node) { return true; }
00044 static bool classof(const Ast *node) {
00045 return node->denotesAttribExpr();
00046 }
00047
00048 protected:
00050 AttribExpr(AstKind kind, Ast *prefix, PrimaryType *type, Location loc)
00051 : Expr(kind, type, loc),
00052 prefix(prefix) {
00053 bits = correspondingID(kind);
00054 assert(this->denotesAttribExpr());
00055 assert(getAttributeID() != attrib::UNKNOWN_ATTRIBUTE);
00056 }
00057
00060 AttribExpr(AstKind kind, Ast *prefix, Location loc)
00061 : Expr(kind, loc),
00062 prefix(prefix) {
00063 bits = correspondingID(kind);
00064 assert(this->denotesAttribExpr());
00065 assert(getAttributeID() != attrib::UNKNOWN_ATTRIBUTE);
00066 }
00067
00070 static attrib::AttributeID correspondingID(AstKind kind);
00071
00072 Ast *prefix;
00073 };
00074
00075
00076
00077
00079 class ScalarBoundAE : public AttribExpr {
00080
00081 public:
00082 virtual ~ScalarBoundAE() { }
00083
00085 bool isFirst() const { return llvm::isa<FirstAE>(this); }
00086
00088 bool isLast() const { return llvm::isa<LastAE>(this); }
00089
00091
00092 const DiscreteType *getPrefix() const {
00093 return llvm::cast<DiscreteType>(prefix);
00094 }
00095 DiscreteType *getPrefix() {
00096 return llvm::cast<DiscreteType>(prefix);
00097 }
00099
00101
00102 const DiscreteType *getType() const {
00103 return llvm::cast<DiscreteType>(Expr::getType());
00104 }
00105 DiscreteType *getType() {
00106 return llvm::cast<DiscreteType>(Expr::getType());
00107 }
00109
00110
00111 static bool classof(const ScalarBoundAE *node) { return true; }
00112 static bool classof(const Ast *node) {
00113 AstKind kind = node->getKind();
00114 return (kind == AST_FirstAE || kind == AST_LastAE);
00115 }
00116
00117 protected:
00118 ScalarBoundAE(AstKind kind, DiscreteType *prefix, Location loc)
00119 : AttribExpr(kind, prefix, prefix, loc) {
00120 assert(kind == AST_FirstAE || kind == AST_LastAE);
00121 }
00122 };
00123
00124
00125
00126
00131 class FirstAE : public ScalarBoundAE {
00132
00133 public:
00134 FirstAE(DiscreteType *prefix, Location loc)
00135 : ScalarBoundAE(AST_FirstAE, prefix, loc) { }
00136
00137
00138 static bool classof(const FirstAE *node) { return true; }
00139 static bool classof(const Ast *node) {
00140 return node->getKind() == AST_FirstAE;
00141 }
00142 };
00143
00144
00145
00146
00151 class LastAE : public ScalarBoundAE {
00152
00153 public:
00154 LastAE(DiscreteType *prefix, Location loc)
00155 : ScalarBoundAE(AST_LastAE, prefix, loc) { }
00156
00157
00158 static bool classof(const LastAE *node) { return true; }
00159 static bool classof(const Ast *node) {
00160 return node->getKind() == AST_LastAE;
00161 }
00162 };
00163
00164
00165
00166
00169 class ArrayBoundAE : public AttribExpr {
00170
00171 public:
00174 bool hasImplicitDimension() const { return dimExpr == 0; }
00175
00177
00178
00179 Expr *getDimensionExpr() { return dimExpr; }
00180 const Expr *getDimensionExpr() const { return dimExpr; }
00182
00184 unsigned getDimension() const { return dimValue; }
00185
00187 bool isFirst() const;
00188
00190 bool isLast() const;
00191
00193
00194 const Expr *getPrefix() const {
00195 return llvm::cast<Expr>(prefix);
00196 }
00197 Expr *getPrefix() {
00198 return llvm::cast<Expr>(prefix);
00199 }
00201
00203
00204 const ArrayType *getPrefixType() const {
00205 return llvm::cast<ArrayType>(getPrefix()->getType());
00206 }
00207 ArrayType *getPrefixType() {
00208 return llvm::cast<ArrayType>(getPrefix()->getType());
00209 }
00211
00213
00214 const IntegerType *getType() const {
00215 return llvm::cast<IntegerType>(Expr::getType());
00216 }
00217 IntegerType *getType() {
00218 return llvm::cast<IntegerType>(Expr::getType());
00219 }
00221
00222
00223 static bool classof(const ArrayBoundAE *node) { return true; }
00224 static bool classof(const Ast *node) {
00225 AstKind kind = node->getKind();
00226 return (kind == AST_FirstArrayAE || kind == AST_LastArrayAE);
00227 }
00228
00229 protected:
00238 ArrayBoundAE(AstKind kind, Expr *prefix, Expr *dimension, Location loc);
00239
00246 ArrayBoundAE(AstKind kind, Expr *prefix, Location loc);
00247
00250 Expr *dimExpr;
00251
00254 unsigned dimValue;
00255 };
00256
00257
00258
00259
00264 class FirstArrayAE : public ArrayBoundAE {
00265
00266 public:
00275 FirstArrayAE(Expr *prefix, Expr *dimension, Location loc)
00276 : ArrayBoundAE(AST_FirstArrayAE, prefix, dimension, loc) { }
00277
00283 FirstArrayAE(Expr *prefix, Location loc)
00284 : ArrayBoundAE(AST_FirstArrayAE, prefix, loc) { }
00285
00286
00287 static bool classof(const FirstArrayAE *node) { return true; }
00288 static bool classof(const Ast *node) {
00289 return node->getKind() == AST_FirstArrayAE;
00290 }
00291 };
00292
00293
00294
00295
00300 class LastArrayAE : public ArrayBoundAE {
00301
00302 public:
00311 LastArrayAE(Expr *prefix, Expr *dimension, Location loc)
00312 : ArrayBoundAE(AST_LastArrayAE, prefix, dimension, loc) { }
00313
00319 LastArrayAE(Expr *prefix, Location loc)
00320 : ArrayBoundAE(AST_LastArrayAE, prefix, loc) { }
00321
00322
00323 static bool classof(const LastArrayAE *node) { return true; }
00324 static bool classof(const Ast *node) {
00325 return node->getKind() == AST_LastArrayAE;
00326 }
00327 };
00328
00329
00330
00331
00332 inline bool ArrayBoundAE::isFirst() const {
00333 return llvm::isa<FirstArrayAE>(this);
00334 }
00335
00336 inline bool ArrayBoundAE::isLast() const {
00337 return llvm::isa<LastArrayAE>(this);
00338 }
00339
00340 }
00341
00342 #endif