Index: cfe/trunk/include/clang/AST/DeclBase.h =================================================================== --- cfe/trunk/include/clang/AST/DeclBase.h +++ cfe/trunk/include/clang/AST/DeclBase.h @@ -1823,7 +1823,9 @@ using lookups_range = llvm::iterator_range; lookups_range lookups() const; - lookups_range noload_lookups() const; + // Like lookups(), but avoids loading external declarations. + // If PreserveInternalState, avoids building lookup data structures too. + lookups_range noload_lookups(bool PreserveInternalState) const; /// \brief Iterators over all possible lookups within this context. all_lookups_iterator lookups_begin() const; @@ -1943,6 +1945,7 @@ StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; + void loadLazyLocalLexicalLookups(); void buildLookupImpl(DeclContext *DCtx, bool Internal); void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Rediscoverable); Index: cfe/trunk/include/clang/AST/DeclLookups.h =================================================================== --- cfe/trunk/include/clang/AST/DeclLookups.h +++ cfe/trunk/include/clang/AST/DeclLookups.h @@ -86,16 +86,11 @@ return lookups_range(all_lookups_iterator(), all_lookups_iterator()); } -inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { - return lookups().begin(); -} - -inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const { - return lookups().end(); -} - -inline DeclContext::lookups_range DeclContext::noload_lookups() const { +inline DeclContext::lookups_range +DeclContext::noload_lookups(bool PreserveInternalState) const { DeclContext *Primary = const_cast(this)->getPrimaryContext(); + if (!PreserveInternalState) + Primary->loadLazyLocalLexicalLookups(); if (StoredDeclsMap *Map = Primary->getLookupPtr()) return lookups_range(all_lookups_iterator(Map->begin(), Map->end()), all_lookups_iterator(Map->end(), Map->end())); @@ -105,16 +100,6 @@ return lookups_range(all_lookups_iterator(), all_lookups_iterator()); } -inline -DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const { - return noload_lookups().begin(); -} - -inline -DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const { - return noload_lookups().end(); -} - } // namespace clang #endif // LLVM_CLANG_AST_DECLLOOKUPS_H Index: cfe/trunk/lib/AST/ASTDumper.cpp =================================================================== --- cfe/trunk/lib/AST/ASTDumper.cpp +++ cfe/trunk/lib/AST/ASTDumper.cpp @@ -809,11 +809,10 @@ bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); - for (auto I = Deserialize ? Primary->lookups_begin() - : Primary->noload_lookups_begin(), - E = Deserialize ? Primary->lookups_end() - : Primary->noload_lookups_end(); - I != E; ++I) { + auto Range = Deserialize + ? Primary->lookups() + : Primary->noload_lookups(/*PreserveInternalState=*/true); + for (auto I = Range.begin(), E = Range.end(); I != E; ++I) { DeclarationName Name = I.getLookupName(); DeclContextLookupResult R = *I; Index: cfe/trunk/lib/AST/DeclBase.cpp =================================================================== --- cfe/trunk/lib/AST/DeclBase.cpp +++ cfe/trunk/lib/AST/DeclBase.cpp @@ -1588,17 +1588,7 @@ if (PrimaryContext != this) return PrimaryContext->noload_lookup(Name); - // If we have any lazy lexical declarations not in our lookup map, add them - // now. Don't import any external declarations, not even if we know we have - // some missing from the external visible lookups. - if (HasLazyLocalLexicalLookups) { - SmallVector Contexts; - collectAllContexts(Contexts); - for (unsigned I = 0, N = Contexts.size(); I != N; ++I) - buildLookupImpl(Contexts[I], hasExternalVisibleStorage()); - HasLazyLocalLexicalLookups = false; - } - + loadLazyLocalLexicalLookups(); StoredDeclsMap *Map = LookupPtr; if (!Map) return lookup_result(); @@ -1608,6 +1598,19 @@ : lookup_result(); } +// If we have any lazy lexical declarations not in our lookup map, add them +// now. Don't import any external declarations, not even if we know we have +// some missing from the external visible lookups. +void DeclContext::loadLazyLocalLexicalLookups() { + if (HasLazyLocalLexicalLookups) { + SmallVector Contexts; + collectAllContexts(Contexts); + for (unsigned I = 0, N = Contexts.size(); I != N; ++I) + buildLookupImpl(Contexts[I], hasExternalVisibleStorage()); + HasLazyLocalLexicalLookups = false; + } +} + void DeclContext::localUncachedLookup(DeclarationName Name, SmallVectorImpl &Results) { Results.clear(); Index: cfe/trunk/lib/Sema/SemaLookup.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaLookup.cpp +++ cfe/trunk/lib/Sema/SemaLookup.cpp @@ -3543,7 +3543,8 @@ // Enumerate all of the results in this context. for (DeclContextLookupResult R : - LoadExternal ? Ctx->lookups() : Ctx->noload_lookups()) { + LoadExternal ? Ctx->lookups() + : Ctx->noload_lookups(/*PreserveInternalState=*/false)) { for (auto *D : R) { if (auto *ND = Result.getAcceptableDecl(D)) { Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass); Index: cfe/trunk/test/Index/complete-pch-skip.h =================================================================== --- cfe/trunk/test/Index/complete-pch-skip.h +++ cfe/trunk/test/Index/complete-pch-skip.h @@ -1,3 +0,0 @@ -namespace ns { -int foo; -} Index: cfe/trunk/test/Index/complete-pch-skip.cpp =================================================================== --- cfe/trunk/test/Index/complete-pch-skip.cpp +++ cfe/trunk/test/Index/complete-pch-skip.cpp @@ -16,3 +16,10 @@ // SKIP-PCH: {TypedText bar} // SKIP-PCH-NOT: foo +// Verify that with *no* preamble (no -include flag) we still get local results. +// SkipPreamble used to break this, by making lookup *too* lazy. +// RUN: env CINDEXTEST_COMPLETION_SKIP_PREAMBLE=1 c-index-test -code-completion-at=%s:5:26 %s | FileCheck -check-prefix=NO-PCH %s +// NO-PCH-NOT: foo +// NO-PCH: {TypedText bar} +// NO-PCH-NOT: foo +