<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hi Richard,</div><div class=""><br class=""></div><div class="">Looks like this caused some ASan failures:</div><div class=""><br class=""></div><div class=""><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__lab.llvm.org-3A8011_builders_sanitizer-2Dx86-5F64-2Dlinux-2Dfast_builds_5677&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=M_G_rDCclSVkMC1sIsgkikh7suKGRIYBSuttwvW1yMo&e=" class="">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5677</a></div><div class=""><br class=""></div><div class="">Can you please take a look?</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Adam</div><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 21, 2015, at 7:08 PM, Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk" class="">richard-llvm@metafoo.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">Author: rsmith<br class="">Date: Tue Jul 21 21:08:40 2015<br class="">New Revision: 242868<br class=""><br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D242868-26view-3Drev&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=WDp5NgCDBIroPU8yBpjOha6qBEVMyqCDBURP_2mrX6A&e=" class="">http://llvm.org/viewvc/llvm-project?rev=242868&view=rev</a><br class="">Log:<br class="">[modules] Stop performing PCM lookups for all identifiers when building with C++ modules. Instead, serialize a list of interesting identifiers and mark those ones out of date on module import. Avoiding the identifier lookups here gives a 20-30% speedup in builds with large numbers of modules. No functionality change intended.<br class=""><br class="">Modified:<br class=""> cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br class=""> cfe/trunk/include/clang/Serialization/Module.h<br class=""> cfe/trunk/include/clang/Serialization/ModuleManager.h<br class=""> cfe/trunk/lib/Sema/Sema.cpp<br class=""> cfe/trunk/lib/Serialization/ASTReader.cpp<br class=""> cfe/trunk/lib/Serialization/ASTWriter.cpp<br class=""> cfe/trunk/lib/Serialization/ModuleManager.cpp<br class=""><br class="">Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Serialization_ASTBitCodes.h-3Frev-3D242868-26r1-3D242867-26r2-3D242868-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=fNHKglhawkmrmA-MtVkd3RA8SZEGUYk47pMHBUztr8c&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=242868&r1=242867&r2=242868&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br class="">+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Jul 21 21:08:40 2015<br class="">@@ -543,7 +543,10 @@ namespace clang {<br class=""> /// macro definition.<br class=""> MACRO_OFFSET = 47,<br class=""><br class="">- // ID 48 used to be a table of macros.<br class="">+ /// \brief A list of "interesting" identifiers. Only used in C++ (where we<br class="">+ /// don't normally do lookups into the serialized identifier table). These<br class="">+ /// are eagerly deserialized.<br class="">+ INTERESTING_IDENTIFIERS = 48,<br class=""><br class=""> /// \brief Record code for undefined but used functions and variables that<br class=""> /// need a definition in this TU.<br class=""><br class="">Modified: cfe/trunk/include/clang/Serialization/Module.h<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Serialization_Module.h-3Frev-3D242868-26r1-3D242867-26r2-3D242868-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=iOiv-zGg4wb8bpiG8of0Z-N0Jrt8W8O2OMFur8acKOg&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=242868&r1=242867&r2=242868&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Serialization/Module.h (original)<br class="">+++ cfe/trunk/include/clang/Serialization/Module.h Tue Jul 21 21:08:40 2015<br class="">@@ -270,6 +270,10 @@ public:<br class=""> /// IdentifierHashTable.<br class=""> void *IdentifierLookupTable;<br class=""><br class="">+ /// \brief Offsets of identifiers that we're going to preload within<br class="">+ /// IdentifierTableData.<br class="">+ std::vector<unsigned> PreloadIdentifierOffsets;<br class="">+<br class=""> // === Macros ===<br class=""><br class=""> /// \brief The cursor to the start of the preprocessor block, which stores<br class=""><br class="">Modified: cfe/trunk/include/clang/Serialization/ModuleManager.h<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Serialization_ModuleManager.h-3Frev-3D242868-26r1-3D242867-26r2-3D242868-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=19nYUfR2tgUY-V30HxzwIEAydRMNuN3johF0n62BfMo&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ModuleManager.h?rev=242868&r1=242867&r2=242868&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Serialization/ModuleManager.h (original)<br class="">+++ cfe/trunk/include/clang/Serialization/ModuleManager.h Tue Jul 21 21:08:40 2015<br class="">@@ -30,14 +30,19 @@ namespace serialization {<br class=""><br class=""> /// \brief Manages the set of modules loaded by an AST reader.<br class=""> class ModuleManager {<br class="">- /// \brief The chain of AST files. The first entry is the one named by the<br class="">- /// user, the last one is the one that doesn't depend on anything further.<br class="">+ /// \brief The chain of AST files, in the order in which we started to load<br class="">+ /// them (this order isn't really useful for anything).<br class=""> SmallVector<ModuleFile *, 2> Chain;<br class=""><br class="">+ /// \brief The chain of non-module PCH files. The first entry is the one named<br class="">+ /// by the user, the last one is the one that doesn't depend on anything<br class="">+ /// further.<br class="">+ SmallVector<ModuleFile *, 2> PCHChain;<br class="">+<br class=""> // \brief The roots of the dependency DAG of AST files. This is used<br class=""> // to implement short-circuiting logic when running DFS over the dependencies.<br class=""> SmallVector<ModuleFile *, 2> Roots;<br class="">- <br class="">+<br class=""> /// \brief All loaded modules, indexed by name.<br class=""> llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;<br class=""><br class="">@@ -138,6 +143,11 @@ public:<br class=""> ModuleReverseIterator rbegin() { return Chain.rbegin(); }<br class=""> /// \brief Reverse iterator end-point to traverse all loaded modules.<br class=""> ModuleReverseIterator rend() { return Chain.rend(); }<br class="">+<br class="">+ /// \brief A range covering the PCH and preamble module files loaded.<br class="">+ llvm::iterator_range<ModuleConstIterator> pch_modules() const {<br class="">+ return llvm::make_range(PCHChain.begin(), PCHChain.end());<br class="">+ }<br class=""><br class=""> /// \brief Returns the primary module associated with the manager, that is,<br class=""> /// the first module loaded<br class=""><br class="">Modified: cfe/trunk/lib/Sema/Sema.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Sema_Sema.cpp-3Frev-3D242868-26r1-3D242867-26r2-3D242868-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=mk096rNummAEOvJsMjrQfud15K_YF0dVslgvxEisZAI&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=242868&r1=242867&r2=242868&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/Sema.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/Sema.cpp Tue Jul 21 21:08:40 2015<br class="">@@ -154,6 +154,9 @@ void Sema::Initialize() {<br class=""> // will not be able to merge any duplicate __va_list_tag decls correctly.<br class=""> VAListTagName = PP.getIdentifierInfo("__va_list_tag");<br class=""><br class="">+ if (!TUScope)<br class="">+ return;<br class="">+<br class=""> // Initialize predefined 128-bit integer types, if needed.<br class=""> if (Context.getTargetInfo().hasInt128Type()) {<br class=""> // If either of the 128-bit integer types are unavailable to name lookup,<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Serialization_ASTReader.cpp-3Frev-3D242868-26r1-3D242867-26r2-3D242868-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=Z0GBNBNwgMwX0R3E4hKb0oyVts2KiFH5Q8xkUilpA7E&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=242868&r1=242867&r2=242868&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Jul 21 21:08:40 2015<br class="">@@ -2564,6 +2564,10 @@ ASTReader::ReadASTBlock(ModuleFile &F, u<br class=""> break;<br class=""> }<br class=""><br class="">+ case INTERESTING_IDENTIFIERS:<br class="">+ F.PreloadIdentifierOffsets.assign(Record.begin(), Record.end());<br class="">+ break;<br class="">+<br class=""> case EAGERLY_DESERIALIZED_DECLS:<br class=""> // FIXME: Skip reading this record if our ASTConsumer doesn't care<br class=""> // about "interesting" decls (for instance, if we're building a module).<br class="">@@ -3410,6 +3414,18 @@ ASTReader::ASTReadResult ASTReader::Read<br class=""> // SourceManager.<br class=""> SourceMgr.getLoadedSLocEntryByID(Index);<br class=""> }<br class="">+<br class="">+ // Preload all the pending interesting identifiers by marking them out of<br class="">+ // date.<br class="">+ for (auto Offset : F.PreloadIdentifierOffsets) {<br class="">+ const unsigned char *Data = reinterpret_cast<const unsigned char *>(<br class="">+ F.IdentifierTableData + Offset);<br class="">+<br class="">+ ASTIdentifierLookupTrait Trait(*this, F);<br class="">+ auto KeyDataLen = Trait.ReadKeyDataLength(Data);<br class="">+ auto Key = Trait.ReadKey(Data, KeyDataLen.first);<br class="">+ PP.getIdentifierTable().getOwn(Key).setOutOfDate(true);<br class="">+ }<br class=""> }<br class=""><br class=""> // Setup the import locations and notify the module manager that we've<br class="">@@ -3430,13 +3446,20 @@ ASTReader::ASTReadResult ASTReader::Read<br class=""> M->ImportLoc.getRawEncoding());<br class=""> }<br class=""><br class="">- // Mark all of the identifiers in the identifier table as being out of date,<br class="">- // so that various accessors know to check the loaded modules when the<br class="">- // identifier is used.<br class="">- for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),<br class="">- IdEnd = PP.getIdentifierTable().end();<br class="">- Id != IdEnd; ++Id)<br class="">- Id->second->setOutOfDate(true);<br class="">+ if (!Context.getLangOpts().CPlusPlus ||<br class="">+ (Type != MK_ImplicitModule && Type != MK_ExplicitModule)) {<br class="">+ // Mark all of the identifiers in the identifier table as being out of date,<br class="">+ // so that various accessors know to check the loaded modules when the<br class="">+ // identifier is used.<br class="">+ //<br class="">+ // For C++ modules, we don't need information on many identifiers (just<br class="">+ // those that provide macros or are poisoned), so we mark all of<br class="">+ // the interesting ones via PreloadIdentifierOffsets.<br class="">+ for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),<br class="">+ IdEnd = PP.getIdentifierTable().end();<br class="">+ Id != IdEnd; ++Id)<br class="">+ Id->second->setOutOfDate(true);<br class="">+ }<br class=""><br class=""> // Resolve any unresolved module exports.<br class=""> for (unsigned I = 0, N = UnresolvedModuleRefs.size(); I != N; ++I) {<br class="">@@ -6827,19 +6850,32 @@ IdentifierInfo *ASTReader::get(StringRef<br class=""> // Note that we are loading an identifier.<br class=""> Deserializing AnIdentifier(this);<br class=""><br class="">- // If there is a global index, look there first to determine which modules<br class="">- // provably do not have any results for this identifier.<br class="">- GlobalModuleIndex::HitSet Hits;<br class="">- GlobalModuleIndex::HitSet *HitsPtr = nullptr;<br class="">- if (!loadGlobalIndex()) {<br class="">- if (GlobalIndex->lookupIdentifier(Name, Hits)) {<br class="">- HitsPtr = &Hits;<br class="">- }<br class="">- }<br class=""> IdentifierLookupVisitor Visitor(Name, /*PriorGeneration=*/0,<br class=""> NumIdentifierLookups,<br class=""> NumIdentifierLookupHits);<br class="">- ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor, HitsPtr);<br class="">+<br class="">+ // We don't need to do identifier table lookups in C++ modules (we preload<br class="">+ // all interesting declarations, and don't need to use the scope for name<br class="">+ // lookups). Perform the lookup in PCH files, though, since we don't build<br class="">+ // a complete initial identifier table if we're carrying on from a PCH.<br class="">+ if (Context.getLangOpts().CPlusPlus) {<br class="">+ for (auto F : ModuleMgr.pch_modules())<br class="">+ if (Visitor.visit(*F, &Visitor))<br class="">+ break;<br class="">+ } else {<br class="">+ // If there is a global index, look there first to determine which modules<br class="">+ // provably do not have any results for this identifier.<br class="">+ GlobalModuleIndex::HitSet Hits;<br class="">+ GlobalModuleIndex::HitSet *HitsPtr = nullptr;<br class="">+ if (!loadGlobalIndex()) {<br class="">+ if (GlobalIndex->lookupIdentifier(Name, Hits)) {<br class="">+ HitsPtr = &Hits;<br class="">+ }<br class="">+ }<br class="">+<br class="">+ ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor, HitsPtr);<br class="">+ }<br class="">+<br class=""> IdentifierInfo *II = Visitor.getIdentifierInfo();<br class=""> markIdentifierUpToDate(II);<br class=""> return II;<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Serialization_ASTWriter.cpp-3Frev-3D242868-26r1-3D242867-26r2-3D242868-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=49Ybq79SAM3ZdJK822fh7X8ulM6IGZzpz45M25zgbeE&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=242868&r1=242867&r2=242868&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Jul 21 21:08:40 2015<br class="">@@ -3104,6 +3104,7 @@ class ASTIdentifierTableTrait {<br class=""> IdentifierResolver &IdResolver;<br class=""> bool IsModule;<br class=""> bool NeedDecls;<br class="">+ ASTWriter::RecordData *InterestingIdentifierOffsets;<br class=""><br class=""> /// \brief Determines whether this is an "interesting" identifier that needs a<br class=""> /// full IdentifierInfo structure written into the hash table. Notably, this<br class="">@@ -3131,14 +3132,20 @@ public:<br class=""> typedef unsigned offset_type;<br class=""><br class=""> ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP,<br class="">- IdentifierResolver &IdResolver, bool IsModule)<br class="">+ IdentifierResolver &IdResolver, bool IsModule,<br class="">+ ASTWriter::RecordData *InterestingIdentifierOffsets)<br class=""> : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule),<br class="">- NeedDecls(!IsModule || !Writer.getLangOpts().CPlusPlus) {}<br class="">+ NeedDecls(!IsModule || !Writer.getLangOpts().CPlusPlus),<br class="">+ InterestingIdentifierOffsets(InterestingIdentifierOffsets) {}<br class=""><br class=""> static hash_value_type ComputeHash(const IdentifierInfo* II) {<br class=""> return llvm::HashString(II->getName());<br class=""> }<br class=""><br class="">+ bool isInterestingIdentifier(const IdentifierInfo *II) {<br class="">+ auto MacroOffset = Writer.getMacroDirectivesOffset(II);<br class="">+ return isInterestingIdentifier(II, MacroOffset);<br class="">+ }<br class=""> bool isInterestingNonMacroIdentifier(const IdentifierInfo *II) {<br class=""> return isInterestingIdentifier(II, 0);<br class=""> }<br class="">@@ -3178,6 +3185,12 @@ public:<br class=""> // Record the location of the key data. This is used when generating<br class=""> // the mapping from persistent IDs to strings.<br class=""> Writer.SetIdentifierOffset(II, Out.tell());<br class="">+<br class="">+ // Emit the offset of the key/data length information to the interesting<br class="">+ // identifiers table if necessary.<br class="">+ if (InterestingIdentifierOffsets && isInterestingIdentifier(II))<br class="">+ InterestingIdentifierOffsets->push_back(Out.tell() - 4);<br class="">+<br class=""> Out.write(II->getNameStart(), KeyLen);<br class=""> }<br class=""><br class="">@@ -3238,11 +3251,15 @@ void ASTWriter::WriteIdentifierTable(Pre<br class=""> bool IsModule) {<br class=""> using namespace llvm;<br class=""><br class="">+ RecordData InterestingIdents;<br class="">+<br class=""> // Create and write out the blob that contains the identifier<br class=""> // strings.<br class=""> {<br class=""> llvm::OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;<br class="">- ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule);<br class="">+ ASTIdentifierTableTrait Trait(<br class="">+ *this, PP, IdResolver, IsModule,<br class="">+ (getLangOpts().CPlusPlus && IsModule) ? &InterestingIdents : nullptr);<br class=""><br class=""> // Look for any identifiers that were named while processing the<br class=""> // headers, but are otherwise not needed. We add these to the hash<br class="">@@ -3316,6 +3333,11 @@ void ASTWriter::WriteIdentifierTable(Pre<br class=""> Record.push_back(FirstIdentID - NUM_PREDEF_IDENT_IDS);<br class=""> Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,<br class=""> bytes(IdentifierOffsets));<br class="">+<br class="">+ // In C++, write the list of interesting identifiers (those that are<br class="">+ // defined as macros, poisoned, or similar unusual things).<br class="">+ if (!InterestingIdents.empty())<br class="">+ Stream.EmitRecord(INTERESTING_IDENTIFIERS, InterestingIdents);<br class=""> }<br class=""><br class=""> //===----------------------------------------------------------------------===//<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ModuleManager.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Serialization_ModuleManager.cpp-3Frev-3D242868-26r1-3D242867-26r2-3D242868-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=yy0KdncFTTY9FTOXxtGlkGP_mKkR8bVkVWPhVa0DLrA&s=4z-ckzA-Jw0lIb25Hwpg13iiROqQ0EREVMTGxOAAqak&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=242868&r1=242867&r2=242868&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ModuleManager.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ModuleManager.cpp Tue Jul 21 21:08:40 2015<br class="">@@ -95,6 +95,8 @@ ModuleManager::addModule(StringRef FileN<br class=""> New->File = Entry;<br class=""> New->ImportLoc = ImportLoc;<br class=""> Chain.push_back(New);<br class="">+ if (!New->isModule())<br class="">+ PCHChain.push_back(New);<br class=""> if (!ImportedBy)<br class=""> Roots.push_back(New);<br class=""> NewModule = true;<br class="">@@ -159,6 +161,8 @@ ModuleManager::addModule(StringRef FileN<br class=""> Modules.erase(Entry);<br class=""> assert(Chain.back() == ModuleEntry);<br class=""> Chain.pop_back();<br class="">+ if (!ModuleEntry->isModule())<br class="">+ PCHChain.pop_back();<br class=""> if (Roots.back() == ModuleEntry)<br class=""> Roots.pop_back();<br class=""> else<br class="">@@ -225,6 +229,15 @@ void ModuleManager::removeModules(<br class=""><br class=""> // Remove the modules from the chain.<br class=""> Chain.erase(first, last);<br class="">+<br class="">+ // Also remove them from the PCH chain.<br class="">+ for (auto I = first; I != last; ++I) {<br class="">+ if (!(*I)->isModule()) {<br class="">+ PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), *I),<br class="">+ PCHChain.end());<br class="">+ break;<br class="">+ }<br class="">+ }<br class=""> }<br class=""><br class=""> void<br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@cs.uiuc.edu" class="">cfe-commits@cs.uiuc.edu</a><br class="">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits<br class=""></div></blockquote></div><br class=""></body></html>