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