00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00023 
00024 
00025 #ifndef COMMA_TYPECHECK_STENCIL_HDR_GUARD
00026 #define COMMA_TYPECHECK_STENCIL_HDR_GUARD
00027 
00028 #include "comma/ast/AstBase.h"
00029 #include "comma/ast/Expr.h"
00030 
00031 #include "llvm/ADT/SmallVector.h"
00032 
00033 #include <utility>
00034 
00035 namespace comma {
00036 
00037 
00038 
00039 
00042 class ASTStencil {
00043 
00044 public:
00045     ASTStencil() { reset(); }
00046 
00048     void init(IdentifierInfo *name, Location loc) {
00049         this->name = name;
00050         this->location = loc;
00051     }
00052 
00054     virtual void reset() {
00055         validFlag = true;
00056         subBits = 0;
00057         name = 0;
00058         location = 0;
00059     }
00060 
00062     IdentifierInfo *getIdInfo() const { return name; }
00063 
00065     Location getLocation() const { return location; }
00066 
00068     bool isValid() const { return validFlag; }
00069 
00071     bool isInvalid() const { return !validFlag; }
00072 
00074     void markInvalid() { validFlag = false; }
00075 
00076 protected:
00077     IdentifierInfo *name;
00078     Location location;
00079     unsigned validFlag : 1;
00080     unsigned subBits : 8*sizeof(unsigned) - 1;
00081 };
00082 
00083 
00084 
00085 
00088 class ASTStencilReseter {
00089 public:
00090     ASTStencilReseter(ASTStencil &stencil) : stencil(stencil) { }
00091 
00092     ~ASTStencilReseter() { stencil.reset(); }
00093 private:
00094     ASTStencil &stencil;
00095 };
00096 
00097 
00098 
00099 
00101 class EnumDeclStencil : public ASTStencil {
00102 
00103 public:
00104     EnumDeclStencil() { reset(); }
00105 
00106     void reset() {
00107         ASTStencil::reset();
00108         elements.clear();
00109     }
00110 
00112     typedef std::pair<IdentifierInfo*, Location> IdLocPair;
00113 
00116     void addElement(IdentifierInfo *name, Location loc) {
00117         elements.push_back(IdLocPair(name, loc));
00118     }
00119 
00121     unsigned numElements() const { return elements.size(); }
00122 
00124     IdLocPair getElement(unsigned i) {
00125         assert(i < numElements() && "Index out of range!");
00126         return elements[i];
00127     }
00128 
00130     typedef llvm::SmallVector<IdLocPair, 8> ElemVec;
00131 
00133     ElemVec &getElements() { return elements; }
00134     const ElemVec &getElements() const { return elements; }
00135 
00137 
00138     typedef ElemVec::iterator elem_iterator;
00139     elem_iterator begin_elems() { return elements.begin(); }
00140     elem_iterator end_elems() { return elements.end(); }
00142 
00144     void markAsCharacterType() { subBits = 1; }
00145 
00147     bool isCharacterType() const { return subBits == 1; }
00148 
00149 private:
00150     ElemVec elements;           
00151 };
00152 
00153 
00154 
00155 
00157 class SRDeclStencil : public ASTStencil {
00158 
00159 public:
00160     SRDeclStencil() { reset(); }
00161 
00162     enum StencilKind {
00163         UNKNOWN_Stencil,        
00164         FUNCTION_Stencil,       
00165         PROCEDURE_Stencil       
00166     };
00167 
00168     void init(IdentifierInfo *name, Location loc, StencilKind kind) {
00169         ASTStencil::init(name, loc);
00170         this->subBits = kind;
00171     }
00172 
00173     void reset() {
00174         ASTStencil::reset();
00175         returnTy = 0;
00176         subBits = UNKNOWN_Stencil;
00177         params.clear();
00178     };
00179 
00181     bool denotesProcedure() const { return subBits == PROCEDURE_Stencil; }
00182 
00184     bool denotesFunction() const { return subBits == FUNCTION_Stencil; }
00185 
00187     void addParameter(ParamValueDecl *param) { params.push_back(param); }
00188 
00190     unsigned numParameters() const { return params.size(); }
00191 
00193     ParamValueDecl *getParameter(unsigned i) {
00194         assert(i < numParameters() && "Index out of range!");
00195         return params[i];
00196     }
00197 
00199     typedef llvm::SmallVector<ParamValueDecl*, 8> ParamVec;
00200 
00202     ParamVec &getParams() { return params; }
00203     const ParamVec &getParams() const { return params; }
00204 
00206 
00207     typedef ParamVec::iterator param_iterator;
00208     param_iterator begin_params() { return params.begin(); }
00209     param_iterator end_params() { return params.end(); }
00211 
00214     void setReturnType(TypeDecl *retTy) {
00215         assert(denotesFunction() && "Wrong type of stencil for return type!");
00216         returnTy = retTy;
00217 
00218     }
00219 
00222     TypeDecl *getReturnType() { return returnTy; }
00223 
00224 private:
00225     ParamVec params;            
00226     TypeDecl *returnTy;         
00227 };
00228 
00229 } 
00230 
00231 #endif