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.cpp ----------------------------------- -*- 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 #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 // Scope::Entry method. 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 // Import the contents of enumeration and integer decls. 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 // Clear the contents of enumeration and integer decls. 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 // Turns this into an uninitialized (dead) scope entry. This method is 00146 // used so that entries can be cached and recognized as inactive objects. 00147 void Scope::Entry::clear() 00148 { 00149 // Traverse the set of IdentifierInfo's owned by this entry and reduce the 00150 // associated decl stacks. 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 // Scope methods. 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 // First, walk the current stack of frames and check that this type has not 00228 // already been imported. 00229 for (EntryStack::const_iterator entryIter = entries.begin(); 00230 entryIter != entries.end(); ++entryIter) 00231 if ((*entryIter)->containsImportDecl(type)) return true; 00232 00233 // The import is not yet in scope. Register it with the current entry. 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 // The only type of declarations that can share the same name in the same 00263 // scope are subroutine declarations (provided that they have distinct 00264 // types). 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