00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_AST_RANGEATTRIB_HDR_GUARD
00010 #define COMMA_AST_RANGEATTRIB_HDR_GUARD
00011
00012 #include "comma/ast/AstBase.h"
00013 #include "comma/ast/Expr.h"
00014
00015 namespace comma {
00016
00017
00018
00019
00021 class RangeAttrib : public Ast {
00022
00023 public:
00025
00026
00027
00028 const Ast *getPrefix() const { return prefix; }
00029 Ast *getPrefix() { return prefix; }
00031
00033 Location getLocation() const { return loc; }
00034
00036
00037 virtual const DiscreteType *getType() const = 0;
00038 virtual DiscreteType *getType() = 0;
00040
00041
00042 static bool classof(const RangeAttrib *node) { return true; }
00043 static bool classof(const Ast *node) {
00044 return denotesRangeAttrib(node->getKind());
00045 }
00046
00047 protected:
00048 RangeAttrib(AstKind kind, Ast *prefix, Location loc)
00049 : Ast(kind), prefix(prefix), loc(loc) { }
00050
00051 static bool denotesRangeAttrib(AstKind kind) {
00052 return (kind == AST_ScalarRangeAttrib || kind == AST_ArrayRangeAttrib);
00053 }
00054
00055 private:
00056 Ast *prefix;
00057 Location loc;
00058 };
00059
00060
00061
00062
00065 class ArrayRangeAttrib : public RangeAttrib
00066 {
00067 public:
00071 ArrayRangeAttrib(Expr *prefix, Expr *dimension, Location loc)
00072 : RangeAttrib(AST_ArrayRangeAttrib, prefix, loc),
00073 dimExpr(dimension) {
00074 assert(llvm::isa<ArrayType>(prefix->getType()) &&
00075 "Invalid prefix for array range attribute!");
00076 assert(dimension->isStaticDiscreteExpr() &&
00077 "Non-static dimension given to range attribute!");
00078 llvm::APInt value;
00079 dimension->staticDiscreteValue(value);
00080 dimValue = value.getZExtValue();
00081 }
00082
00084 ArrayRangeAttrib(Expr *prefix, Location loc)
00085 : RangeAttrib(AST_ArrayRangeAttrib, prefix, loc),
00086 dimExpr(0), dimValue(0) {
00087 assert(llvm::isa<ArrayType>(prefix->getType()) &&
00088 "Invalid prefix for array range attribute!");
00089 }
00090
00092
00093 const Expr *getPrefix() const {
00094 return llvm::cast<Expr>(RangeAttrib::getPrefix());
00095 }
00096 Expr *getPrefix() {
00097 return llvm::cast<Expr>(RangeAttrib::getPrefix());
00098 }
00100
00103 bool hasImplicitDimension() const { return dimExpr == 0; }
00104
00106
00107
00108
00109
00110 Expr *getDimensionExpr() { return dimExpr; }
00111 const Expr *getDimensionExpr() const { return dimExpr; }
00113
00115 unsigned getDimension() const { return dimValue; }
00116
00118
00119 const DiscreteType *getType() const {
00120 const ArrayType *arrTy = llvm::cast<ArrayType>(getPrefix()->getType());
00121 return arrTy->getIndexType(dimValue);
00122 };
00123
00124 DiscreteType *getType() {
00125 ArrayType *arrTy = llvm::cast<ArrayType>(getPrefix()->getType());
00126 return arrTy->getIndexType(dimValue);
00127 }
00129
00130
00131 static bool classof(const ArrayRangeAttrib *node) { return true; }
00132 static bool classof(const Ast *node) {
00133 return node->getKind() == AST_ArrayRangeAttrib;
00134 }
00135
00136 private:
00139 Expr *dimExpr;
00140
00143 unsigned dimValue;
00144 };
00145
00146
00147
00148
00150 class ScalarRangeAttrib : public RangeAttrib
00151 {
00152 public:
00153 ScalarRangeAttrib(DiscreteType *prefix, Location loc)
00154 : RangeAttrib(AST_ScalarRangeAttrib, prefix, loc) { }
00155
00157
00158 const DiscreteType *getPrefix() const {
00159 return llvm::cast<DiscreteType>(RangeAttrib::getPrefix());
00160 }
00161 DiscreteType *getPrefix() {
00162 return llvm::cast<DiscreteType>(RangeAttrib::getPrefix());
00163 }
00165
00167
00168 const DiscreteType *getType() const { return getPrefix(); }
00169 DiscreteType *getType() { return getPrefix(); }
00171
00172
00173 static bool classof(const ScalarRangeAttrib *node) { return true; }
00174 static bool classof(const Ast *node) {
00175 return node->getKind() == AST_ScalarRangeAttrib;
00176 }
00177 };
00178
00179 }
00180
00181 #endif