00001 //===-- ast/Range.h ------------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 //===----------------------------------------------------------------------===// 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef COMMA_AST_RANGE_HDR_GUARD 00016 #define COMMA_AST_RANGE_HDR_GUARD 00017 00018 #include "comma/ast/AstBase.h" 00019 00020 #include "llvm/ADT/APInt.h" 00021 #include "llvm/ADT/PointerIntPair.h" 00022 00023 namespace comma { 00024 00025 //===----------------------------------------------------------------------===// 00026 // Range 00027 // 00029 class Range : public Ast { 00030 00031 public: 00044 Range(Expr *lower, Expr *upper, DiscreteType *type = 0); 00045 00047 Location getLowerLocation() const; 00048 00050 Location getUpperLocation() const; 00051 00053 bool hasType() const { return rangeTy != 0; } 00054 00057 void setType(DiscreteType *type) { 00058 assert(!hasType() && "Range already associated with a type!"); 00059 rangeTy = type; 00060 checkAndAdjustLimits(); 00061 } 00062 00064 00065 DiscreteType *getType() { return rangeTy; } 00066 const DiscreteType *getType() const { return rangeTy; } 00068 00070 00071 Expr *getLowerBound() { return lowerBound.getPointer(); } 00072 const Expr *getLowerBound() const { return lowerBound.getPointer(); } 00074 00076 00077 Expr *getUpperBound() { return upperBound.getPointer(); } 00078 const Expr *getUpperBound() const { return upperBound.getPointer(); } 00080 00082 void setLowerBound(Expr *expr); 00083 00085 void setUpperBound(Expr *expr); 00086 00088 bool hasStaticLowerBound() const { return lowerBound.getInt(); } 00089 00091 bool hasStaticUpperBound() const { return upperBound.getInt(); } 00092 00097 bool isStatic() const { 00098 return hasStaticLowerBound() && hasStaticUpperBound(); 00099 } 00100 00102 const llvm::APInt &getStaticLowerBound() const { 00103 assert(hasStaticLowerBound() && "Lower bound not static!"); 00104 return lowerValue; 00105 } 00106 00108 const llvm::APInt &getStaticUpperBound() const { 00109 assert(hasStaticUpperBound() && "Upper bound not static!"); 00110 return upperValue; 00111 } 00112 00115 bool isNull() const; 00116 00120 bool contains(const llvm::APInt &value) const; 00121 00125 uint64_t length() const; 00126 00127 // Support isa/dyn_cast. 00128 static bool classof(const Range *node) { return true; } 00129 static bool classof(const Ast *node) { 00130 return node->getKind() == AST_Range; 00131 } 00132 00133 private: 00134 Range(const Range &); // Do not implement. 00135 00139 void initializeStaticBounds(); 00140 00145 void checkAndAdjustLimits(); 00146 00148 00149 00150 void markLowerAsStatic() { lowerBound.setInt(1); } 00151 void markUpperAsStatic() { upperBound.setInt(1); } 00153 00155 00156 void markLowerAsDynamic() { lowerBound.setInt(0); } 00157 void markUpperAsDynamic() { upperBound.setInt(0); } 00159 00160 typedef llvm::PointerIntPair<Expr *, 1> PtrInt; 00161 PtrInt lowerBound; 00162 PtrInt upperBound; 00163 llvm::APInt lowerValue; 00164 llvm::APInt upperValue; 00165 DiscreteType *rangeTy; 00166 }; 00167 00168 } // end comma namespace. 00169 00170 #endif