This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- typecheck/Scope.h ------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008-2010, Stephen Wilson 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 // Creates an initial compilation unit scope. 00038 Scope(); 00039 00040 // On destruction, all frames associated with this scope object are cleared 00041 // as though thru repeated calls to popScope(). 00042 ~Scope(); 00043 00044 // Returns the kind of this scope. 00045 ScopeKind getKind() const; 00046 00047 // Returns the current nesting level, zero based. 00048 unsigned getLevel() const { return entries.size() - 1; } 00049 00050 // Returns the number of ScopeEntries currently being managed. 00051 unsigned numEntries() const { return entries.size(); } 00052 00053 // Pushes a fresh scope of the given kind. 00054 void push(ScopeKind kind = BASIC_SCOPE); 00055 00056 // Moves the scope up one level and unlinks all declarations. 00057 void pop(); 00058 00059 // Registers the given decl with the current scope. 00060 // 00061 // There is only one kind of declaration node which is inadmissible to a 00062 // Scope, namely DomainInstanceDecls. For these declarations the 00063 // corresponding DomoidDecl's are used for lookup. 00064 // 00065 // This method looks for any extant direct declarations which conflict with 00066 // the given decl. If such a declaration is found, it is returned and the 00067 // given node is not inserted into the scope. Otherwise, null is returned 00068 // and the decl is registered. 00069 Decl *addDirectDecl(Decl *decl); 00070 00071 // Adds the given decl to the scope unconditionally. This method will 00072 // assert in debug builds if a conflict is found. 00073 void addDirectDeclNoConflicts(Decl *decl); 00074 00075 // Adds an import into the scope, making all of the exports from the given 00076 // type indirectly visible. Returns true if the given type has already been 00077 // imported and false otherwise. 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 // An entry in a Scope object. 00090 class Entry { 00091 00092 // The set of lexical declarations associated with this entry. 00093 typedef llvm::SmallPtrSet<Decl*, 16> DeclSet; 00094 00095 // Collection of imports associated with this entry. 00096 typedef llvm::SmallVector<DomainType*, 8> ImportVector; 00097 00098 public: 00099 Entry(ScopeKind kind, unsigned tag) 00100 : kind(kind), 00101 tag(tag) { } 00102 00103 // Reinitializes this frame to the specified kind. 00104 void initialize(ScopeKind kind, unsigned tag) { 00105 this->kind = kind; 00106 this->tag = tag; 00107 } 00108 00109 // Returns the kind of this entry. 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 // Returns the number of direct declarations managed by this entry. 00121 unsigned numDirectDecls() const { return directDecls.size(); } 00122 00123 // Returns true if this entry contains a direct declaration bound to the 00124 // given name. 00125 bool containsDirectDecl(IdentifierInfo *name); 00126 00127 // Returns true if this the given declaration is directly visible in 00128 // this entry. 00129 bool containsDirectDecl(Decl *decl) { 00130 return directDecls.count(decl); 00131 } 00132 00133 void addImportDecl(DomainType *type); 00134 00135 // Returns the number of imported declarations managed by this frame. 00136 unsigned numImportDecls() const { return importDecls.size(); } 00137 00138 bool containsImportDecl(IdentifierInfo *name); 00139 bool containsImportDecl(DomainType *type); 00140 00141 // Iterators over the direct declarations managed by this frame. 00142 typedef DeclSet::const_iterator DirectIterator; 00143 DirectIterator beginDirectDecls() const { return directDecls.begin(); } 00144 DirectIterator endDirectDecls() const { return directDecls.end(); } 00145 00146 // Iterators over the imports managed by this frame. 00147 typedef ImportVector::const_iterator ImportIterator; 00148 ImportIterator beginImportDecls() const { return importDecls.begin(); } 00149 ImportIterator endImportDecls() const { return importDecls.end(); } 00150 00151 // Turns this into an uninitialized (dead) scope entry. This method is 00152 // used so that entries can be cached and recognized as inactive 00153 // objects. 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 // Type of stack used to maintain our scope frames. 00169 typedef std::deque<Entry*> EntryStack; 00170 EntryStack entries; 00171 00172 // A Resolver instance to facilitate user lookups. 00173 Resolver resolver; 00174 00175 // We cache the following number of entries to help ease allocation 00176 // pressure. 00177 enum { ENTRY_CACHE_SIZE = 16 }; 00178 Entry *entryCache[ENTRY_CACHE_SIZE]; 00179 00180 // Number of entries currently cached and available for reuse. 00181 unsigned numCachedEntries; 00182 00183 // If the given declaration conflicts with another declaration in the 00184 // current entry, return the declaration with which it conflicts. 00185 // Otherwise, return null. 00186 Decl *findConflictingDirectDecl(Decl *decl) const; 00187 00188 // Returns true if the given declarations conflict. 00189 bool directDeclsConflict(Decl *X, Decl *Y) const; 00190 }; 00191 00192 } // End comma namespace 00193 00194 #endif