diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp | 1280 |
1 files changed, 574 insertions, 706 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp index 416164e..609c25d 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp @@ -1,4 +1,4 @@ -//===--- ASTReader.cpp - AST File Reader ----------------------------------===// +//===-- ASTReader.cpp - AST File Reader ----------------------------------===// // // The LLVM Compiler Infrastructure // @@ -89,11 +89,13 @@ ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts, Second->ReadLanguageOptions(LangOpts, Complain, AllowCompatibleDifferences); } -bool -ChainedASTReaderListener::ReadTargetOptions(const TargetOptions &TargetOpts, - bool Complain) { - return First->ReadTargetOptions(TargetOpts, Complain) || - Second->ReadTargetOptions(TargetOpts, Complain); +bool ChainedASTReaderListener::ReadTargetOptions( + const TargetOptions &TargetOpts, bool Complain, + bool AllowCompatibleDifferences) { + return First->ReadTargetOptions(TargetOpts, Complain, + AllowCompatibleDifferences) || + Second->ReadTargetOptions(TargetOpts, Complain, + AllowCompatibleDifferences); } bool ChainedASTReaderListener::ReadDiagnosticOptions( IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) { @@ -108,9 +110,12 @@ ChainedASTReaderListener::ReadFileSystemOptions(const FileSystemOptions &FSOpts, } bool ChainedASTReaderListener::ReadHeaderSearchOptions( - const HeaderSearchOptions &HSOpts, bool Complain) { - return First->ReadHeaderSearchOptions(HSOpts, Complain) || - Second->ReadHeaderSearchOptions(HSOpts, Complain); + const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath, + bool Complain) { + return First->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath, + Complain) || + Second->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath, + Complain); } bool ChainedASTReaderListener::ReadPreprocessorOptions( const PreprocessorOptions &PPOpts, bool Complain, @@ -229,7 +234,8 @@ static bool checkLanguageOptions(const LangOptions &LangOpts, /// \returns true if the target options mis-match, false otherwise. static bool checkTargetOptions(const TargetOptions &TargetOpts, const TargetOptions &ExistingTargetOpts, - DiagnosticsEngine *Diags) { + DiagnosticsEngine *Diags, + bool AllowCompatibleDifferences = true) { #define CHECK_TARGET_OPT(Field, Name) \ if (TargetOpts.Field != ExistingTargetOpts.Field) { \ if (Diags) \ @@ -238,9 +244,16 @@ static bool checkTargetOptions(const TargetOptions &TargetOpts, return true; \ } + // The triple and ABI must match exactly. CHECK_TARGET_OPT(Triple, "target"); - CHECK_TARGET_OPT(CPU, "target CPU"); CHECK_TARGET_OPT(ABI, "target ABI"); + + // We can tolerate different CPUs in many cases, notably when one CPU + // supports a strict superset of another. When allowing compatible + // differences skip this check. + if (!AllowCompatibleDifferences) + CHECK_TARGET_OPT(CPU, "target CPU"); + #undef CHECK_TARGET_OPT // Compare feature sets. @@ -252,43 +265,31 @@ static bool checkTargetOptions(const TargetOptions &TargetOpts, std::sort(ExistingFeatures.begin(), ExistingFeatures.end()); std::sort(ReadFeatures.begin(), ReadFeatures.end()); - unsigned ExistingIdx = 0, ExistingN = ExistingFeatures.size(); - unsigned ReadIdx = 0, ReadN = ReadFeatures.size(); - while (ExistingIdx < ExistingN && ReadIdx < ReadN) { - if (ExistingFeatures[ExistingIdx] == ReadFeatures[ReadIdx]) { - ++ExistingIdx; - ++ReadIdx; - continue; - } - - if (ReadFeatures[ReadIdx] < ExistingFeatures[ExistingIdx]) { - if (Diags) - Diags->Report(diag::err_pch_targetopt_feature_mismatch) - << false << ReadFeatures[ReadIdx]; - return true; - } - - if (Diags) - Diags->Report(diag::err_pch_targetopt_feature_mismatch) - << true << ExistingFeatures[ExistingIdx]; - return true; - } + // We compute the set difference in both directions explicitly so that we can + // diagnose the differences differently. + SmallVector<StringRef, 4> UnmatchedExistingFeatures, UnmatchedReadFeatures; + std::set_difference( + ExistingFeatures.begin(), ExistingFeatures.end(), ReadFeatures.begin(), + ReadFeatures.end(), std::back_inserter(UnmatchedExistingFeatures)); + std::set_difference(ReadFeatures.begin(), ReadFeatures.end(), + ExistingFeatures.begin(), ExistingFeatures.end(), + std::back_inserter(UnmatchedReadFeatures)); + + // If we are allowing compatible differences and the read feature set is + // a strict subset of the existing feature set, there is nothing to diagnose. + if (AllowCompatibleDifferences && UnmatchedReadFeatures.empty()) + return false; - if (ExistingIdx < ExistingN) { - if (Diags) + if (Diags) { + for (StringRef Feature : UnmatchedReadFeatures) Diags->Report(diag::err_pch_targetopt_feature_mismatch) - << true << ExistingFeatures[ExistingIdx]; - return true; - } - - if (ReadIdx < ReadN) { - if (Diags) + << /* is-existing-feature */ false << Feature; + for (StringRef Feature : UnmatchedExistingFeatures) Diags->Report(diag::err_pch_targetopt_feature_mismatch) - << false << ReadFeatures[ReadIdx]; - return true; + << /* is-existing-feature */ true << Feature; } - return false; + return !UnmatchedReadFeatures.empty() || !UnmatchedExistingFeatures.empty(); } bool @@ -302,10 +303,12 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts, } bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts, - bool Complain) { + bool Complain, + bool AllowCompatibleDifferences) { const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts(); return checkTargetOptions(TargetOpts, ExistingTargetOpts, - Complain? &Reader.Diags : nullptr); + Complain ? &Reader.Diags : nullptr, + AllowCompatibleDifferences); } namespace { @@ -464,7 +467,7 @@ collectMacroDefinitions(const PreprocessorOptions &PPOpts, Macros[MacroName] = std::make_pair(MacroBody, false); } } - + /// \brief Check the preprocessor options deserialized from the control block /// against the preprocessor options in an existing preprocessor. /// @@ -591,6 +594,36 @@ bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, PP.getLangOpts()); } +/// Check the header search options deserialized from the control block +/// against the header search options in an existing preprocessor. +/// +/// \param Diags If non-null, produce diagnostics for any mismatches incurred. +static bool checkHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + StringRef SpecificModuleCachePath, + StringRef ExistingModuleCachePath, + DiagnosticsEngine *Diags, + const LangOptions &LangOpts) { + if (LangOpts.Modules) { + if (SpecificModuleCachePath != ExistingModuleCachePath) { + if (Diags) + Diags->Report(diag::err_pch_modulecache_mismatch) + << SpecificModuleCachePath << ExistingModuleCachePath; + return true; + } + } + + return false; +} + +bool PCHValidator::ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + StringRef SpecificModuleCachePath, + bool Complain) { + return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath, + PP.getHeaderSearchInfo().getModuleCachePath(), + Complain ? &Reader.Diags : nullptr, + PP.getLangOpts()); +} + void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) { PP.setCounterValue(Value); } @@ -744,8 +777,6 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, Bits >>= 1; bool ExtensionToken = Bits & 0x01; Bits >>= 1; - bool hasSubmoduleMacros = Bits & 0x01; - Bits >>= 1; bool hadMacroDefinition = Bits & 0x01; Bits >>= 1; @@ -787,49 +818,8 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, uint32_t MacroDirectivesOffset = endian::readNext<uint32_t, little, unaligned>(d); DataLen -= 4; - SmallVector<uint32_t, 8> LocalMacroIDs; - if (hasSubmoduleMacros) { - while (true) { - uint32_t LocalMacroID = - endian::readNext<uint32_t, little, unaligned>(d); - DataLen -= 4; - if (LocalMacroID == 0xdeadbeef) break; - LocalMacroIDs.push_back(LocalMacroID); - } - } - - if (F.Kind == MK_ImplicitModule || F.Kind == MK_ExplicitModule) { - // Macro definitions are stored from newest to oldest, so reverse them - // before registering them. - llvm::SmallVector<unsigned, 8> MacroSizes; - for (SmallVectorImpl<uint32_t>::iterator - I = LocalMacroIDs.begin(), E = LocalMacroIDs.end(); I != E; /**/) { - unsigned Size = 1; - - static const uint32_t HasOverridesFlag = 0x80000000U; - if (I + 1 != E && (I[1] & HasOverridesFlag)) - Size += 1 + (I[1] & ~HasOverridesFlag); - MacroSizes.push_back(Size); - I += Size; - } - - SmallVectorImpl<uint32_t>::iterator I = LocalMacroIDs.end(); - for (SmallVectorImpl<unsigned>::reverse_iterator SI = MacroSizes.rbegin(), - SE = MacroSizes.rend(); - SI != SE; ++SI) { - I -= *SI; - - uint32_t LocalMacroID = *I; - ArrayRef<uint32_t> Overrides; - if (*SI != 1) - Overrides = llvm::makeArrayRef(&I[2], *SI - 2); - Reader.addPendingMacroFromModule(II, &F, LocalMacroID, Overrides); - } - assert(I == LocalMacroIDs.begin()); - } else { - Reader.addPendingMacroFromPCH(II, &F, MacroDirectivesOffset); - } + Reader.addPendingMacro(II, &F, MacroDirectivesOffset); } Reader.SetIdentifierInfo(ID, II); @@ -1393,6 +1383,7 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { PreprocessorRecordTypes RecType = (PreprocessorRecordTypes)Stream.readRecord(Entry.ID, Record); switch (RecType) { + case PP_MODULE_MACRO: case PP_MACRO_DIRECTIVE_HISTORY: return Macro; @@ -1441,10 +1432,10 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { PreprocessedEntityID GlobalID = getGlobalPreprocessedEntityID(F, Record[NextIndex]); PreprocessingRecord &PPRec = *PP.getPreprocessingRecord(); - PreprocessingRecord::PPEntityID - PPID = PPRec.getPPEntityID(GlobalID-1, /*isLoaded=*/true); - MacroDefinition *PPDef = - cast_or_null<MacroDefinition>(PPRec.getPreprocessedEntity(PPID)); + PreprocessingRecord::PPEntityID PPID = + PPRec.getPPEntityID(GlobalID - 1, /*isLoaded=*/true); + MacroDefinitionRecord *PPDef = cast_or_null<MacroDefinitionRecord>( + PPRec.getPreprocessedEntity(PPID)); if (PPDef) PPRec.RegisterMacroDefinition(Macro, PPDef); } @@ -1586,24 +1577,9 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, return HFI; } -void -ASTReader::addPendingMacroFromModule(IdentifierInfo *II, ModuleFile *M, - GlobalMacroID GMacID, - ArrayRef<SubmoduleID> Overrides) { - assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard"); - SubmoduleID *OverrideData = nullptr; - if (!Overrides.empty()) { - OverrideData = new (Context) SubmoduleID[Overrides.size() + 1]; - OverrideData[0] = Overrides.size(); - for (unsigned I = 0; I != Overrides.size(); ++I) - OverrideData[I + 1] = getGlobalSubmoduleID(*M, Overrides[I]); - } - PendingMacroIDs[II].push_back(PendingMacroInfo(M, GMacID, OverrideData)); -} - -void ASTReader::addPendingMacroFromPCH(IdentifierInfo *II, - ModuleFile *M, - uint64_t MacroDirectivesOffset) { +void ASTReader::addPendingMacro(IdentifierInfo *II, + ModuleFile *M, + uint64_t MacroDirectivesOffset) { assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard"); PendingMacroIDs[II].push_back(PendingMacroInfo(M, MacroDirectivesOffset)); } @@ -1747,110 +1723,81 @@ void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) { IdentifierGeneration[II] = getGeneration(); } -struct ASTReader::ModuleMacroInfo { - SubmoduleID SubModID; - MacroInfo *MI; - SubmoduleID *Overrides; - // FIXME: Remove this. - ModuleFile *F; - - bool isDefine() const { return MI; } - - SubmoduleID getSubmoduleID() const { return SubModID; } - - ArrayRef<SubmoduleID> getOverriddenSubmodules() const { - if (!Overrides) - return None; - return llvm::makeArrayRef(Overrides + 1, *Overrides); - } - - MacroDirective *import(Preprocessor &PP, SourceLocation ImportLoc) const { - if (!MI) - return PP.AllocateUndefMacroDirective(ImportLoc, SubModID, - getOverriddenSubmodules()); - return PP.AllocateDefMacroDirective(MI, ImportLoc, SubModID, - getOverriddenSubmodules()); - } -}; - -ASTReader::ModuleMacroInfo * -ASTReader::getModuleMacro(const PendingMacroInfo &PMInfo) { - ModuleMacroInfo Info; - - uint32_t ID = PMInfo.ModuleMacroData.MacID; - if (ID & 1) { - // Macro undefinition. - Info.SubModID = getGlobalSubmoduleID(*PMInfo.M, ID >> 1); - Info.MI = nullptr; - } else { - // Macro definition. - GlobalMacroID GMacID = getGlobalMacroID(*PMInfo.M, ID >> 1); - assert(GMacID); - - // If this macro has already been loaded, don't do so again. - // FIXME: This is highly dubious. Multiple macro definitions can have the - // same MacroInfo (and hence the same GMacID) due to #pragma push_macro etc. - if (MacrosLoaded[GMacID - NUM_PREDEF_MACRO_IDS]) - return nullptr; +void ASTReader::resolvePendingMacro(IdentifierInfo *II, + const PendingMacroInfo &PMInfo) { + ModuleFile &M = *PMInfo.M; - Info.MI = getMacro(GMacID); - Info.SubModID = Info.MI->getOwningModuleID(); - } - Info.Overrides = PMInfo.ModuleMacroData.Overrides; - Info.F = PMInfo.M; + BitstreamCursor &Cursor = M.MacroCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(PMInfo.MacroDirectivesOffset); - return new (Context) ModuleMacroInfo(Info); -} + struct ModuleMacroRecord { + SubmoduleID SubModID; + MacroInfo *MI; + SmallVector<SubmoduleID, 8> Overrides; + }; + llvm::SmallVector<ModuleMacroRecord, 8> ModuleMacros; -void ASTReader::resolvePendingMacro(IdentifierInfo *II, - const PendingMacroInfo &PMInfo) { - assert(II); + // We expect to see a sequence of PP_MODULE_MACRO records listing exported + // macros, followed by a PP_MACRO_DIRECTIVE_HISTORY record with the complete + // macro histroy. + RecordData Record; + while (true) { + llvm::BitstreamEntry Entry = + Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd); + if (Entry.Kind != llvm::BitstreamEntry::Record) { + Error("malformed block record in AST file"); + return; + } - if (PMInfo.M->Kind != MK_ImplicitModule && - PMInfo.M->Kind != MK_ExplicitModule) { - installPCHMacroDirectives(II, *PMInfo.M, - PMInfo.PCHMacroData.MacroDirectivesOffset); - return; - } + Record.clear(); + switch ((PreprocessorRecordTypes)Cursor.readRecord(Entry.ID, Record)) { + case PP_MACRO_DIRECTIVE_HISTORY: + break; - // Module Macro. + case PP_MODULE_MACRO: { + ModuleMacros.push_back(ModuleMacroRecord()); + auto &Info = ModuleMacros.back(); + Info.SubModID = getGlobalSubmoduleID(M, Record[0]); + Info.MI = getMacro(getGlobalMacroID(M, Record[1])); + for (int I = 2, N = Record.size(); I != N; ++I) + Info.Overrides.push_back(getGlobalSubmoduleID(M, Record[I])); + continue; + } - ModuleMacroInfo *MMI = getModuleMacro(PMInfo); - if (!MMI) - return; + default: + Error("malformed block record in AST file"); + return; + } - Module *Owner = getSubmodule(MMI->getSubmoduleID()); - if (Owner && Owner->NameVisibility == Module::Hidden) { - // Macros in the owning module are hidden. Just remember this macro to - // install if we make this module visible. - HiddenNamesMap[Owner].HiddenMacros.insert(std::make_pair(II, MMI)); - } else { - installImportedMacro(II, MMI, Owner); + // We found the macro directive history; that's the last record + // for this macro. + break; } -} - -void ASTReader::installPCHMacroDirectives(IdentifierInfo *II, - ModuleFile &M, uint64_t Offset) { - assert(M.Kind != MK_ImplicitModule && M.Kind != MK_ExplicitModule); - BitstreamCursor &Cursor = M.MacroCursor; - SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(Offset); + // Module macros are listed in reverse dependency order. + { + std::reverse(ModuleMacros.begin(), ModuleMacros.end()); + llvm::SmallVector<ModuleMacro*, 8> Overrides; + for (auto &MMR : ModuleMacros) { + Overrides.clear(); + for (unsigned ModID : MMR.Overrides) { + Module *Mod = getSubmodule(ModID); + auto *Macro = PP.getModuleMacro(Mod, II); + assert(Macro && "missing definition for overridden macro"); + Overrides.push_back(Macro); + } - llvm::BitstreamEntry Entry = - Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd); - if (Entry.Kind != llvm::BitstreamEntry::Record) { - Error("malformed block record in AST file"); - return; + bool Inserted = false; + Module *Owner = getSubmodule(MMR.SubModID); + PP.addModuleMacro(Owner, II, MMR.MI, Overrides, Inserted); + } } - RecordData Record; - PreprocessorRecordTypes RecType = - (PreprocessorRecordTypes)Cursor.readRecord(Entry.ID, Record); - if (RecType != PP_MACRO_DIRECTIVE_HISTORY) { - Error("malformed block record in AST file"); + // Don't read the directive history for a module; we don't have anywhere + // to put it. + if (M.Kind == MK_ImplicitModule || M.Kind == MK_ExplicitModule) return; - } // Deserialize the macro directives history in reverse source-order. MacroDirective *Latest = nullptr, *Earliest = nullptr; @@ -1861,31 +1808,12 @@ void ASTReader::installPCHMacroDirectives(IdentifierInfo *II, MacroDirective::Kind K = (MacroDirective::Kind)Record[Idx++]; switch (K) { case MacroDirective::MD_Define: { - GlobalMacroID GMacID = getGlobalMacroID(M, Record[Idx++]); - MacroInfo *MI = getMacro(GMacID); - SubmoduleID ImportedFrom = Record[Idx++]; - bool IsAmbiguous = Record[Idx++]; - llvm::SmallVector<unsigned, 4> Overrides; - if (ImportedFrom) { - Overrides.insert(Overrides.end(), - &Record[Idx] + 1, &Record[Idx] + 1 + Record[Idx]); - Idx += Overrides.size() + 1; - } - DefMacroDirective *DefMD = - PP.AllocateDefMacroDirective(MI, Loc, ImportedFrom, Overrides); - DefMD->setAmbiguous(IsAmbiguous); - MD = DefMD; + MacroInfo *MI = getMacro(getGlobalMacroID(M, Record[Idx++])); + MD = PP.AllocateDefMacroDirective(MI, Loc); break; } case MacroDirective::MD_Undefine: { - SubmoduleID ImportedFrom = Record[Idx++]; - llvm::SmallVector<unsigned, 4> Overrides; - if (ImportedFrom) { - Overrides.insert(Overrides.end(), - &Record[Idx] + 1, &Record[Idx] + 1 + Record[Idx]); - Idx += Overrides.size() + 1; - } - MD = PP.AllocateUndefMacroDirective(Loc, ImportedFrom, Overrides); + MD = PP.AllocateUndefMacroDirective(Loc); break; } case MacroDirective::MD_Visibility: @@ -1901,177 +1829,8 @@ void ASTReader::installPCHMacroDirectives(IdentifierInfo *II, Earliest = MD; } - PP.setLoadedMacroDirective(II, Latest); -} - -/// \brief For the given macro definitions, check if they are both in system -/// modules. -static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI, - Module *NewOwner, ASTReader &Reader) { - assert(PrevMI && NewMI); - Module *PrevOwner = nullptr; - if (SubmoduleID PrevModID = PrevMI->getOwningModuleID()) - PrevOwner = Reader.getSubmodule(PrevModID); - SourceManager &SrcMgr = Reader.getSourceManager(); - bool PrevInSystem - = PrevOwner? PrevOwner->IsSystem - : SrcMgr.isInSystemHeader(PrevMI->getDefinitionLoc()); - bool NewInSystem - = NewOwner? NewOwner->IsSystem - : SrcMgr.isInSystemHeader(NewMI->getDefinitionLoc()); - if (PrevOwner && PrevOwner == NewOwner) - return false; - return PrevInSystem && NewInSystem; -} - -void ASTReader::removeOverriddenMacros(IdentifierInfo *II, - SourceLocation ImportLoc, - AmbiguousMacros &Ambig, - ArrayRef<SubmoduleID> Overrides) { - for (unsigned OI = 0, ON = Overrides.size(); OI != ON; ++OI) { - SubmoduleID OwnerID = Overrides[OI]; - - // If this macro is not yet visible, remove it from the hidden names list. - // It won't be there if we're in the middle of making the owner visible. - Module *Owner = getSubmodule(OwnerID); - auto HiddenIt = HiddenNamesMap.find(Owner); - if (HiddenIt != HiddenNamesMap.end()) { - HiddenNames &Hidden = HiddenIt->second; - HiddenMacrosMap::iterator HI = Hidden.HiddenMacros.find(II); - if (HI != Hidden.HiddenMacros.end()) { - // Register the macro now so we don't lose it when we re-export. - PP.appendMacroDirective(II, HI->second->import(PP, ImportLoc)); - - auto SubOverrides = HI->second->getOverriddenSubmodules(); - Hidden.HiddenMacros.erase(HI); - removeOverriddenMacros(II, ImportLoc, Ambig, SubOverrides); - } - } - - // If this macro is already in our list of conflicts, remove it from there. - Ambig.erase( - std::remove_if(Ambig.begin(), Ambig.end(), [&](DefMacroDirective *MD) { - return MD->getInfo()->getOwningModuleID() == OwnerID; - }), - Ambig.end()); - } -} - -ASTReader::AmbiguousMacros * -ASTReader::removeOverriddenMacros(IdentifierInfo *II, - SourceLocation ImportLoc, - ArrayRef<SubmoduleID> Overrides) { - MacroDirective *Prev = PP.getMacroDirective(II); - if (!Prev && Overrides.empty()) - return nullptr; - - DefMacroDirective *PrevDef = Prev ? Prev->getDefinition().getDirective() - : nullptr; - if (PrevDef && PrevDef->isAmbiguous()) { - // We had a prior ambiguity. Check whether we resolve it (or make it worse). - AmbiguousMacros &Ambig = AmbiguousMacroDefs[II]; - Ambig.push_back(PrevDef); - - removeOverriddenMacros(II, ImportLoc, Ambig, Overrides); - - if (!Ambig.empty()) - return &Ambig; - - AmbiguousMacroDefs.erase(II); - } else { - // There's no ambiguity yet. Maybe we're introducing one. - AmbiguousMacros Ambig; - if (PrevDef) - Ambig.push_back(PrevDef); - - removeOverriddenMacros(II, ImportLoc, Ambig, Overrides); - - if (!Ambig.empty()) { - AmbiguousMacros &Result = AmbiguousMacroDefs[II]; - std::swap(Result, Ambig); - return &Result; - } - } - - // We ended up with no ambiguity. - return nullptr; -} - -void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI, - Module *Owner) { - assert(II && Owner); - - SourceLocation ImportLoc = Owner->MacroVisibilityLoc; - if (ImportLoc.isInvalid()) { - // FIXME: If we made macros from this module visible but didn't provide a - // source location for the import, we don't have a location for the macro. - // Use the location at which the containing module file was first imported - // for now. - ImportLoc = MMI->F->DirectImportLoc; - assert(ImportLoc.isValid() && "no import location for a visible macro?"); - } - - AmbiguousMacros *Prev = - removeOverriddenMacros(II, ImportLoc, MMI->getOverriddenSubmodules()); - - // Create a synthetic macro definition corresponding to the import (or null - // if this was an undefinition of the macro). - MacroDirective *Imported = MMI->import(PP, ImportLoc); - DefMacroDirective *MD = dyn_cast<DefMacroDirective>(Imported); - - // If there's no ambiguity, just install the macro. - if (!Prev) { - PP.appendMacroDirective(II, Imported); - return; - } - assert(!Prev->empty()); - - if (!MD) { - // We imported a #undef that didn't remove all prior definitions. The most - // recent prior definition remains, and we install it in the place of the - // imported directive, as if by a local #pragma pop_macro. - MacroInfo *NewMI = Prev->back()->getInfo(); - Prev->pop_back(); - MD = PP.AllocateDefMacroDirective(NewMI, ImportLoc); - - // Install our #undef first so that we don't lose track of it. We'll replace - // this with whichever macro definition ends up winning. - PP.appendMacroDirective(II, Imported); - } - - // We're introducing a macro definition that creates or adds to an ambiguity. - // We can resolve that ambiguity if this macro is token-for-token identical to - // all of the existing definitions. - MacroInfo *NewMI = MD->getInfo(); - assert(NewMI && "macro definition with no MacroInfo?"); - while (!Prev->empty()) { - MacroInfo *PrevMI = Prev->back()->getInfo(); - assert(PrevMI && "macro definition with no MacroInfo?"); - - // Before marking the macros as ambiguous, check if this is a case where - // both macros are in system headers. If so, we trust that the system - // did not get it wrong. This also handles cases where Clang's own - // headers have a different spelling of certain system macros: - // #define LONG_MAX __LONG_MAX__ (clang's limits.h) - // #define LONG_MAX 0x7fffffffffffffffL (system's limits.h) - // - // FIXME: Remove the defined-in-system-headers check. clang's limits.h - // overrides the system limits.h's macros, so there's no conflict here. - if (NewMI != PrevMI && - !PrevMI->isIdenticalTo(*NewMI, PP, /*Syntactically=*/true) && - !areDefinedInSystemModules(PrevMI, NewMI, Owner, *this)) - break; - - // The previous definition is the same as this one (or both are defined in - // system modules so we can assume they're equivalent); we don't need to - // track it any more. - Prev->pop_back(); - } - - if (!Prev->empty()) - MD->setAmbiguous(true); - - PP.appendMacroDirective(II, MD); + if (Latest) + PP.setLoadedMacroDirective(II, Latest); } ASTReader::InputFileInfo @@ -2426,6 +2185,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, break; } + case KNOWN_MODULE_FILES: + break; + case LANGUAGE_OPTIONS: { bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; // FIXME: The &F == *ModuleMgr.begin() check is wrong for modules. @@ -2440,7 +2202,8 @@ ASTReader::ReadControlBlock(ModuleFile &F, case TARGET_OPTIONS: { bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0; if (Listener && &F == *ModuleMgr.begin() && - ParseTargetOptions(Record, Complain, *Listener) && + ParseTargetOptions(Record, Complain, *Listener, + AllowCompatibleConfigurationMismatch) && !DisableValidation && !AllowConfigurationMismatch) return ConfigurationMismatch; break; @@ -2543,7 +2306,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, case INPUT_FILE_OFFSETS: NumInputs = Record[0]; NumUserInputs = Record[1]; - F.InputFileOffsets = (const uint32_t *)Blob.data(); + F.InputFileOffsets = (const uint64_t *)Blob.data(); F.InputFilesLoaded.resize(NumInputs); break; } @@ -2795,6 +2558,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } case EAGERLY_DESERIALIZED_DECLS: + // FIXME: Skip reading this record if our ASTConsumer doesn't care + // about "interesting" decls (for instance, if we're building a module). for (unsigned I = 0, N = Record.size(); I != N; ++I) EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); break; @@ -2859,11 +2624,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; - case LOCALLY_SCOPED_EXTERN_C_DECLS: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - LocallyScopedExternCDecls.push_back(getGlobalDeclID(F, Record[I])); - break; - case SELECTOR_OFFSETS: { F.SelectorOffsets = (const uint32_t *)Blob.data(); F.LocalNumSelectors = Record[0]; @@ -3066,11 +2826,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; - case DYNAMIC_CLASSES: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - DynamicClasses.push_back(getGlobalDeclID(F, Record[I])); - break; - case PENDING_IMPLICIT_INSTANTIATIONS: if (PendingInstantiations.size() % 2 != 0) { Error("Invalid existing PendingInstantiations"); @@ -3172,16 +2927,26 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case OBJC_CATEGORIES: F.ObjCCategories.swap(Record); break; - + case CXX_BASE_SPECIFIER_OFFSETS: { if (F.LocalNumCXXBaseSpecifiers != 0) { Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file"); return Failure; } - + F.LocalNumCXXBaseSpecifiers = Record[0]; F.CXXBaseSpecifiersOffsets = (const uint32_t *)Blob.data(); - NumCXXBaseSpecifiersLoaded += F.LocalNumCXXBaseSpecifiers; + break; + } + + case CXX_CTOR_INITIALIZERS_OFFSETS: { + if (F.LocalNumCXXCtorInitializers != 0) { + Error("duplicate CXX_CTOR_INITIALIZERS_OFFSETS record in AST file"); + return Failure; + } + + F.LocalNumCXXCtorInitializers = Record[0]; + F.CXXCtorInitializersOffsets = (const uint32_t *)Blob.data(); break; } @@ -3256,6 +3021,18 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { ReadSourceLocation(F, Record, I).getRawEncoding()); } break; + case DELETE_EXPRS_TO_ANALYZE: + for (unsigned I = 0, N = Record.size(); I != N;) { + DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++])); + const uint64_t Count = Record[I++]; + DelayedDeleteExprs.push_back(Count); + for (uint64_t C = 0; C < Count; ++C) { + DelayedDeleteExprs.push_back(ReadSourceLocation(F, Record, I).getRawEncoding()); + bool IsArrayForm = Record[I++] == 1; + DelayedDeleteExprs.push_back(IsArrayForm); + } + } + break; case IMPORTED_MODULES: { if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule) { @@ -3288,16 +3065,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - case MERGED_DECLARATIONS: { - for (unsigned Idx = 0; Idx < Record.size(); /* increment in loop */) { - GlobalDeclID CanonID = getGlobalDeclID(F, Record[Idx++]); - SmallVectorImpl<GlobalDeclID> &Decls = StoredMergedDecls[CanonID]; - for (unsigned N = Record[Idx++]; N > 0; --N) - Decls.push_back(getGlobalDeclID(F, Record[Idx++])); - } - break; - } - case MACRO_OFFSET: { if (F.LocalNumMacros != 0) { Error("duplicate MACRO_OFFSET record in AST file"); @@ -3322,11 +3089,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - case MACRO_TABLE: { - // FIXME: Not used yet. - break; - } - case LATE_PARSED_TEMPLATE: { LateParsedTemplates.append(Record.begin(), Record.end()); break; @@ -3472,10 +3234,9 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { } } -void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner, - bool FromFinalization) { - // FIXME: Only do this if Owner->NameVisibility == AllVisible. - for (Decl *D : Names.HiddenDecls) { +void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) { + assert(Owner->NameVisibility != Module::Hidden && "nothing to make visible?"); + for (Decl *D : Names) { bool wasHidden = D->Hidden; D->Hidden = false; @@ -3485,22 +3246,11 @@ void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner, } } } - - assert((FromFinalization || Owner->NameVisibility >= Module::MacrosVisible) && - "nothing to make visible?"); - for (const auto &Macro : Names.HiddenMacros) { - if (FromFinalization) - PP.appendMacroDirective(Macro.first, - Macro.second->import(PP, SourceLocation())); - else - installImportedMacro(Macro.first, Macro.second, Owner); - } } void ASTReader::makeModuleVisible(Module *Mod, Module::NameVisibilityKind NameVisibility, - SourceLocation ImportLoc, - bool Complain) { + SourceLocation ImportLoc) { llvm::SmallPtrSet<Module *, 4> Visited; SmallVector<Module *, 4> Stack; Stack.push_back(Mod); @@ -3519,9 +3269,6 @@ void ASTReader::makeModuleVisible(Module *Mod, } // Update the module's name visibility. - if (NameVisibility >= Module::MacrosVisible && - Mod->NameVisibility < Module::MacrosVisible) - Mod->MacroVisibilityLoc = ImportLoc; Mod->NameVisibility = NameVisibility; // If we've already deserialized any names from this module, @@ -3530,8 +3277,7 @@ void ASTReader::makeModuleVisible(Module *Mod, if (Hidden != HiddenNamesMap.end()) { auto HiddenNames = std::move(*Hidden); HiddenNamesMap.erase(Hidden); - makeNamesVisible(HiddenNames.second, HiddenNames.first, - /*FromFinalization*/false); + makeNamesVisible(HiddenNames.second, HiddenNames.first); assert(HiddenNamesMap.find(Mod) == HiddenNamesMap.end() && "making names visible added hidden names"); } @@ -3545,20 +3291,6 @@ void ASTReader::makeModuleVisible(Module *Mod, if (Visited.insert(Exported).second) Stack.push_back(Exported); } - - // Detect any conflicts. - if (Complain) { - assert(ImportLoc.isValid() && "Missing import location"); - for (unsigned I = 0, N = Mod->Conflicts.size(); I != N; ++I) { - if (Mod->Conflicts[I].Other->NameVisibility >= NameVisibility) { - Diag(ImportLoc, diag::warn_module_conflict) - << Mod->getFullModuleName() - << Mod->Conflicts[I].Other->getFullModuleName() - << Mod->Conflicts[I].Message; - // FIXME: Need note where the other module was imported. - } - } - } } } @@ -3717,7 +3449,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, case UnresolvedModuleRef::Import: if (ResolvedMod) - Unresolved.Mod->Imports.push_back(ResolvedMod); + Unresolved.Mod->Imports.insert(ResolvedMod); continue; case UnresolvedModuleRef::Export: @@ -3785,6 +3517,14 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile); +/// \brief Whether \p Stream starts with the AST/PCH file magic number 'CPCH'. +static bool startsWithASTFileMagic(BitstreamCursor &Stream) { + return Stream.Read(8) == 'C' && + Stream.Read(8) == 'P' && + Stream.Read(8) == 'C' && + Stream.Read(8) == 'H'; +} + ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, ModuleKind Type, @@ -3854,10 +3594,7 @@ ASTReader::ReadASTCore(StringRef FileName, F.SizeInBits = F.Buffer->getBufferSize() * 8; // Sniff for the signature. - if (Stream.Read(8) != 'C' || - Stream.Read(8) != 'P' || - Stream.Read(8) != 'C' || - Stream.Read(8) != 'H') { + if (!startsWithASTFileMagic(Stream)) { Diag(diag::err_not_a_pch_file) << FileName; return Failure; } @@ -3924,7 +3661,7 @@ ASTReader::ReadASTCore(StringRef FileName, return Success; } -void ASTReader::InitializeContext() { +void ASTReader::InitializeContext() { // If there's a listener, notify them that we "read" the translation unit. if (DeserializationListener) DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, @@ -4047,24 +3784,19 @@ void ASTReader::InitializeContext() { } // Re-export any modules that were imported by a non-module AST file. - // FIXME: This does not make macro-only imports visible again. It also doesn't - // make #includes mapped to module imports visible. + // FIXME: This does not make macro-only imports visible again. for (auto &Import : ImportedModules) { - if (Module *Imported = getSubmodule(Import.ID)) + if (Module *Imported = getSubmodule(Import.ID)) { makeModuleVisible(Imported, Module::AllVisible, - /*ImportLoc=*/Import.ImportLoc, - /*Complain=*/false); + /*ImportLoc=*/Import.ImportLoc); + PP.makeModuleVisible(Imported, Import.ImportLoc); + } } ImportedModules.clear(); } void ASTReader::finalizeForWriting() { - while (!HiddenNamesMap.empty()) { - auto HiddenNames = std::move(*HiddenNamesMap.begin()); - HiddenNamesMap.erase(HiddenNamesMap.begin()); - makeNamesVisible(HiddenNames.second, HiddenNames.first, - /*FromFinalization*/true); - } + // Nothing to do for now. } /// \brief Given a cursor at the start of an AST file, scan ahead and drop the @@ -4097,14 +3829,12 @@ static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) { } } +/// \brief Reads and return the signature record from \p StreamFile's control +/// block, or else returns 0. static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile){ BitstreamCursor Stream(StreamFile); - if (Stream.Read(8) != 'C' || - Stream.Read(8) != 'P' || - Stream.Read(8) != 'C' || - Stream.Read(8) != 'H') { + if (!startsWithASTFileMagic(Stream)) return 0; - } // Scan for the CONTROL_BLOCK_ID block. if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) @@ -4146,10 +3876,7 @@ std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName, BitstreamCursor Stream(StreamFile); // Sniff for the signature. - if (Stream.Read(8) != 'C' || - Stream.Read(8) != 'P' || - Stream.Read(8) != 'C' || - Stream.Read(8) != 'H') { + if (!startsWithASTFileMagic(Stream)) { Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName; return std::string(); } @@ -4184,16 +3911,19 @@ namespace { const LangOptions &ExistingLangOpts; const TargetOptions &ExistingTargetOpts; const PreprocessorOptions &ExistingPPOpts; + std::string ExistingModuleCachePath; FileManager &FileMgr; - + public: SimplePCHValidator(const LangOptions &ExistingLangOpts, const TargetOptions &ExistingTargetOpts, const PreprocessorOptions &ExistingPPOpts, + StringRef ExistingModuleCachePath, FileManager &FileMgr) : ExistingLangOpts(ExistingLangOpts), ExistingTargetOpts(ExistingTargetOpts), ExistingPPOpts(ExistingPPOpts), + ExistingModuleCachePath(ExistingModuleCachePath), FileMgr(FileMgr) { } @@ -4203,9 +3933,17 @@ namespace { return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr, AllowCompatibleDifferences); } - bool ReadTargetOptions(const TargetOptions &TargetOpts, - bool Complain) override { - return checkTargetOptions(ExistingTargetOpts, TargetOpts, nullptr); + bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, + bool AllowCompatibleDifferences) override { + return checkTargetOptions(ExistingTargetOpts, TargetOpts, nullptr, + AllowCompatibleDifferences); + } + bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + StringRef SpecificModuleCachePath, + bool Complain) override { + return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath, + ExistingModuleCachePath, + nullptr, ExistingLangOpts); } bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, @@ -4220,6 +3958,8 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, ASTReaderListener &Listener) { // Open the AST file. + // FIXME: This allows use of the VFS; we do not allow use of the + // VFS when actually loading a module. auto Buffer = FileMgr.getBufferForFile(Filename); if (!Buffer) { return true; @@ -4232,12 +3972,8 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, BitstreamCursor Stream(StreamFile); // Sniff for the signature. - if (Stream.Read(8) != 'C' || - Stream.Read(8) != 'P' || - Stream.Read(8) != 'C' || - Stream.Read(8) != 'H') { + if (!startsWithASTFileMagic(Stream)) return true; - } // Scan for the CONTROL_BLOCK_ID block. if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) @@ -4310,7 +4046,8 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, break; case TARGET_OPTIONS: - if (ParseTargetOptions(Record, false, Listener)) + if (ParseTargetOptions(Record, false, Listener, + /*AllowCompatibleConfigurationMismatch*/ false)) return true; break; @@ -4343,7 +4080,7 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, unsigned NumInputFiles = Record[0]; unsigned NumUserFiles = Record[1]; - const uint32_t *InputFileOffs = (const uint32_t *)Blob.data(); + const uint64_t *InputFileOffs = (const uint64_t *)Blob.data(); for (unsigned I = 0; I != NumInputFiles; ++I) { // Go find this input file. bool isSystemFile = I >= NumUserFiles; @@ -4389,6 +4126,20 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, break; } + case KNOWN_MODULE_FILES: { + // Known-but-not-technically-used module files are treated as imports. + if (!NeedsImports) + break; + + unsigned Idx = 0, N = Record.size(); + while (Idx < N) { + std::string Filename = ReadString(Record, Idx); + ResolveImportedPath(Filename, ModuleDir); + Listener.visitImport(Filename); + } + break; + } + default: // No other validation to perform. break; @@ -4401,8 +4152,10 @@ bool ASTReader::isAcceptableASTFile(StringRef Filename, FileManager &FileMgr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, - const PreprocessorOptions &PPOpts) { - SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts, FileMgr); + const PreprocessorOptions &PPOpts, + std::string ExistingModuleCachePath) { + SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts, + ExistingModuleCachePath, FileMgr); return !readASTFileControlBlock(Filename, FileMgr, validator); } @@ -4529,13 +4282,19 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } case SUBMODULE_UMBRELLA_HEADER: { - if (const FileEntry *Umbrella = PP.getFileManager().getFile(Blob)) { + std::string Filename = Blob; + ResolveImportedPath(F, Filename); + if (auto *Umbrella = PP.getFileManager().getFile(Filename)) { if (!CurrentModule->getUmbrellaHeader()) - ModMap.setUmbrellaHeader(CurrentModule, Umbrella); - else if (CurrentModule->getUmbrellaHeader() != Umbrella) { - if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) - Error("mismatched umbrella headers in submodule"); - return OutOfDate; + ModMap.setUmbrellaHeader(CurrentModule, Umbrella, Blob); + else if (CurrentModule->getUmbrellaHeader().Entry != Umbrella) { + // This can be a spurious difference caused by changing the VFS to + // point to a different copy of the file, and it is too late to + // to rebuild safely. + // FIXME: If we wrote the virtual paths instead of the 'real' paths, + // after input file validation only real problems would remain and we + // could just error. For now, assume it's okay. + break; } } break; @@ -4561,11 +4320,12 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } case SUBMODULE_UMBRELLA_DIR: { - if (const DirectoryEntry *Umbrella - = PP.getFileManager().getDirectory(Blob)) { + std::string Dirname = Blob; + ResolveImportedPath(F, Dirname); + if (auto *Umbrella = PP.getFileManager().getDirectory(Dirname)) { if (!CurrentModule->getUmbrellaDir()) - ModMap.setUmbrellaDir(CurrentModule, Umbrella); - else if (CurrentModule->getUmbrellaDir() != Umbrella) { + ModMap.setUmbrellaDir(CurrentModule, Umbrella, Blob); + else if (CurrentModule->getUmbrellaDir().Entry != Umbrella) { if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) Error("mismatched umbrella directories in submodule"); return OutOfDate; @@ -4696,9 +4456,9 @@ bool ASTReader::ParseLanguageOptions(const RecordData &Record, AllowCompatibleDifferences); } -bool ASTReader::ParseTargetOptions(const RecordData &Record, - bool Complain, - ASTReaderListener &Listener) { +bool ASTReader::ParseTargetOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener, + bool AllowCompatibleDifferences) { unsigned Idx = 0; TargetOptions TargetOpts; TargetOpts.Triple = ReadString(Record, Idx); @@ -4711,7 +4471,8 @@ bool ASTReader::ParseTargetOptions(const RecordData &Record, TargetOpts.Features.push_back(ReadString(Record, Idx)); } - return Listener.ReadTargetOptions(TargetOpts, Complain); + return Listener.ReadTargetOptions(TargetOpts, Complain, + AllowCompatibleDifferences); } bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain, @@ -4753,16 +4514,15 @@ bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record, = static_cast<frontend::IncludeDirGroup>(Record[Idx++]); bool IsFramework = Record[Idx++]; bool IgnoreSysRoot = Record[Idx++]; - HSOpts.UserEntries.push_back( - HeaderSearchOptions::Entry(Path, Group, IsFramework, IgnoreSysRoot)); + HSOpts.UserEntries.emplace_back(std::move(Path), Group, IsFramework, + IgnoreSysRoot); } // System header prefixes. for (unsigned N = Record[Idx++]; N; --N) { std::string Prefix = ReadString(Record, Idx); bool IsSystemHeader = Record[Idx++]; - HSOpts.SystemHeaderPrefixes.push_back( - HeaderSearchOptions::SystemHeaderPrefix(Prefix, IsSystemHeader)); + HSOpts.SystemHeaderPrefixes.emplace_back(std::move(Prefix), IsSystemHeader); } HSOpts.ResourceDir = ReadString(Record, Idx); @@ -4773,8 +4533,10 @@ bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record, HSOpts.UseStandardSystemIncludes = Record[Idx++]; HSOpts.UseStandardCXXIncludes = Record[Idx++]; HSOpts.UseLibcxx = Record[Idx++]; + std::string SpecificModuleCachePath = ReadString(Record, Idx); - return Listener.ReadHeaderSearchOptions(HSOpts, Complain); + return Listener.ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath, + Complain); } bool ASTReader::ParsePreprocessorOptions(const RecordData &Record, @@ -4823,21 +4585,22 @@ ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) { return std::make_pair(M, LocalIndex); } -std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> +llvm::iterator_range<PreprocessingRecord::iterator> ASTReader::getModulePreprocessedEntities(ModuleFile &Mod) const { if (PreprocessingRecord *PPRec = PP.getPreprocessingRecord()) return PPRec->getIteratorsForLoadedRange(Mod.BasePreprocessedEntityID, Mod.NumPreprocessedEntities); - return std::make_pair(PreprocessingRecord::iterator(), - PreprocessingRecord::iterator()); + return llvm::make_range(PreprocessingRecord::iterator(), + PreprocessingRecord::iterator()); } -std::pair<ASTReader::ModuleDeclIterator, ASTReader::ModuleDeclIterator> +llvm::iterator_range<ASTReader::ModuleDeclIterator> ASTReader::getModuleFileLevelDecls(ModuleFile &Mod) { - return std::make_pair(ModuleDeclIterator(this, &Mod, Mod.FileSortedDecls), - ModuleDeclIterator(this, &Mod, - Mod.FileSortedDecls + Mod.NumFileSortedDecls)); + return llvm::make_range( + ModuleDeclIterator(this, &Mod, Mod.FileSortedDecls), + ModuleDeclIterator(this, &Mod, + Mod.FileSortedDecls + Mod.NumFileSortedDecls)); } PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { @@ -4873,13 +4636,14 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { case PPD_MACRO_EXPANSION: { bool isBuiltin = Record[0]; IdentifierInfo *Name = nullptr; - MacroDefinition *Def = nullptr; + MacroDefinitionRecord *Def = nullptr; if (isBuiltin) Name = getLocalIdentifier(M, Record[1]); else { - PreprocessedEntityID - GlobalID = getGlobalPreprocessedEntityID(M, Record[1]); - Def =cast<MacroDefinition>(PPRec.getLoadedPreprocessedEntity(GlobalID-1)); + PreprocessedEntityID GlobalID = + getGlobalPreprocessedEntityID(M, Record[1]); + Def = cast<MacroDefinitionRecord>( + PPRec.getLoadedPreprocessedEntity(GlobalID - 1)); } MacroExpansion *ME; @@ -4895,8 +4659,7 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { // Decode the identifier info and then check again; if the macro is // still defined and associated with the identifier, IdentifierInfo *II = getLocalIdentifier(M, Record[0]); - MacroDefinition *MD - = new (PPRec) MacroDefinition(II, Range); + MacroDefinitionRecord *MD = new (PPRec) MacroDefinitionRecord(II, Range); if (DeserializationListener) DeserializationListener->MacroDefinitionRead(PPID, MD); @@ -6081,6 +5844,12 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) { return GetDecl(ID); } +template<typename TemplateSpecializationDecl> +static void completeRedeclChainForTemplateSpecialization(Decl *D) { + if (auto *TSD = dyn_cast<TemplateSpecializationDecl>(D)) + TSD->getSpecializedTemplate()->LoadLazySpecializations(); +} + void ASTReader::CompleteRedeclChain(const Decl *D) { if (NumCurrentElementsDeserializing) { // We arrange to not care about the complete redeclaration chain while we're @@ -6114,6 +5883,47 @@ void ASTReader::CompleteRedeclChain(const Decl *D) { D->getDeclContext()->decls_begin(); } } + + if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) + CTSD->getSpecializedTemplate()->LoadLazySpecializations(); + if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) + VTSD->getSpecializedTemplate()->LoadLazySpecializations(); + if (auto *FD = dyn_cast<FunctionDecl>(D)) { + if (auto *Template = FD->getPrimaryTemplate()) + Template->LoadLazySpecializations(); + } +} + +uint64_t ASTReader::ReadCXXCtorInitializersRef(ModuleFile &M, + const RecordData &Record, + unsigned &Idx) { + if (Idx >= Record.size() || Record[Idx] > M.LocalNumCXXCtorInitializers) { + Error("malformed AST file: missing C++ ctor initializers"); + return 0; + } + + unsigned LocalID = Record[Idx++]; + return getGlobalBitOffset(M, M.CXXCtorInitializersOffsets[LocalID - 1]); +} + +CXXCtorInitializer ** +ASTReader::GetExternalCXXCtorInitializers(uint64_t Offset) { + RecordLocation Loc = getLocalBitOffset(Offset); + BitstreamCursor &Cursor = Loc.F->DeclsCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(Loc.Offset); + ReadingKindTracker ReadingKind(Read_Decl, *this); + + RecordData Record; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.readRecord(Code, Record); + if (RecCode != DECL_CXX_CTOR_INITIALIZERS) { + Error("malformed AST file: missing C++ ctor initializers"); + return nullptr; + } + + unsigned Idx = 0; + return ReadCXXCtorInitializers(*Loc.F, Record, Idx); } uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, @@ -6165,6 +5975,10 @@ ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const { bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const { + // Predefined decls aren't from any module. + if (ID < NUM_PREDEF_DECL_IDS) + return false; + GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(ID); assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); return &M == I->second; @@ -6197,39 +6011,55 @@ SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { return ReadSourceLocation(*Rec.F, RawLocation); } -Decl *ASTReader::GetExistingDecl(DeclID ID) { - if (ID < NUM_PREDEF_DECL_IDS) { - switch ((PredefinedDeclIDs)ID) { - case PREDEF_DECL_NULL_ID: - return nullptr; +static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { + switch (ID) { + case PREDEF_DECL_NULL_ID: + return nullptr; + + case PREDEF_DECL_TRANSLATION_UNIT_ID: + return Context.getTranslationUnitDecl(); - case PREDEF_DECL_TRANSLATION_UNIT_ID: - return Context.getTranslationUnitDecl(); + case PREDEF_DECL_OBJC_ID_ID: + return Context.getObjCIdDecl(); - case PREDEF_DECL_OBJC_ID_ID: - return Context.getObjCIdDecl(); + case PREDEF_DECL_OBJC_SEL_ID: + return Context.getObjCSelDecl(); - case PREDEF_DECL_OBJC_SEL_ID: - return Context.getObjCSelDecl(); + case PREDEF_DECL_OBJC_CLASS_ID: + return Context.getObjCClassDecl(); - case PREDEF_DECL_OBJC_CLASS_ID: - return Context.getObjCClassDecl(); + case PREDEF_DECL_OBJC_PROTOCOL_ID: + return Context.getObjCProtocolDecl(); - case PREDEF_DECL_OBJC_PROTOCOL_ID: - return Context.getObjCProtocolDecl(); + case PREDEF_DECL_INT_128_ID: + return Context.getInt128Decl(); - case PREDEF_DECL_INT_128_ID: - return Context.getInt128Decl(); + case PREDEF_DECL_UNSIGNED_INT_128_ID: + return Context.getUInt128Decl(); - case PREDEF_DECL_UNSIGNED_INT_128_ID: - return Context.getUInt128Decl(); + case PREDEF_DECL_OBJC_INSTANCETYPE_ID: + return Context.getObjCInstanceTypeDecl(); - case PREDEF_DECL_OBJC_INSTANCETYPE_ID: - return Context.getObjCInstanceTypeDecl(); + case PREDEF_DECL_BUILTIN_VA_LIST_ID: + return Context.getBuiltinVaListDecl(); - case PREDEF_DECL_BUILTIN_VA_LIST_ID: - return Context.getBuiltinVaListDecl(); + case PREDEF_DECL_EXTERN_C_CONTEXT_ID: + return Context.getExternCContextDecl(); + } + llvm_unreachable("PredefinedDeclIDs unknown enum value"); +} + +Decl *ASTReader::GetExistingDecl(DeclID ID) { + if (ID < NUM_PREDEF_DECL_IDS) { + Decl *D = getPredefinedDecl(Context, (PredefinedDeclIDs)ID); + if (D) { + // Track that we have merged the declaration with ID \p ID into the + // pre-existing predefined declaration \p D. + auto &Merged = MergedDecls[D->getCanonicalDecl()]; + if (Merged.empty()) + Merged.push_back(ID); } + return D; } unsigned Index = ID - NUM_PREDEF_DECL_IDS; @@ -6326,10 +6156,7 @@ namespace { PredefsVisited[I] = false; } - static bool visit(ModuleFile &M, bool Preorder, void *UserData) { - if (Preorder) - return false; - + static bool visitPostorder(ModuleFile &M, void *UserData) { FindExternalLexicalDeclsVisitor *This = static_cast<FindExternalLexicalDeclsVisitor *>(UserData); @@ -6371,7 +6198,8 @@ ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC, // There might be lexical decls in multiple modules, for the TU at // least. Walk all of the modules in the order they were loaded. FindExternalLexicalDeclsVisitor Visitor(*this, DC, isKindWeWant, Decls); - ModuleMgr.visitDepthFirst(&FindExternalLexicalDeclsVisitor::visit, &Visitor); + ModuleMgr.visitDepthFirst( + nullptr, &FindExternalLexicalDeclsVisitor::visitPostorder, &Visitor); ++NumLexicalDeclContextsRead; return ELR_Success; } @@ -6460,13 +6288,16 @@ namespace { ArrayRef<const DeclContext *> Contexts; DeclarationName Name; SmallVectorImpl<NamedDecl *> &Decls; + llvm::SmallPtrSetImpl<NamedDecl *> &DeclSet; public: DeclContextNameLookupVisitor(ASTReader &Reader, ArrayRef<const DeclContext *> Contexts, DeclarationName Name, - SmallVectorImpl<NamedDecl *> &Decls) - : Reader(Reader), Contexts(Contexts), Name(Name), Decls(Decls) { } + SmallVectorImpl<NamedDecl *> &Decls, + llvm::SmallPtrSetImpl<NamedDecl *> &DeclSet) + : Reader(Reader), Contexts(Contexts), Name(Name), Decls(Decls), + DeclSet(DeclSet) { } static bool visit(ModuleFile &M, void *UserData) { DeclContextNameLookupVisitor *This @@ -6515,7 +6346,8 @@ namespace { // Record this declaration. FoundAnything = true; - This->Decls.push_back(ND); + if (This->DeclSet.insert(ND).second) + This->Decls.push_back(ND); } return FoundAnything; @@ -6555,6 +6387,7 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, Deserializing LookupResults(this); SmallVector<NamedDecl *, 64> Decls; + llvm::SmallPtrSet<NamedDecl*, 64> DeclSet; // Compute the declaration contexts we need to look into. Multiple such // declaration contexts occur when two declaration contexts from disjoint @@ -6572,7 +6405,7 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, } auto LookUpInContexts = [&](ArrayRef<const DeclContext*> Contexts) { - DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls); + DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls, DeclSet); // If we can definitively determine which module file to look into, // only look there. Otherwise, look in all module files. @@ -6592,19 +6425,14 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, // individually, because finding an entity in one of them doesn't imply that // we can't find a different entity in another one. if (isa<CXXRecordDecl>(DC)) { - auto Kind = Name.getNameKind(); - if (Kind == DeclarationName::CXXConstructorName || - Kind == DeclarationName::CXXDestructorName || - (Kind == DeclarationName::CXXOperatorName && - Name.getCXXOverloadedOperator() == OO_Equal)) { - auto Merged = MergedLookups.find(DC); - if (Merged != MergedLookups.end()) { - for (unsigned I = 0; I != Merged->second.size(); ++I) { - LookUpInContexts(Merged->second[I]); - // We might have just added some more merged lookups. If so, our - // iterator is now invalid, so grab a fresh one before continuing. - Merged = MergedLookups.find(DC); - } + auto Merged = MergedLookups.find(DC); + if (Merged != MergedLookups.end()) { + for (unsigned I = 0; I != Merged->second.size(); ++I) { + const DeclContext *Context = Merged->second[I]; + LookUpInContexts(Context); + // We might have just added some more merged lookups. If so, our + // iterator is now invalid, so grab a fresh one before continuing. + Merged = MergedLookups.find(DC); } } } @@ -6621,6 +6449,7 @@ namespace { ASTReader &Reader; SmallVectorImpl<const DeclContext *> &Contexts; DeclsMap &Decls; + llvm::SmallPtrSet<NamedDecl *, 256> DeclSet; bool VisitAll; public: @@ -6665,7 +6494,8 @@ namespace { // Record this declaration. FoundAnything = true; - This->Decls[ND->getDeclName()].push_back(ND); + if (This->DeclSet.insert(ND).second) + This->Decls[ND->getDeclName()].push_back(ND); } } @@ -6731,6 +6561,12 @@ void ASTReader::PassInterestingDeclsToConsumer() { SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer, true); + // Ensure that we've loaded all potentially-interesting declarations + // that need to be eagerly loaded. + for (auto ID : EagerlyDeserializedDecls) + GetDecl(ID); + EagerlyDeserializedDecls.clear(); + while (!InterestingDecls.empty()) { Decl *D = InterestingDecls.front(); InterestingDecls.pop_front(); @@ -6749,17 +6585,11 @@ void ASTReader::PassInterestingDeclToConsumer(Decl *D) { void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) { this->Consumer = Consumer; - if (!Consumer) - return; + if (Consumer) + PassInterestingDeclsToConsumer(); - for (unsigned I = 0, N = EagerlyDeserializedDecls.size(); I != N; ++I) { - // Force deserialization of this decl, which will cause it to be queued for - // passing to the consumer. - GetDecl(EagerlyDeserializedDecls[I]); - } - EagerlyDeserializedDecls.clear(); - - PassInterestingDeclsToConsumer(); + if (DeserializationListener) + DeserializationListener->ReaderInitialized(this); } void ASTReader::PrintStats() { @@ -7195,6 +7025,21 @@ void ASTReader::ReadUndefinedButUsed( } } +void ASTReader::ReadMismatchingDeleteExpressions(llvm::MapVector< + FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & + Exprs) { + for (unsigned Idx = 0, N = DelayedDeleteExprs.size(); Idx != N;) { + FieldDecl *FD = cast<FieldDecl>(GetDecl(DelayedDeleteExprs[Idx++])); + uint64_t Count = DelayedDeleteExprs[Idx++]; + for (uint64_t C = 0; C < Count; ++C) { + SourceLocation DeleteLoc = + SourceLocation::getFromRawEncoding(DelayedDeleteExprs[Idx++]); + const bool IsArrayForm = DelayedDeleteExprs[Idx++]; + Exprs[FD].push_back(std::make_pair(DeleteLoc, IsArrayForm)); + } + } +} + void ASTReader::ReadTentativeDefinitions( SmallVectorImpl<VarDecl *> &TentativeDefs) { for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) { @@ -7237,16 +7082,6 @@ void ASTReader::ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) { ExtVectorDecls.clear(); } -void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) { - for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) { - CXXRecordDecl *D - = dyn_cast_or_null<CXXRecordDecl>(GetDecl(DynamicClasses[I])); - if (D) - Decls.push_back(D); - } - DynamicClasses.clear(); -} - void ASTReader::ReadUnusedLocalTypedefNameCandidates( llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) { for (unsigned I = 0, N = UnusedLocalTypedefNameCandidates.size(); I != N; @@ -7259,17 +7094,6 @@ void ASTReader::ReadUnusedLocalTypedefNameCandidates( UnusedLocalTypedefNameCandidates.clear(); } -void -ASTReader::ReadLocallyScopedExternCDecls(SmallVectorImpl<NamedDecl *> &Decls) { - for (unsigned I = 0, N = LocallyScopedExternCDecls.size(); I != N; ++I) { - NamedDecl *D - = dyn_cast_or_null<NamedDecl>(GetDecl(LocallyScopedExternCDecls[I])); - if (D) - Decls.push_back(D); - } - LocallyScopedExternCDecls.clear(); -} - void ASTReader::ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) { if (ReferencedSelectorsData.empty()) @@ -7333,7 +7157,7 @@ void ASTReader::ReadPendingInstantiations( } void ASTReader::ReadLateParsedTemplates( - llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) { + llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) { for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N; /* In loop */) { FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++])); @@ -7349,7 +7173,7 @@ void ASTReader::ReadLateParsedTemplates( for (unsigned T = 0; T < TokN; ++T) LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx)); - LPTMap[FD] = LT; + LPTMap.insert(std::make_pair(FD, LT)); } LateParsedTemplates.clear(); @@ -7840,92 +7664,89 @@ ASTReader::ReadCXXBaseSpecifier(ModuleFile &F, return Result; } -std::pair<CXXCtorInitializer **, unsigned> +CXXCtorInitializer ** ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, unsigned &Idx) { - CXXCtorInitializer **CtorInitializers = nullptr; unsigned NumInitializers = Record[Idx++]; - if (NumInitializers) { - CtorInitializers - = new (Context) CXXCtorInitializer*[NumInitializers]; - for (unsigned i=0; i != NumInitializers; ++i) { - TypeSourceInfo *TInfo = nullptr; - bool IsBaseVirtual = false; - FieldDecl *Member = nullptr; - IndirectFieldDecl *IndirectMember = nullptr; - - CtorInitializerType Type = (CtorInitializerType)Record[Idx++]; - switch (Type) { - case CTOR_INITIALIZER_BASE: - TInfo = GetTypeSourceInfo(F, Record, Idx); - IsBaseVirtual = Record[Idx++]; - break; - - case CTOR_INITIALIZER_DELEGATING: - TInfo = GetTypeSourceInfo(F, Record, Idx); - break; + assert(NumInitializers && "wrote ctor initializers but have no inits"); + auto **CtorInitializers = new (Context) CXXCtorInitializer*[NumInitializers]; + for (unsigned i = 0; i != NumInitializers; ++i) { + TypeSourceInfo *TInfo = nullptr; + bool IsBaseVirtual = false; + FieldDecl *Member = nullptr; + IndirectFieldDecl *IndirectMember = nullptr; - case CTOR_INITIALIZER_MEMBER: - Member = ReadDeclAs<FieldDecl>(F, Record, Idx); - break; + CtorInitializerType Type = (CtorInitializerType)Record[Idx++]; + switch (Type) { + case CTOR_INITIALIZER_BASE: + TInfo = GetTypeSourceInfo(F, Record, Idx); + IsBaseVirtual = Record[Idx++]; + break; - case CTOR_INITIALIZER_INDIRECT_MEMBER: - IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx); - break; - } + case CTOR_INITIALIZER_DELEGATING: + TInfo = GetTypeSourceInfo(F, Record, Idx); + break; - SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx); - Expr *Init = ReadExpr(F); - SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx); - SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx); - bool IsWritten = Record[Idx++]; - unsigned SourceOrderOrNumArrayIndices; - SmallVector<VarDecl *, 8> Indices; - if (IsWritten) { - SourceOrderOrNumArrayIndices = Record[Idx++]; - } else { - SourceOrderOrNumArrayIndices = Record[Idx++]; - Indices.reserve(SourceOrderOrNumArrayIndices); - for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i) - Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx)); - } + case CTOR_INITIALIZER_MEMBER: + Member = ReadDeclAs<FieldDecl>(F, Record, Idx); + break; - CXXCtorInitializer *BOMInit; - if (Type == CTOR_INITIALIZER_BASE) { - BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, IsBaseVirtual, - LParenLoc, Init, RParenLoc, - MemberOrEllipsisLoc); - } else if (Type == CTOR_INITIALIZER_DELEGATING) { - BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, LParenLoc, - Init, RParenLoc); - } else if (IsWritten) { - if (Member) - BOMInit = new (Context) CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc, - LParenLoc, Init, RParenLoc); - else - BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember, - MemberOrEllipsisLoc, LParenLoc, - Init, RParenLoc); + case CTOR_INITIALIZER_INDIRECT_MEMBER: + IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx); + break; + } + + SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx); + Expr *Init = ReadExpr(F); + SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx); + SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx); + bool IsWritten = Record[Idx++]; + unsigned SourceOrderOrNumArrayIndices; + SmallVector<VarDecl *, 8> Indices; + if (IsWritten) { + SourceOrderOrNumArrayIndices = Record[Idx++]; + } else { + SourceOrderOrNumArrayIndices = Record[Idx++]; + Indices.reserve(SourceOrderOrNumArrayIndices); + for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i) + Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx)); + } + + CXXCtorInitializer *BOMInit; + if (Type == CTOR_INITIALIZER_BASE) { + BOMInit = new (Context) + CXXCtorInitializer(Context, TInfo, IsBaseVirtual, LParenLoc, Init, + RParenLoc, MemberOrEllipsisLoc); + } else if (Type == CTOR_INITIALIZER_DELEGATING) { + BOMInit = new (Context) + CXXCtorInitializer(Context, TInfo, LParenLoc, Init, RParenLoc); + } else if (IsWritten) { + if (Member) + BOMInit = new (Context) CXXCtorInitializer( + Context, Member, MemberOrEllipsisLoc, LParenLoc, Init, RParenLoc); + else + BOMInit = new (Context) + CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc, + LParenLoc, Init, RParenLoc); + } else { + if (IndirectMember) { + assert(Indices.empty() && "Indirect field improperly initialized"); + BOMInit = new (Context) + CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc, + LParenLoc, Init, RParenLoc); } else { - if (IndirectMember) { - assert(Indices.empty() && "Indirect field improperly initialized"); - BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember, - MemberOrEllipsisLoc, LParenLoc, - Init, RParenLoc); - } else { - BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc, - LParenLoc, Init, RParenLoc, - Indices.data(), Indices.size()); - } + BOMInit = CXXCtorInitializer::Create( + Context, Member, MemberOrEllipsisLoc, LParenLoc, Init, RParenLoc, + Indices.data(), Indices.size()); } - - if (IsWritten) - BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices); - CtorInitializers[i] = BOMInit; } + + if (IsWritten) + BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices); + CtorInitializers[i] = BOMInit; } - return std::make_pair(CtorInitializers, NumInitializers); + return CtorInitializers; } NestedNameSpecifier * @@ -8203,7 +8024,7 @@ void ASTReader::getInputFiles(ModuleFile &F, std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) { // If we know the owning module, use it. - if (Module *M = D->getOwningModule()) + if (Module *M = D->getImportedOwningModule()) return M->getFullModuleName(); // Otherwise, use the name of the top-level module the decl is within. @@ -8243,9 +8064,10 @@ void ASTReader::finishPendingActions() { // Load pending declaration chains. for (unsigned I = 0; I != PendingDeclChains.size(); ++I) { - loadPendingDeclChain(PendingDeclChains[I]); PendingDeclChainsKnown.erase(PendingDeclChains[I]); + loadPendingDeclChain(PendingDeclChains[I]); } + assert(PendingDeclChainsKnown.empty()); PendingDeclChains.clear(); // Make the most recent of the top-level declarations visible. @@ -8298,7 +8120,12 @@ void ASTReader::finishPendingActions() { loadDeclUpdateRecords(Update.first, Update.second); } } - + + // At this point, all update records for loaded decls are in place, so any + // fake class definitions should have become real. + assert(PendingFakeDefinitionData.empty() && + "faked up a class definition but never saw the real one"); + // If we deserialized any C++ or Objective-C class definitions, any // Objective-C protocol definitions, or any redeclarable templates, make sure // that all redeclarations point to the definitions. Note that this can only @@ -8309,10 +8136,12 @@ void ASTReader::finishPendingActions() { // Make sure that the TagType points at the definition. const_cast<TagType*>(TagT)->decl = TD; } - + if (auto RD = dyn_cast<CXXRecordDecl>(D)) { - for (auto R : RD->redecls()) { - assert((R == D) == R->isThisDeclarationADefinition() && + for (auto *R = getMostRecentExistingDecl(RD); R; + R = R->getPreviousDecl()) { + assert((R == D) == + cast<CXXRecordDecl>(R)->isThisDeclarationADefinition() && "declaration thinks it's the definition but it isn't"); cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData; } @@ -8320,34 +8149,36 @@ void ASTReader::finishPendingActions() { continue; } - + if (auto ID = dyn_cast<ObjCInterfaceDecl>(D)) { // Make sure that the ObjCInterfaceType points at the definition. const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl)) ->Decl = ID; - - for (auto R : ID->redecls()) - R->Data = ID->Data; - + + for (auto *R = getMostRecentExistingDecl(ID); R; R = R->getPreviousDecl()) + cast<ObjCInterfaceDecl>(R)->Data = ID->Data; + continue; } - + if (auto PD = dyn_cast<ObjCProtocolDecl>(D)) { - for (auto R : PD->redecls()) - R->Data = PD->Data; - + for (auto *R = getMostRecentExistingDecl(PD); R; R = R->getPreviousDecl()) + cast<ObjCProtocolDecl>(R)->Data = PD->Data; + continue; } - + auto RTD = cast<RedeclarableTemplateDecl>(D)->getCanonicalDecl(); - for (auto R : RTD->redecls()) - R->Common = RTD->Common; + for (auto *R = getMostRecentExistingDecl(RTD); R; R = R->getPreviousDecl()) + cast<RedeclarableTemplateDecl>(R)->Common = RTD->Common; } PendingDefinitions.clear(); // Load the bodies of any functions or methods we've encountered. We do // this now (delayed) so that we can be sure that the declaration chains // have been fully wired up. + // FIXME: There seems to be no point in delaying this, it does not depend + // on the redecl chains having been wired up. for (PendingBodiesMap::iterator PB = PendingBodies.begin(), PBEnd = PendingBodies.end(); PB != PBEnd; ++PB) { @@ -8364,6 +8195,11 @@ void ASTReader::finishPendingActions() { MD->setLazyBody(PB->second); } PendingBodies.clear(); + + // Do some cleanup. + for (auto *ND : PendingMergedDefinitionsToDeduplicate) + getContext().deduplicateMergedDefinitonsFor(ND); + PendingMergedDefinitionsToDeduplicate.clear(); } void ASTReader::diagnoseOdrViolations() { @@ -8440,6 +8276,10 @@ void ASTReader::diagnoseOdrViolations() { // completed. We only really need to mark FieldDecls as invalid here. if (!isa<TagDecl>(D)) D->setInvalidDecl(); + + // Ensure we don't accidentally recursively enter deserialization while + // we're producing our diagnostic. + Deserializing RecursionGuard(this); std::string CanonDefModule = getOwningModuleNameForDiagnostic(cast<Decl>(CanonDef)); @@ -8461,6 +8301,13 @@ void ASTReader::diagnoseOdrViolations() { } } + if (OdrMergeFailures.empty()) + return; + + // Ensure we don't accidentally recursively enter deserialization while + // we're producing our diagnostics. + Deserializing RecursionGuard(this); + // Issue any pending ODR-failure diagnostics. for (auto &Merge : OdrMergeFailures) { // If we've already pointed out a specific problem with this class, don't @@ -8514,6 +8361,17 @@ void ASTReader::FinishedDeserializing() { --NumCurrentElementsDeserializing; if (NumCurrentElementsDeserializing == 0) { + // Propagate exception specification updates along redeclaration chains. + while (!PendingExceptionSpecUpdates.empty()) { + auto Updates = std::move(PendingExceptionSpecUpdates); + PendingExceptionSpecUpdates.clear(); + for (auto Update : Updates) { + auto *FPT = Update.second->getType()->castAs<FunctionProtoType>(); + SemaObj->UpdateExceptionSpec(Update.second, + FPT->getExtProtoInfo().ExceptionSpec); + } + } + diagnoseOdrViolations(); // We are not in recursive loading, so it's safe to pass the "interesting" @@ -8524,7 +8382,18 @@ void ASTReader::FinishedDeserializing() { } void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { - D = D->getMostRecentDecl(); + if (IdentifierInfo *II = Name.getAsIdentifierInfo()) { + // Remove any fake results before adding any real ones. + auto It = PendingFakeLookupResults.find(II); + if (It != PendingFakeLookupResults.end()) { + for (auto *ND : PendingFakeLookupResults[II]) + SemaObj->IdResolver.RemoveDecl(ND); + // FIXME: this works around module+PCH performance issue. + // Rather than erase the result from the map, which is O(n), just clear + // the vector of NamedDecls. + It->second.clear(); + } + } if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) { SemaObj->TUScope->AddDecl(D); @@ -8562,8 +8431,7 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot, NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0), TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0), - PassingDeclsToConsumer(false), NumCXXBaseSpecifiersLoaded(0), - ReadingKind(Read_None) { + PassingDeclsToConsumer(false), ReadingKind(Read_None) { SourceMgr.setExternalSLocEntrySource(this); } |