DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) { assert(DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"); DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) return PrimaryContext->lookup(Name); if (hasExternalVisibleStorage()) { StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) Map = buildLookup(); else if (NeedToReconcileExternalVisibleStorage) reconcileExternalVisibleStorage(); if (!Map) Map = CreateStoredDeclsMap(getParentASTContext()); // If a PCH/module has a result for this name, and we have a local // declaration, we will have imported the PCH/module result when adding the // local declaration or when reconciling the module. std::pair<StoredDeclsMap::iterator, bool> R = Map->insert(std::make_pair(Name, StoredDeclsList())); if (!R.second) return R.first->second.getLookupResult(); ExternalASTSource *Source = getParentASTContext().getExternalSource(); if (Source->FindExternalVisibleDeclsByName(this, Name)) { if (StoredDeclsMap *Map = LookupPtr.getPointer()) { StoredDeclsMap::iterator I = Map->find(Name); if (I != Map->end()) return I->second.getLookupResult(); } } return lookup_result(lookup_iterator(0), lookup_iterator(0)); } StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) Map = buildLookup(); if (!Map) return lookup_result(lookup_iterator(0), lookup_iterator(0)); StoredDeclsMap::iterator I = Map->find(Name); if (I == Map->end()) return lookup_result(lookup_iterator(0), lookup_iterator(0)); return I->second.getLookupResult(); }
DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) { DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) return PrimaryContext->lookup(Name); if (hasExternalVisibleStorage()) LoadVisibleDeclsFromExternalStorage(); /// If there is no lookup data structure, build one now by walking /// all of the linked DeclContexts (in declaration order!) and /// inserting their values. if (!LookupPtr) { buildLookup(this); if (!LookupPtr) return lookup_result(0, 0); } StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr); StoredDeclsMap::iterator Pos = Map->find(Name); if (Pos == Map->end()) return lookup_result(0, 0); return Pos->second.getLookupResult(getParentASTContext()); }
void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) { // Find or create the stored declaration map. // AXEL: #if AXEL_LOOKUP_CHANGES bool MustVisitExternalSources = false; #endif StoredDeclsMap *Map = LookupPtr.getPointer(); if (!Map) { ASTContext *C = &getParentASTContext(); Map = CreateStoredDeclsMap(*C); #ifndef AXEL_LOOKUP_CHANGES } // If there is an external AST source, load any declarations it knows about // with this declaration's name. // If the lookup table contains an entry about this name it means that we // have already checked the external source. if (!Internal) if (ExternalASTSource *Source = getParentASTContext().getExternalSource()) if (hasExternalVisibleStorage() && Map->find(D->getDeclName()) == Map->end()) Source->FindExternalVisibleDeclsByName(this, D->getDeclName()); #else MustVisitExternalSources = hasExternalVisibleStorage(); } else if (hasExternalVisibleStorage() &&
void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) { // Find or create the stored declaration map. StoredDeclsMap *Map = LookupPtr.getPointer(); if (!Map) { ASTContext *C = &getParentASTContext(); Map = CreateStoredDeclsMap(*C); } // If there is an external AST source, load any declarations it knows about // with this declaration's name. // If the lookup table contains an entry about this name it means that we // have already checked the external source. if (!Internal) if (ExternalASTSource *Source = getParentASTContext().getExternalSource()) if (hasExternalVisibleStorage() && Map->find(D->getDeclName()) == Map->end()) Source->FindExternalVisibleDeclsByName(this, D->getDeclName()); // Insert this declaration into the map. StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()]; if (DeclNameEntries.isNull()) { DeclNameEntries.setOnlyValue(D); return; } if (DeclNameEntries.HandleRedeclaration(D)) { // This declaration has replaced an existing one for which // declarationReplaces returns true. return; } // Put this declaration into the appropriate slot. DeclNameEntries.AddSubsequentDecl(D); }
void DeclContext::removeDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "decl being removed from non-lexical context"); assert((D->NextInContextAndBits.getPointer() || D == LastDecl) && "decl is not in decls list"); // Remove D from the decl chain. This is O(n) but hopefully rare. if (D == FirstDecl) { if (D == LastDecl) FirstDecl = LastDecl = 0; else FirstDecl = D->NextInContextAndBits.getPointer(); } else { for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) { assert(I && "decl not found in linked list"); if (I->NextInContextAndBits.getPointer() == D) { I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer()); if (D == LastDecl) LastDecl = I; break; } } } // Mark that D is no longer in the decl chain. D->NextInContextAndBits.setPointer(0); // Remove D from the lookup table if necessary. if (isa<NamedDecl>(D)) { NamedDecl *ND = cast<NamedDecl>(D); // Remove only decls that have a name or registered in the lookup. if (!ND->getDeclName() || ND->isHidden()) return; StoredDeclsMap *Map = D->getDeclContext()->getPrimaryContext()->LookupPtr.getPointer(); if (!Map) return; StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); #ifndef NDEBUG assert(Pos != Map->end() && "no lookup entry for decl"); #endif if (Pos != Map->end() && (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND) ) Pos->second.remove(ND); } }
DeclContext::lookup_result DeclContext::noload_lookup(DeclarationName Name) { assert(DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"); if (!hasExternalVisibleStorage()) return lookup(Name); DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) return PrimaryContext->noload_lookup(Name); StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) { // Carefully build the lookup map, without deserializing anything. SmallVector<DeclContext *, 2> Contexts; collectAllContexts(Contexts); for (unsigned I = 0, N = Contexts.size(); I != N; ++I) buildLookupImpl<&DeclContext::noload_decls_begin, &DeclContext::noload_decls_end>(Contexts[I]); // We no longer have any lazy decls. LookupPtr.setInt(false); // There may now be names for which we have local decls but are // missing the external decls. FIXME: Just set the hasExternalDecls // flag on those names that have external decls. NeedToReconcileExternalVisibleStorage = true; Map = LookupPtr.getPointer(); } if (!Map) return lookup_result(lookup_iterator(0), lookup_iterator(0)); StoredDeclsMap::iterator I = Map->find(Name); return I != Map->end() ? I->second.getLookupResult() : lookup_result(lookup_iterator(0), lookup_iterator(0)); }
void DeclContext::removeDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "decl being removed from non-lexical context"); assert((D->NextDeclInContext || D == LastDecl) && "decl is not in decls list"); // Remove D from the decl chain. This is O(n) but hopefully rare. if (D == FirstDecl) { if (D == LastDecl) FirstDecl = LastDecl = 0; else FirstDecl = D->NextDeclInContext; } else { for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) { assert(I && "decl not found in linked list"); if (I->NextDeclInContext == D) { I->NextDeclInContext = D->NextDeclInContext; if (D == LastDecl) LastDecl = I; break; } } } // Mark that D is no longer in the decl chain. D->NextDeclInContext = 0; // Remove D from the lookup table if necessary. if (isa<NamedDecl>(D)) { NamedDecl *ND = cast<NamedDecl>(D); StoredDeclsMap *Map = getPrimaryContext()->LookupPtr; if (!Map) return; StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); assert(Pos != Map->end() && "no lookup entry for decl"); Pos->second.remove(ND); } }
DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) { assert(DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"); DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) return PrimaryContext->lookup(Name); if (hasExternalVisibleStorage()) { // If a PCH has a result for this name, and we have a local declaration, we // will have imported the PCH result when adding the local declaration. // FIXME: For modules, we could have had more declarations added by module // imoprts since we saw the declaration of the local name. if (StoredDeclsMap *Map = LookupPtr.getPointer()) { StoredDeclsMap::iterator I = Map->find(Name); if (I != Map->end()) return I->second.getLookupResult(); } ExternalASTSource *Source = getParentASTContext().getExternalSource(); return Source->FindExternalVisibleDeclsByName(this, Name); } StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) Map = buildLookup(); if (!Map) return lookup_result(lookup_iterator(0), lookup_iterator(0)); StoredDeclsMap::iterator I = Map->find(Name); if (I == Map->end()) return lookup_result(lookup_iterator(0), lookup_iterator(0)); return I->second.getLookupResult(); }
DeclContext::lookup_result DeclContext::lookup(IdentifierInfo &Name) { DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) // FIXME: not needed? return PrimaryContext->lookup(Name); #if 0 // FIXME: modules. eventually. resync this part from clang. if (hasExternalVisibleStorage()) { // If a PCH has a result for this name, and we have a local declaration, we // will have imported the PCH result when adding the local declaration. // FIXME: For modules, we could have had more declarations added by module // imoprts since we saw the declaration of the local name. if (StoredDeclsMap *Map = LookupPtr.getPointer()) { StoredDeclsMap::iterator I = Map->find(&Name); if (I != Map->end()) return I->second.getLookupResult(); } ExternalASTSource *Source = getParentASTContext().getExternalSource(); return Source->FindExternalVisibleDeclsByName(this, Name); } #endif StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) Map = buildLookup(); if (!Map) return lookup_result(lookup_iterator(0), lookup_iterator(0)); StoredDeclsMap::iterator I = Map->find(&Name); if (I == Map->end()) return lookup_result(lookup_iterator(0), lookup_iterator(0)); return I->second.getLookupResult(); }
DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) { assert(DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"); DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) return PrimaryContext->lookup(Name); #if AXEL_LOOKUP_CHANGES StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) Map = buildLookup(); #endif if (hasExternalVisibleStorage()) { // If a PCH has a result for this name, and we have a local declaration, we // will have imported the PCH result when adding the local declaration. // FIXME: For modules, we could have had more declarations added by module // imoprts since we saw the declaration of the local name. #if AXEL_LOOKUP_CHANGES if (Map) { #else if (StoredDeclsMap *Map = LookupPtr.getPointer()) { #endif StoredDeclsMap::iterator I = Map->find(Name); if (I != Map->end()) return I->second.getLookupResult(); } ExternalASTSource *Source = getParentASTContext().getExternalSource(); return Source->FindExternalVisibleDeclsByName(this, Name); } #ifndef AXEL_LOOKUP_CHANGES StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) Map = buildLookup(); #endif if (!Map) return lookup_result(lookup_iterator(0), lookup_iterator(0)); StoredDeclsMap::iterator I = Map->find(Name); if (I == Map->end()) return lookup_result(lookup_iterator(0), lookup_iterator(0)); return I->second.getLookupResult(); } void DeclContext::localUncachedLookup(DeclarationName Name, llvm::SmallVectorImpl<NamedDecl *> &Results) { Results.clear(); // If there's no external storage, just perform a normal lookup and copy // the results. if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) { lookup_result LookupResults = lookup(Name); Results.insert(Results.end(), LookupResults.first, LookupResults.second); return; } // If we have a lookup table, check there first. Maybe we'll get lucky. if (Name) { if (StoredDeclsMap *Map = LookupPtr.getPointer()) { StoredDeclsMap::iterator Pos = Map->find(Name); if (Pos != Map->end()) { Results.insert(Results.end(), Pos->second.getLookupResult().first, Pos->second.getLookupResult().second); return; } } } // Slow case: grovel through the declarations in our chain looking for // matches. for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) { if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) if (ND->getDeclName() == Name) Results.push_back(ND); } }