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