00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_TYPECHECK_SCOPE_HDR_GUARD
00010 #define COMMA_TYPECHECK_SCOPE_HDR_GUARD
00011 
00012 #include "Resolver.h"
00013 #include "comma/ast/AstBase.h"
00014 #include "comma/ast/Decl.h"
00015 
00016 #include "llvm/ADT/SmallPtrSet.h"
00017 
00018 #include <deque>
00019 
00020 namespace comma {
00021 
00022 class Homonym;
00023 
00024 enum ScopeKind {
00025     DEAD_SCOPE,             
00026     BASIC_SCOPE,            
00027     CUNIT_SCOPE,            
00028     MODEL_SCOPE,            
00029     SUBROUTINE_SCOPE,       
00030     RECORD_SCOPE            
00031 };
00032 
00033 class Scope {
00034 
00035 public:
00036 
00037     
00038     Scope();
00039 
00040     
00041     
00042     ~Scope();
00043 
00044     
00045     ScopeKind getKind() const;
00046 
00047     
00048     unsigned getLevel() const { return entries.size() - 1; }
00049 
00050     
00051     unsigned numEntries() const { return entries.size(); }
00052 
00053     
00054     void push(ScopeKind kind = BASIC_SCOPE);
00055 
00056     
00057     void pop();
00058 
00059     
00060     
00061     
00062     
00063     
00064     
00065     
00066     
00067     
00068     
00069     Decl *addDirectDecl(Decl *decl);
00070 
00071     
00072     
00073     void addDirectDeclNoConflicts(Decl *decl);
00074 
00075     
00076     
00077     
00078     bool addImport(DomainType *type);
00079 
00081     Resolver &getResolver() {
00082         resolver.clear();
00083         return resolver;
00084     }
00085 
00086     void dump() const;
00087 
00088 private:
00089     
00090     class Entry {
00091 
00092         
00093         typedef llvm::SmallPtrSet<Decl*, 16> DeclSet;
00094 
00095         
00096         typedef llvm::SmallVector<DomainType*, 8> ImportVector;
00097 
00098     public:
00099         Entry(ScopeKind kind, unsigned tag)
00100             : kind(kind),
00101               tag(tag) { }
00102 
00103         
00104         void initialize(ScopeKind kind, unsigned tag) {
00105             this->kind = kind;
00106             this->tag  = tag;
00107         }
00108 
00109         
00110         ScopeKind getKind() const { return kind; }
00111 
00112         unsigned getTag() const { return tag; }
00113 
00114         void addDirectDecl(Decl *decl);
00115 
00116         void removeDirectDecl(Decl *decl);
00117 
00118         void removeImportDecl(Decl *decl);
00119 
00120         
00121         unsigned numDirectDecls() const { return directDecls.size(); }
00122 
00123         
00124         
00125         bool containsDirectDecl(IdentifierInfo *name);
00126 
00127         
00128         
00129         bool containsDirectDecl(Decl *decl) {
00130             return directDecls.count(decl);
00131         }
00132 
00133         void addImportDecl(DomainType *type);
00134 
00135         
00136         unsigned numImportDecls() const { return importDecls.size(); }
00137 
00138         bool containsImportDecl(IdentifierInfo *name);
00139         bool containsImportDecl(DomainType *type);
00140 
00141         
00142         typedef DeclSet::const_iterator DirectIterator;
00143         DirectIterator beginDirectDecls() const { return directDecls.begin(); }
00144         DirectIterator endDirectDecls()   const { return directDecls.end(); }
00145 
00146         
00147         typedef ImportVector::const_iterator ImportIterator;
00148         ImportIterator beginImportDecls() const { return importDecls.begin(); }
00149         ImportIterator endImportDecls()  const { return importDecls.end(); }
00150 
00151         
00152         
00153         
00154         void clear();
00155 
00156     private:
00157         ScopeKind    kind;
00158         unsigned     tag;
00159         DeclSet      directDecls;
00160         ImportVector importDecls;
00161 
00162         static Homonym *getOrCreateHomonym(IdentifierInfo *info);
00163 
00164         void importDeclarativeRegion(DeclRegion *region);
00165         void clearDeclarativeRegion(DeclRegion *region);
00166     };
00167 
00168     
00169     typedef std::deque<Entry*> EntryStack;
00170     EntryStack entries;
00171 
00172     
00173     Resolver resolver;
00174 
00175     
00176     
00177     enum { ENTRY_CACHE_SIZE = 16 };
00178     Entry *entryCache[ENTRY_CACHE_SIZE];
00179 
00180     
00181     unsigned numCachedEntries;
00182 
00183     
00184     
00185     
00186     Decl *findConflictingDirectDecl(Decl *decl) const;
00187 
00188     
00189     bool directDeclsConflict(Decl *X, Decl *Y) const;
00190 };
00191 
00192 } 
00193 
00194 #endif