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