00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "Homonym.h"
00010 #include "Scope.h"
00011 #include "comma/basic/IdentifierInfo.h"
00012 #include "comma/ast/Decl.h"
00013 #include "comma/ast/Type.h"
00014
00015 #include "llvm/Support/Casting.h"
00016 #include "llvm/Support/DataTypes.h"
00017
00018 #include <iostream>
00019
00020 using namespace comma;
00021 using llvm::dyn_cast;
00022 using llvm::dyn_cast_or_null;
00023 using llvm::cast;
00024 using llvm::isa;
00025
00026
00027
00028
00029 bool Scope::Entry::containsImportDecl(DomainType *type)
00030 {
00031 ImportIterator endIter = endImportDecls();
00032
00033 for (ImportIterator iter = beginImportDecls(); iter != endIter; ++iter)
00034 if (type == *iter) return true;
00035 return false;
00036 }
00037
00038 bool Scope::Entry::containsImportDecl(IdentifierInfo *name)
00039 {
00040 ImportIterator endIter = endImportDecls();
00041
00042 for (ImportIterator iter = beginImportDecls(); iter != endIter; ++iter)
00043 if (name == (*iter)->getIdInfo()) return true;
00044 return false;
00045 }
00046
00047 void Scope::Entry::addDirectDecl(Decl *decl)
00048 {
00049 if (directDecls.insert(decl)) {
00050 IdentifierInfo *idInfo = decl->getIdInfo();
00051 Homonym *homonym = getOrCreateHomonym(idInfo);
00052 homonym->addDirectDecl(decl);
00053 }
00054 }
00055
00056 void Scope::Entry::removeDirectDecl(Decl *decl)
00057 {
00058 assert(containsDirectDecl(decl) &&
00059 "Declaration not associated with this scope entry!");
00060
00061 IdentifierInfo *info = decl->getIdInfo();
00062 Homonym *homonym = info->getMetadata<Homonym>();
00063 assert(homonym && "No identifier metadata!");
00064
00065 for (Homonym::DirectIterator iter = homonym->beginDirectDecls();
00066 iter != homonym->endDirectDecls(); ++iter)
00067 if (decl == *iter) {
00068 homonym->eraseDirectDecl(iter);
00069 return;
00070 }
00071 assert(false && "Decl not associated with corresponding identifier!");
00072 }
00073
00074 void Scope::Entry::removeImportDecl(Decl *decl)
00075 {
00076 IdentifierInfo *info = decl->getIdInfo();
00077 Homonym *homonym = info->getMetadata<Homonym>();
00078 assert(homonym && "No identifier metadata!");
00079
00080 for (Homonym::ImportIterator iter = homonym->beginImportDecls();
00081 iter != homonym->endImportDecls(); ++iter)
00082 if (decl == *iter) {
00083 homonym->eraseImportDecl(iter);
00084 return;
00085 }
00086 assert(false && "Decl not associated with corresponding indentifier!");
00087 }
00088
00089 bool Scope::Entry::containsDirectDecl(IdentifierInfo *name)
00090 {
00091 DirectIterator endIter = endDirectDecls();
00092 for (DirectIterator iter = beginDirectDecls(); iter != endIter; ++iter)
00093 if (name == (*iter)->getIdInfo()) return true;
00094 return false;
00095 }
00096
00097 void Scope::Entry::importDeclarativeRegion(DeclRegion *region)
00098 {
00099 typedef DeclRegion::DeclIter DeclIter;
00100
00101 DeclIter iter;
00102 DeclIter endIter = region->endDecls();
00103 for (iter = region->beginDecls(); iter != endIter; ++iter) {
00104 Decl *decl = *iter;
00105 IdentifierInfo *idinfo = decl->getIdInfo();
00106 Homonym *homonym = getOrCreateHomonym(idinfo);
00107
00108 homonym->addImportDecl(decl);
00109
00110
00111 if (EnumerationDecl *edecl = dyn_cast<EnumerationDecl>(decl))
00112 importDeclarativeRegion(edecl);
00113 else if (IntegerDecl *idecl = dyn_cast<IntegerDecl>(decl))
00114 importDeclarativeRegion(idecl);
00115 }
00116 }
00117
00118 void Scope::Entry::clearDeclarativeRegion(DeclRegion *region)
00119 {
00120 typedef DeclRegion::DeclIter DeclIter;
00121
00122 DeclIter iter;
00123 DeclIter endIter = region->endDecls();
00124 for (iter = region->beginDecls(); iter != endIter; ++iter) {
00125 Decl *decl = *iter;
00126 removeImportDecl(decl);
00127
00128 if (EnumerationDecl *edecl = dyn_cast<EnumerationDecl>(decl))
00129 clearDeclarativeRegion(edecl);
00130 else if (IntegerDecl *idecl = dyn_cast<IntegerDecl>(decl))
00131 clearDeclarativeRegion(idecl);
00132 }
00133 }
00134
00135 void Scope::Entry::addImportDecl(DomainType *type)
00136 {
00137 typedef DeclRegion::DeclIter DeclIter;
00138 DomainTypeDecl *domain = type->getDomainTypeDecl();
00139 assert(domain && "Cannot import from the given domain!");
00140
00141 importDeclarativeRegion(domain);
00142 importDecls.push_back(type);
00143 }
00144
00145
00146
00147 void Scope::Entry::clear()
00148 {
00149
00150
00151 DirectIterator endDeclIter = endDirectDecls();
00152 for (DirectIterator declIter = beginDirectDecls();
00153 declIter != endDeclIter; ++declIter)
00154 removeDirectDecl(*declIter);
00155
00156 ImportIterator endImportIter = endImportDecls();
00157 for (ImportIterator importIter = beginImportDecls();
00158 importIter != endImportIter; ++importIter)
00159 clearDeclarativeRegion((*importIter)->getDomainTypeDecl());
00160
00161 kind = DEAD_SCOPE;
00162 directDecls.clear();
00163 importDecls.clear();
00164 }
00165
00166 Homonym *Scope::Entry::getOrCreateHomonym(IdentifierInfo *info)
00167 {
00168 Homonym *homonym = info->getMetadata<Homonym>();
00169
00170 if (!homonym) {
00171 homonym = new Homonym();
00172 info->setMetadata(homonym);
00173 }
00174 return homonym;
00175 }
00176
00177
00178
00179
00180 Scope::Scope()
00181 : numCachedEntries(0)
00182 {
00183 push(CUNIT_SCOPE);
00184 }
00185
00186 Scope::~Scope()
00187 {
00188 while (!entries.empty()) pop();
00189 }
00190
00191 ScopeKind Scope::getKind() const
00192 {
00193 return entries.front()->getKind();
00194 }
00195
00196 void Scope::push(ScopeKind kind)
00197 {
00198 Entry *entry;
00199 unsigned tag = numEntries() + 1;
00200
00201 if (numCachedEntries) {
00202 entry = entryCache[--numCachedEntries];
00203 entry->initialize(kind, tag);
00204 }
00205 else
00206 entry = new Entry(kind, tag);
00207 entries.push_front(entry);
00208 }
00209
00210 void Scope::pop()
00211 {
00212 assert(!entries.empty() && "Cannot pop empty stack frame!");
00213
00214 Entry *entry = entries.front();
00215
00216 entry->clear();
00217 entries.pop_front();
00218 if (numCachedEntries < ENTRY_CACHE_SIZE)
00219 entryCache[numCachedEntries++] = entry;
00220 else
00221 delete entry;
00222 return;
00223 }
00224
00225 bool Scope::addImport(DomainType *type)
00226 {
00227
00228
00229 for (EntryStack::const_iterator entryIter = entries.begin();
00230 entryIter != entries.end(); ++entryIter)
00231 if ((*entryIter)->containsImportDecl(type)) return true;
00232
00233
00234 entries.front()->addImportDecl(type);
00235
00236 return false;
00237 }
00238
00239 Decl *Scope::addDirectDecl(Decl *decl) {
00240 assert(!llvm::isa<DomainInstanceDecl>(decl) &&
00241 "Cannot add domain instance declarations to a scope!");
00242 if (Decl *conflict = findConflictingDirectDecl(decl))
00243 return conflict;
00244 entries.front()->addDirectDecl(decl);
00245 return 0;
00246 }
00247
00248 void Scope::addDirectDeclNoConflicts(Decl *decl)
00249 {
00250 assert(!llvm::isa<DomainInstanceDecl>(decl) &&
00251 "Cannot add domain instance declarations to a scope!");
00252 assert(findConflictingDirectDecl(decl) == 0 &&
00253 "Conflicting decl found when there should be none!");
00254 entries.front()->addDirectDecl(decl);
00255 }
00256
00257 bool Scope::directDeclsConflict(Decl *X, Decl *Y) const
00258 {
00259 if (X->getIdInfo() != Y->getIdInfo())
00260 return false;
00261
00262
00263
00264
00265 SubroutineDecl *XSDecl = dyn_cast<SubroutineDecl>(X);
00266 SubroutineDecl *YSDecl = dyn_cast<SubroutineDecl>(Y);
00267 if (XSDecl && YSDecl && XSDecl->getType() != YSDecl->getType())
00268 return false;
00269 return true;
00270 }
00271
00272 Decl *Scope::findConflictingDirectDecl(Decl *candidate) const
00273 {
00274 Entry *currentEntry = entries.front();
00275
00276 typedef Entry::DirectIterator iterator;
00277 iterator E = currentEntry->endDirectDecls();
00278 for (iterator I = currentEntry->beginDirectDecls(); I != E; ++I) {
00279 Decl *extant = *I;
00280 if (directDeclsConflict(extant, candidate))
00281 return extant;
00282 }
00283 return 0;
00284 }
00285
00286 void Scope::dump() const
00287 {
00288 std::cerr << "**** Scope trace for <"
00289 << std::hex << (uintptr_t)this
00290 << ">:\n";
00291
00292 unsigned depth = entries.size();
00293 for (EntryStack::const_iterator entryIter = entries.begin();
00294 entryIter != entries.end(); ++entryIter) {
00295 Entry *entry = *entryIter;
00296 std::cerr << " Entry[" << depth-- << "] <"
00297 << std::hex << (uintptr_t)entry
00298 << ">: ";
00299 switch (entry->getKind()) {
00300 case BASIC_SCOPE:
00301 std::cerr << "BASIC_SCOPE\n";
00302 break;
00303 case CUNIT_SCOPE:
00304 std::cerr << "CUINT_SCOPE\n";
00305 break;
00306 case MODEL_SCOPE:
00307 std::cerr << "MODEL_SCOPE\n";
00308 break;
00309 case SUBROUTINE_SCOPE:
00310 std::cerr << "SUBROUTINE_SCOPE\n";
00311 break;
00312 case RECORD_SCOPE:
00313 std::cerr << "RECORD_SCOPE\n";
00314 break;
00315 case DEAD_SCOPE:
00316 assert(false && "Cannot print uninitialized scope!");
00317 }
00318
00319 if (entry->numDirectDecls()) {
00320 std::cerr << " Direct Decls:\n";
00321 for (Entry::DirectIterator lexIter = entry->beginDirectDecls();
00322 lexIter != entry->endDirectDecls(); ++lexIter) {
00323 Decl *decl = *lexIter;
00324 std::cerr << " " << decl->getString() << " : ";
00325 decl->dump();
00326 std::cerr << '\n';
00327 }
00328 std::cerr << '\n';
00329 }
00330
00331 if (entry->numImportDecls()) {
00332 std::cerr << " Imports:\n";
00333 for (Entry::ImportIterator importIter = entry->beginImportDecls();
00334 importIter != entry->endImportDecls(); ++importIter) {
00335 DomainType *type = *importIter;
00336 std::cerr << " " << type->getString() << " : ";
00337 type->dump();
00338 std::cerr << '\n';
00339
00340 DomainTypeDecl *domain = type->getDomainTypeDecl();
00341 for (DeclRegion::DeclIter iter = domain->beginDecls();
00342 iter != domain->endDecls(); ++iter) {
00343 std::cerr << " ";
00344 (*iter)->dump();
00345 std::cerr << '\n';
00346 }
00347 }
00348 std::cerr << '\n';
00349 }
00350 std::cerr << std::endl;
00351 }
00352 }
00353