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