> On Apr 10, 2015, at 3:46 PM, Richard Smith <[email protected]> wrote: > > On Fri, Apr 10, 2015 at 3:28 PM, Ben Langmuir <[email protected] > <mailto:[email protected]>> wrote: > >> On Mar 23, 2015, at 8:20 PM, Ben Langmuir <[email protected] >> <mailto:[email protected]>> wrote: >> >>> >>> On Mar 23, 2015, at 7:52 PM, Richard Smith <[email protected] >>> <mailto:[email protected]>> wrote: >>> >>> On Mon, Mar 23, 2015 at 7:36 PM, Ben Langmuir <[email protected] >>> <mailto:[email protected]>> wrote: >>> >>>> On Mar 23, 2015, at 5:06 PM, Richard Smith <[email protected] >>>> <mailto:[email protected]>> wrote: >>>> >>>> On Mon, Mar 23, 2015 at 5:01 PM, Ben Langmuir <[email protected] >>>> <mailto:[email protected]>> wrote: >>>> >>>>> On Mar 23, 2015, at 4:18 PM, Richard Smith <[email protected] >>>>> <mailto:[email protected]>> wrote: >>>>> >>>>> On Mon, Mar 23, 2015 at 3:59 PM, Ben Langmuir <[email protected] >>>>> <mailto:[email protected]>> wrote: >>>>> >>>>>> On Mar 23, 2015, at 3:43 PM, Richard Smith <[email protected] >>>>>> <mailto:[email protected]>> wrote: >>>>>> >>>>>> On Mon, Mar 23, 2015 at 2:41 PM, Ben Langmuir <[email protected] >>>>>> <mailto:[email protected]>> wrote: >>>>>> >>>>>>> On Mar 23, 2015, at 1:05 PM, Richard Smith <[email protected] >>>>>>> <mailto:[email protected]>> wrote: >>>>>>> >>>>>>> On Sat, Mar 14, 2015 at 9:25 AM, Ben Langmuir <[email protected] >>>>>>> <mailto:[email protected]>> wrote: >>>>>>> Hi Richard, >>>>>>> >>>>>>> This commit looks like it caused a regression in PCH-loading >>>>>>> performance when the PCH imports modules. It doesn’t affect >>>>>>> performance of loading modules on their own, or of a PCH that doesn’t >>>>>>> use modules. If you have access to a Darwin system, it’s easy to >>>>>>> reproduce with: >>>>>>> >>>>>>> $ cat t.h >>>>>>> @import Cocoa; >>>>>>> >>>>>>> $ cat t.m >>>>>>> // empty >>>>>>> >>>>>>> $ clang -fmodules -fmodules-cache-path=mcp -x objective-c-header t.h -o >>>>>>> t.pch >>>>>>> $ time clang -fmodules -fmodules-cache-path=mcp -Xclang -include-pch >>>>>>> -Xclang t.pch t.m -fsyntax-only >>>>>>> >>>>>>> I’m seeing ~8x difference between r228233 and r228234. In real world >>>>>>> code (where the .m file isn’t empty) we’ve seen up to a ~90% difference. >>>>>>> >>>>>>> Do you know what’s going on here? >>>>>>> >>>>>>> Hmm. I suspect this change causes the lookup table for the translation >>>>>>> unit to be built, which in turn pulls in all the lexical contents of >>>>>>> the translation unit (because outside of C++ we don't serialize a >>>>>>> DeclContext lookup table for the TU, nor even build one usually). >>>>>>> >>>>>>> When a PCH loads I think we do it without Sema, but (at least >>>>>>> previously) queued up the interesting Decls we saw for when Sema was >>>>>>> added later. So I’m surprised this had such a big effect. >>>>>>> >>>>>>> If we were loading PCHs without Sema, then I think before this change >>>>>>> we would not have merged declarations of the same entity from two >>>>>>> independent modules imported into the same PCH. >>>>>> >>>>>> Wouldn’t that happen in InitializeSema() when we called >>>>>> pushExternalDeclIntoScope() on the contents of PreloadedDeclIDs? >>>>>> >>>>>> No; we're talking about the case where a Decl is deserialized before we >>>>>> have a Sema instance. If we never deserialized the Decl from its DeclID >>>>>> before we had a Sema (which I think is what you're suggesting) we'd >>>>>> never have reached the modified code. >>>>>> >>>>>> If we want to support loading Decls without Sema, we need to be able to >>>>>> merge them without Sema. If we don't, then we should find whichever >>>>>> codepath is leading us to do so and fix it. Being able to load a >>>>>> serialized AST without a Sema seems useful to me, in the absence of a >>>>>> good reason why it shouldn't work. >>>>> >>>>> I thought PCH intentionally wouldn’t deserialize decls until after we >>>>> initialized Sema. Maybe we have a bug (which wouldn’t surprise me), or >>>>> maybe that wasn’t the intent (which would scare me a bit since then we >>>>> have some decls showing up immediately and some waiting for sema with no >>>>> clear split between them). >>>>> >>>>>>> Perhaps we should use a separate side-table for merging in this case >>>>>>> outside C++, rather than falling back to DeclContext lookup? >>>>>> >>>>>> I don’t know this code path well enough to say. What would go into the >>>>>> table (or perhaps more importantly what wouldn’t)? >>>>>> >>>>>> Any deserialized declarations that should be visible by name lookup in >>>>>> the TU would be in the table. The only difference would be that we'd be >>>>>> more careful to ensure that we never trigger the import of all lexical >>>>>> declarations in the TU in order to build the table. >>>>>> >>>>>> Are you still seeing this performance problem with Clang trunk? Towards >>>>>> the end of last week I fixed a bug where we would unnecessarily pull in >>>>>> all lexical declarations within the TU when doing certain lookups, which >>>>>> might have fixed this slowdown. (If not, it'd be useful to find out >>>>>> whether that's the problem, and if so, what is causing us to load these >>>>>> declarations.) >>>>> >>>>> Cool, I’ll give ToT a shot. I last tried with r232229. >>>>> >>>>> r232928 onwards, or a revision in [232793, 232905), have the change I'm >>>>> referring to. >>>> >>>> ToT got faster, but not even close to pre-228234. >>>> >>>> r228233: 0.0574 s <== “before” >>>> r228234: 0.4433 s <== “after" >>>> r232229: 0.4028 s >>>> r233028: 0.3097 s <== ToT >>>> >>>> Where's ToT spending its time? >>> >>> Suspiciously it’s coming from LoadLexicalDeclsFromExternalStorage inside >>> **noload_lookup**… >>> >>> Aha, thanks! Should be fixed in r233046, let me know if there are still >>> problems. >> >> Excellent, thanks for the fix! I’ve verified we’re back to the pre-228234 >> performance. > > > Hey Richard, > > Sorry to drag this back up, but apparently I didn’t verify it carefully > enough. Your commit fixed the regression for initially loading the PCH, but > it’s still slow if you actually do any lookups into the ASTReader. If I add: > > void foo() { > } > > to my test .m file, which means we try to lookup ‘foo’ in the ASTReader, > clang is still slow (3-5 seconds with -fsyntax-only). The trace is: > > Running Time Self (ms) Symbol Name > 3202.0ms 98.6% 0.0 > clang::Sema::ActOnStartOfFunctionDef(clang::Scope*, clang::Declarator&) > 3202.0ms 98.6% 0.0 > clang::Sema::HandleDeclarator(clang::Scope*, clang::Declarator&, > llvm::MutableArrayRef<clang::TemplateParameterList*>) > 3202.0ms 98.6% 0.0 > clang::Sema::PushOnScopeChains(clang::NamedDecl*, clang::Scope*, bool) > 3202.0ms 98.6% 0.0 > clang::DeclContext::makeDeclVisibleInContextWithFlags(clang::NamedDecl*, > bool, bool) > 3202.0ms 98.6% 0.0 > clang::DeclContext::buildLookup() > 3199.0ms 98.5% 0.0 > clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const > 3004.0ms 92.5% 0.0 > clang::ASTReader::FinishedDeserializing() > 3004.0ms 92.5% 1.0 > clang::ASTReader::finishPendingActions() > 2955.0ms 91.0% 3.0 > clang::ASTReader::pushExternalDeclIntoScope(clang::NamedDecl*, > clang::DeclarationName) > 2942.0ms 90.6% 1721.0 > llvm::MapVector<clang::IdentifierInfo*, llvm::SmallVector<clang::NamedDecl*, > 2u>, llvm::SmallDenseMap<clang::IdentifierInfo*, unsigned int, 16u, > llvm::DenseMapInfo<clang::IdentifierInfo*>, > llvm::detail::DenseMapPair<clang::IdentifierInfo*, unsigned int> >, > llvm::SmallVector<std::__1::pair<clang::IdentifierInfo*, > llvm::SmallVector<clang::NamedDecl*, 2u> >, 16u> > >::erase(std::__1::pair<clang::IdentifierInfo*, > llvm::SmallVector<clang::NamedDecl*, 2u> >*) > > > Most of this is because MapVector::erase is O(n), so as a workaround I > switched to clear() ing the contained SmallVector in r234655. But I think > there’s a more fundamental issue here, because even with that improvement the > whole compile still takes 0.25 - 0.5 seconds, rather than the 0.02 seconds it > takes without PCH, or without Modules (ie. only the combination of both is > slow). The trace after removing the MapVector::erase is: > > Running Time Self (ms) Symbol Name > 246.0ms 84.2% 0.0 > clang::Sema::ActOnStartOfFunctionDef(clang::Scope*, clang::Declarator&) > 246.0ms 84.2% 0.0 > clang::Sema::HandleDeclarator(clang::Scope*, clang::Declarator&, > llvm::MutableArrayRef<clang::TemplateParameterList*>) > 245.0ms 83.9% 0.0 > clang::Sema::PushOnScopeChains(clang::NamedDecl*, clang::Scope*, bool) > 245.0ms 83.9% 0.0 > clang::DeclContext::makeDeclVisibleInContextWithFlags(clang::NamedDecl*, > bool, bool) > 245.0ms 83.9% 0.0 > clang::DeclContext::buildLookup() > 242.0ms 82.8% 0.0 > clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const > > This shouldn't be happening; I think makeDeclVisibleInContextWithFlags is too > eager to build the lookup table for a DeclContext. Can you try removing the > 'hasExternalVisibleStorage() ||' from it?
Didn’t have any noticeable affect. > > 189.0ms 64.7% 0.0 non-virtual thunk > to clang::ASTReader::FindExternalLexicalDecls(clang::DeclContext const*, bool > (*)(clang::Decl::Kind), llvm::SmallVectorImpl<clang::Decl*>&) > 189.0ms 64.7% 0.0 > clang::serialization::ModuleManager::visitDepthFirst(bool > (*)(clang::serialization::ModuleFile&, bool, void*), void*) > 189.0ms 64.7% 0.0 > visitDepthFirst(clang::serialization::ModuleFile&, bool > (*)(clang::serialization::ModuleFile&, bool, void*), void*, > llvm::SmallVectorImpl<bool>&) > 189.0ms 64.7% 0.0 > visitDepthFirst(clang::serialization::ModuleFile&, bool > (*)(clang::serialization::ModuleFile&, bool, void*), void*, > llvm::SmallVectorImpl<bool>&) > 189.0ms 64.7% 0.0 > visitDepthFirst(clang::serialization::ModuleFile&, bool > (*)(clang::serialization::ModuleFile&, bool, void*), void*, > llvm::SmallVectorImpl<bool>&) > 170.0ms 58.2% 0.0 > visitDepthFirst(clang::serialization::ModuleFile&, bool > (*)(clang::serialization::ModuleFile&, bool, void*), void*, > llvm::SmallVectorImpl<bool>&) > 98.0ms 33.5% 0.0 > visitDepthFirst(clang::serialization::ModuleFile&, bool > (*)(clang::serialization::ModuleFile&, bool, void*), void*, > llvm::SmallVectorImpl<bool>&) > 71.0ms 24.3% 0.0 (anonymous > namespace)::FindExternalLexicalDeclsVisitor::visit(clang::serialization::ModuleFile&, > bool, void*) > 27.0ms 9.2% 0.0 > visitDepthFirst(clang::serialization::ModuleFile&, bool > (*)(clang::serialization::ModuleFile&, bool, void*), void*, > llvm::SmallVectorImpl<bool>&) > 72.0ms 24.6% 0.0 (anonymous > namespace)::FindExternalLexicalDeclsVisitor::visit(clang::serialization::ModuleFile&, > bool, void*) > 19.0ms 6.5% 1.0 (anonymous > namespace)::FindExternalLexicalDeclsVisitor::visit(clang::serialization::ModuleFile&, > bool, void*) > > > We still seem to be eagerly loading something that we shouldn’t. > -print-stats gives: > > *** AST File Statistics: > 28/96751 source location entries read (0.028940%) > 24388/29520 types read (82.615181%) > 64783/142552 declarations read (45.445171%) > 29024/90665 identifiers read (32.012352%) > 1527/19301 macros read (7.911507%) > 0/10332 selectors read (0.000000%) > 204/49951 statements read (0.408400%) > 1527/19301 macros read (7.911507%) > 1/6984 lexical declcontexts read (0.014318%) > 0/5973 visible declcontexts read (0.000000%) > 0/9318 method pool entries read (0.000000%) > 24171 / 52370 identifier table lookups succeeded (46.154287%) > > Ben > >> >>> >>> are we setting hasExternalVisibleStorage incorrectly? >>> >>> Running Time Self Symbol Name >>> 341.0ms 97.1% 0.0 cc1_main(llvm::ArrayRef<char >>> const*>, char const*, void*) >>> 340.0ms 96.8% 0.0 >>> clang::ExecuteCompilerInvocation(clang::CompilerInstance*) >>> 340.0ms 96.8% 0.0 >>> clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) >>> 336.0ms 95.7% 0.0 >>> clang::FrontendAction::BeginSourceFile(clang::CompilerInstance&, >>> clang::FrontendInputFile const&) >>> 335.0ms 95.4% 0.0 >>> clang::CompilerInstance::createPCHExternalASTSource(llvm::StringRef, bool, >>> bool, void*, bool) >>> 335.0ms 95.4% 0.0 >>> clang::CompilerInstance::createPCHExternalASTSource(llvm::StringRef, >>> std::__1::basic_string<char, std::__1::char_traits<char>, >>> std::__1::allocator<char> > const&, bool, bool, clang::Preprocessor&, >>> clang::ASTContext&, void*, bool, bool, bool) >>> 335.0ms 95.4% 1.0 >>> clang::ASTReader::ReadAST(std::__1::basic_string<char, >>> std::__1::char_traits<char>, std::__1::allocator<char> > const&, >>> clang::serialization::ModuleKind, clang::SourceLocation, unsigned int) >>> 248.0ms 70.6% 0.0 >>> clang::ASTReader::InitializeContext() >>> 247.0ms 70.3% 0.0 >>> clang::ASTReader::GetType(unsigned int) >>> 247.0ms 70.3% 0.0 >>> clang::ASTReader::readTypeRecord(unsigned int) >>> 247.0ms 70.3% 0.0 >>> clang::ASTReader::ReadDeclRecord(unsigned int) >>> 247.0ms 70.3% 0.0 >>> clang::ASTDeclReader::Visit(clang::Decl*) >>> 247.0ms 70.3% 0.0 >>> clang::declvisitor::Base<clang::declvisitor::make_ptr, >>> clang::ASTDeclReader, void>::Visit(clang::Decl*) >>> 247.0ms 70.3% 0.0 >>> clang::ASTDeclReader::VisitTypedefNameDecl(clang::TypedefNameDecl*) >>> 246.0ms 70.0% 0.0 >>> clang::ASTReader::GetTypeSourceInfo(clang::serialization::ModuleFile&, >>> llvm::SmallVector<unsigned long long, 64u> const&, unsigned int&) >>> 246.0ms 70.0% 0.0 >>> clang::ASTReader::GetType(unsigned int) >>> 246.0ms 70.0% 0.0 >>> clang::ASTReader::readTypeRecord(unsigned int) >>> 246.0ms 70.0% 0.0 >>> clang::ASTReader::GetType(unsigned int) >>> 246.0ms 70.0% 0.0 >>> clang::ASTReader::readTypeRecord(unsigned int) >>> 246.0ms 70.0% 0.0 >>> clang::ASTReader::ReadDeclRecord(unsigned int) >>> 246.0ms 70.0% 0.0 >>> clang::ASTDeclReader::Visit(clang::Decl*) >>> 246.0ms 70.0% 0.0 >>> clang::declvisitor::Base<clang::declvisitor::make_ptr, >>> clang::ASTDeclReader, void>::Visit(clang::Decl*) >>> 246.0ms 70.0% 0.0 >>> clang::ASTDeclReader::VisitTagDecl(clang::TagDecl*) >>> 246.0ms 70.0% 0.0 void >>> clang::ASTDeclReader::mergeRedeclarable<clang::TagDecl>(clang::Redeclarable<clang::TagDecl>*, >>> clang::ASTDeclReader::RedeclarableResult&, unsigned int) >>> 246.0ms 70.0% 0.0 >>> clang::ASTDeclReader::findExisting(clang::NamedDecl*) >>> 246.0ms 70.0% 0.0 >>> clang::DeclContext::noload_lookup(clang::DeclarationName) >>> 246.0ms 70.0% 0.0 >>> clang::DeclContext::lookup(clang::DeclarationName) const >>> 246.0ms 70.0% 0.0 >>> clang::DeclContext::buildLookup() >>> 242.0ms 68.9% 1.0 >>> clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const >>> >>> >>> >>>> >>>> Ben >>>> >>>>>>> Ben >>>>>>> >>>>>>> > On Feb 4, 2015, at 3:37 PM, Richard Smith <[email protected] >>>>>>> > <mailto:[email protected]>> wrote: >>>>>>> > >>>>>>> > Author: rsmith >>>>>>> > Date: Wed Feb 4 17:37:59 2015 >>>>>>> > New Revision: 228234 >>>>>>> > >>>>>>> > URL: http://llvm.org/viewvc/llvm-project?rev=228234&view=rev >>>>>>> > <http://llvm.org/viewvc/llvm-project?rev=228234&view=rev> >>>>>>> > Log: >>>>>>> > [modules] When using -E, we may try to merge decls despite having no >>>>>>> > Sema >>>>>>> > object. In such a case, use the TU's DC for merging global decls >>>>>>> > rather than >>>>>>> > giving up when we find there is no TU scope. >>>>>>> > >>>>>>> > Ultimately, we should probably avoid all loading of decls when >>>>>>> > preprocessing, >>>>>>> > but there are other reasonable use cases for loading an AST file with >>>>>>> > no Sema >>>>>>> > object for which this is the right thing. >>>>>>> > >>>>>>> > Added: >>>>>>> > cfe/trunk/test/Modules/Inputs/preprocess/ >>>>>>> > cfe/trunk/test/Modules/Inputs/preprocess/file.h >>>>>>> > cfe/trunk/test/Modules/Inputs/preprocess/fwd.h >>>>>>> > cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap >>>>>>> > Modified: >>>>>>> > cfe/trunk/include/clang/Frontend/CompilerInstance.h >>>>>>> > cfe/trunk/lib/Frontend/CompilerInstance.cpp >>>>>>> > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >>>>>>> > cfe/trunk/test/Modules/preprocess.m >>>>>>> > >>>>>>> > Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h >>>>>>> > URL: >>>>>>> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=228234&r1=228233&r2=228234&view=diff >>>>>>> > >>>>>>> > <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=228234&r1=228233&r2=228234&view=diff> >>>>>>> > ============================================================================== >>>>>>> > --- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original) >>>>>>> > +++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Wed Feb 4 >>>>>>> > 17:37:59 2015 >>>>>>> > @@ -588,7 +588,7 @@ public: >>>>>>> > /// Create an external AST source to read a PCH file. >>>>>>> > /// >>>>>>> > /// \return - The new object on success, or null on failure. >>>>>>> > - static ExternalASTSource *createPCHExternalASTSource( >>>>>>> > + static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource( >>>>>>> > StringRef Path, const std::string &Sysroot, bool >>>>>>> > DisablePCHValidation, >>>>>>> > bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext >>>>>>> > &Context, >>>>>>> > void *DeserializationListener, bool OwnDeserializationListener, >>>>>>> > >>>>>>> > Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp >>>>>>> > URL: >>>>>>> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=228234&r1=228233&r2=228234&view=diff >>>>>>> > >>>>>>> > <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=228234&r1=228233&r2=228234&view=diff> >>>>>>> > ============================================================================== >>>>>>> > --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original) >>>>>>> > +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Wed Feb 4 17:37:59 >>>>>>> > 2015 >>>>>>> > @@ -388,32 +388,30 @@ void CompilerInstance::createASTContext( >>>>>>> > void CompilerInstance::createPCHExternalASTSource( >>>>>>> > StringRef Path, bool DisablePCHValidation, bool >>>>>>> > AllowPCHWithCompilerErrors, >>>>>>> > void *DeserializationListener, bool OwnDeserializationListener) { >>>>>>> > - IntrusiveRefCntPtr<ExternalASTSource> Source; >>>>>>> > bool Preamble = >>>>>>> > getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; >>>>>>> > - Source = createPCHExternalASTSource( >>>>>>> > + ModuleManager = createPCHExternalASTSource( >>>>>>> > Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, >>>>>>> > AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), >>>>>>> > DeserializationListener, OwnDeserializationListener, Preamble, >>>>>>> > getFrontendOpts().UseGlobalModuleIndex); >>>>>>> > - ModuleManager = static_cast<ASTReader*>(Source.get()); >>>>>>> > - getASTContext().setExternalSource(Source); >>>>>>> > } >>>>>>> > >>>>>>> > -ExternalASTSource *CompilerInstance::createPCHExternalASTSource( >>>>>>> > +IntrusiveRefCntPtr<ASTReader> >>>>>>> > CompilerInstance::createPCHExternalASTSource( >>>>>>> > StringRef Path, const std::string &Sysroot, bool >>>>>>> > DisablePCHValidation, >>>>>>> > bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext >>>>>>> > &Context, >>>>>>> > void *DeserializationListener, bool OwnDeserializationListener, >>>>>>> > bool Preamble, bool UseGlobalModuleIndex) { >>>>>>> > HeaderSearchOptions &HSOpts = >>>>>>> > PP.getHeaderSearchInfo().getHeaderSearchOpts(); >>>>>>> > >>>>>>> > - std::unique_ptr<ASTReader> Reader; >>>>>>> > - Reader.reset(new ASTReader(PP, Context, >>>>>>> > - Sysroot.empty() ? "" : Sysroot.c_str(), >>>>>>> > - DisablePCHValidation, >>>>>>> > - AllowPCHWithCompilerErrors, >>>>>>> > - /*AllowConfigurationMismatch*/false, >>>>>>> > - HSOpts.ModulesValidateSystemHeaders, >>>>>>> > - UseGlobalModuleIndex)); >>>>>>> > + IntrusiveRefCntPtr<ASTReader> Reader( >>>>>>> > + new ASTReader(PP, Context, Sysroot.empty() ? "" : >>>>>>> > Sysroot.c_str(), >>>>>>> > + DisablePCHValidation, AllowPCHWithCompilerErrors, >>>>>>> > + /*AllowConfigurationMismatch*/ false, >>>>>>> > + HSOpts.ModulesValidateSystemHeaders, >>>>>>> > UseGlobalModuleIndex)); >>>>>>> > + >>>>>>> > + // We need the external source to be set up before we read the >>>>>>> > AST, because >>>>>>> > + // eagerly-deserialized declarations may use it. >>>>>>> > + Context.setExternalSource(Reader.get()); >>>>>>> > >>>>>>> > Reader->setDeserializationListener( >>>>>>> > static_cast<ASTDeserializationListener >>>>>>> > *>(DeserializationListener), >>>>>>> > @@ -427,7 +425,7 @@ ExternalASTSource *CompilerInstance::cre >>>>>>> > // Set the predefines buffer as suggested by the PCH reader. >>>>>>> > Typically, the >>>>>>> > // predefines buffer will be empty. >>>>>>> > PP.setPredefines(Reader->getSuggestedPredefines()); >>>>>>> > - return Reader.release(); >>>>>>> > + return Reader; >>>>>>> > >>>>>>> > case ASTReader::Failure: >>>>>>> > // Unrecoverable failure: don't even try to process the input >>>>>>> > file. >>>>>>> > @@ -442,6 +440,7 @@ ExternalASTSource *CompilerInstance::cre >>>>>>> > break; >>>>>>> > } >>>>>>> > >>>>>>> > + Context.setExternalSource(nullptr); >>>>>>> > return nullptr; >>>>>>> > } >>>>>>> > >>>>>>> > >>>>>>> > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >>>>>>> > URL: >>>>>>> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=228234&r1=228233&r2=228234&view=diff >>>>>>> > >>>>>>> > <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=228234&r1=228233&r2=228234&view=diff> >>>>>>> > ============================================================================== >>>>>>> > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) >>>>>>> > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Feb 4 17:37:59 >>>>>>> > 2015 >>>>>>> > @@ -2591,6 +2591,11 @@ DeclContext *ASTDeclReader::getPrimaryCo >>>>>>> > return ED->getASTContext().getLangOpts().CPlusPlus? >>>>>>> > ED->getDefinition() >>>>>>> > : nullptr; >>>>>>> > >>>>>>> > + // We can see the TU here only if we have no Sema object. In that >>>>>>> > case, >>>>>>> > + // there's no TU scope to look in, so using the DC alone is >>>>>>> > sufficient. >>>>>>> > + if (auto *TU = dyn_cast<TranslationUnitDecl>(DC)) >>>>>>> > + return TU; >>>>>>> > + >>>>>>> > return nullptr; >>>>>>> > } >>>>>>> > >>>>>>> > >>>>>>> > Added: cfe/trunk/test/Modules/Inputs/preprocess/file.h >>>>>>> > URL: >>>>>>> > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/file.h?rev=228234&view=auto >>>>>>> > >>>>>>> > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/file.h?rev=228234&view=auto> >>>>>>> > ============================================================================== >>>>>>> > --- cfe/trunk/test/Modules/Inputs/preprocess/file.h (added) >>>>>>> > +++ cfe/trunk/test/Modules/Inputs/preprocess/file.h Wed Feb 4 >>>>>>> > 17:37:59 2015 >>>>>>> > @@ -0,0 +1,3 @@ >>>>>>> > +struct __FILE; >>>>>>> > +#include "fwd.h" >>>>>>> > +typedef struct __FILE FILE; >>>>>>> > >>>>>>> > Added: cfe/trunk/test/Modules/Inputs/preprocess/fwd.h >>>>>>> > URL: >>>>>>> > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/fwd.h?rev=228234&view=auto >>>>>>> > >>>>>>> > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/fwd.h?rev=228234&view=auto> >>>>>>> > ============================================================================== >>>>>>> > --- cfe/trunk/test/Modules/Inputs/preprocess/fwd.h (added) >>>>>>> > +++ cfe/trunk/test/Modules/Inputs/preprocess/fwd.h Wed Feb 4 >>>>>>> > 17:37:59 2015 >>>>>>> > @@ -0,0 +1 @@ >>>>>>> > +struct __FILE; >>>>>>> > >>>>>>> > Added: cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap >>>>>>> > URL: >>>>>>> > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap?rev=228234&view=auto >>>>>>> > >>>>>>> > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap?rev=228234&view=auto> >>>>>>> > ============================================================================== >>>>>>> > --- cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap (added) >>>>>>> > +++ cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap Wed Feb >>>>>>> > 4 17:37:59 2015 >>>>>>> > @@ -0,0 +1,2 @@ >>>>>>> > +module fwd { header "fwd.h" export * } >>>>>>> > +module file { header "file.h" export * } >>>>>>> > >>>>>>> > Modified: cfe/trunk/test/Modules/preprocess.m >>>>>>> > URL: >>>>>>> > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess.m?rev=228234&r1=228233&r2=228234&view=diff >>>>>>> > >>>>>>> > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess.m?rev=228234&r1=228233&r2=228234&view=diff> >>>>>>> > ============================================================================== >>>>>>> > --- cfe/trunk/test/Modules/preprocess.m (original) >>>>>>> > +++ cfe/trunk/test/Modules/preprocess.m Wed Feb 4 17:37:59 2015 >>>>>>> > @@ -1,9 +1,14 @@ >>>>>>> > // RUN: rm -rf %t >>>>>>> > -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs >>>>>>> > -include %S/Inputs/preprocess-prefix.h -E %s | FileCheck >>>>>>> > -strict-whitespace %s >>>>>>> > -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -x >>>>>>> > objective-c-header -emit-pch %S/Inputs/preprocess-prefix.h -o %t.pch >>>>>>> > -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs >>>>>>> > -include-pch %t.pch -E %s | FileCheck -strict-whitespace %s >>>>>>> > +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I >>>>>>> > %S/Inputs/preprocess -include %S/Inputs/preprocess-prefix.h -E %s | >>>>>>> > FileCheck -strict-whitespace %s >>>>>>> > +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I >>>>>>> > %S/Inputs/preprocess -x objective-c-header -emit-pch >>>>>>> > %S/Inputs/preprocess-prefix.h -o %t.pch >>>>>>> > +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I >>>>>>> > %S/Inputs/preprocess -include-pch %t.pch -E %s | FileCheck >>>>>>> > -strict-whitespace %s >>>>>>> > +// >>>>>>> > +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I >>>>>>> > %S/Inputs/preprocess -x objective-c++ -include >>>>>>> > %S/Inputs/preprocess-prefix.h -E %s | FileCheck -strict-whitespace %s >>>>>>> > +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I >>>>>>> > %S/Inputs/preprocess -x objective-c++-header -emit-pch >>>>>>> > %S/Inputs/preprocess-prefix.h -o %t.pch >>>>>>> > +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I >>>>>>> > %S/Inputs/preprocess -x objective-c++ -include-pch %t.pch -E %s | >>>>>>> > FileCheck -strict-whitespace %s >>>>>>> > #import "diamond_right.h" >>>>>>> > #import "diamond_right.h" // to check that imports get their own line >>>>>>> > +#include "file.h" >>>>>>> > void test() { >>>>>>> > top_left_before(); >>>>>>> > left_and_right(); >>>>>>> > @@ -15,6 +20,7 @@ void test() { >>>>>>> > >>>>>>> > // CHECK: @import diamond_right; /* clang -E: implicit import for >>>>>>> > "{{.*}}diamond_right.h" */{{$}} >>>>>>> > // CHECK: @import diamond_right; /* clang -E: implicit import for >>>>>>> > "{{.*}}diamond_right.h" */{{$}} >>>>>>> > +// CHECK: @import file; /* clang -E: implicit import for >>>>>>> > "{{.*}}file.h" */{{$}} >>>>>>> > // CHECK-NEXT: void test() {{{$}} >>>>>>> > // CHECK-NEXT: top_left_before();{{$}} >>>>>>> > // CHECK-NEXT: left_and_right();{{$}} >>>>>>> > >>>>>>> > >>>>>>> > _______________________________________________ >>>>>>> > cfe-commits mailing list >>>>>>> > [email protected] <mailto:[email protected]> >>>>>>> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >>>>>>> > <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] <mailto:[email protected]> >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits>
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
