diff options
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 1067 |
1 files changed, 641 insertions, 426 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 9d1554a826aa..fe2c53b77e1d 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1,4 +1,4 @@ -//===-- ASTReader.cpp - AST File Reader ----------------------------------===// +//===-- ASTReader.cpp - AST File Reader -----------------------------------===// // // The LLVM Compiler Infrastructure // @@ -16,39 +16,62 @@ #include "ASTReaderInternals.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTMutationListener.h" +#include "clang/AST/ASTUnresolvedSet.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclGroup.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" -#include "clang/Frontend/PCHContainerOperations.h" -#include "clang/AST/ASTMutationListener.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/RawCommentList.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLocVisitor.h" +#include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/CommentOptions.h" #include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/Sanitizers.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManagerInternals.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Basic/TokenKinds.h" #include "clang/Basic/Version.h" #include "clang/Basic/VersionTuple.h" -#include "clang/Frontend/Utils.h" +#include "clang/Frontend/PCHContainerOperations.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/MacroInfo.h" +#include "clang/Lex/ModuleMap.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Sema/Scope.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/Weak.h" #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Serialization/GlobalModuleIndex.h" #include "clang/Serialization/ModuleManager.h" #include "clang/Serialization/SerializationDiagnostic.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Triple.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/Compression.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" @@ -56,16 +79,27 @@ #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> +#include <cassert> +#include <cstdint> #include <cstdio> +#include <cstring> +#include <ctime> #include <iterator> +#include <limits> +#include <map> +#include <memory> +#include <new> +#include <string> #include <system_error> +#include <tuple> +#include <utility> +#include <vector> using namespace clang; using namespace clang::serialization; using namespace clang::serialization::reader; using llvm::BitstreamCursor; - //===----------------------------------------------------------------------===// // ChainedASTReaderListener implementation //===----------------------------------------------------------------------===// @@ -75,14 +109,17 @@ ChainedASTReaderListener::ReadFullVersionInformation(StringRef FullVersion) { return First->ReadFullVersionInformation(FullVersion) || Second->ReadFullVersionInformation(FullVersion); } + void ChainedASTReaderListener::ReadModuleName(StringRef ModuleName) { First->ReadModuleName(ModuleName); Second->ReadModuleName(ModuleName); } + void ChainedASTReaderListener::ReadModuleMapFile(StringRef ModuleMapPath) { First->ReadModuleMapFile(ModuleMapPath); Second->ReadModuleMapFile(ModuleMapPath); } + bool ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, @@ -92,6 +129,7 @@ ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts, Second->ReadLanguageOptions(LangOpts, Complain, AllowCompatibleDifferences); } + bool ChainedASTReaderListener::ReadTargetOptions( const TargetOptions &TargetOpts, bool Complain, bool AllowCompatibleDifferences) { @@ -100,11 +138,13 @@ bool ChainedASTReaderListener::ReadTargetOptions( Second->ReadTargetOptions(TargetOpts, Complain, AllowCompatibleDifferences); } + bool ChainedASTReaderListener::ReadDiagnosticOptions( IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) { return First->ReadDiagnosticOptions(DiagOpts, Complain) || Second->ReadDiagnosticOptions(DiagOpts, Complain); } + bool ChainedASTReaderListener::ReadFileSystemOptions(const FileSystemOptions &FSOpts, bool Complain) { @@ -120,6 +160,7 @@ bool ChainedASTReaderListener::ReadHeaderSearchOptions( Second->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath, Complain); } + bool ChainedASTReaderListener::ReadPreprocessorOptions( const PreprocessorOptions &PPOpts, bool Complain, std::string &SuggestedPredefines) { @@ -145,6 +186,7 @@ void ChainedASTReaderListener::visitModuleFile(StringRef Filename, First->visitModuleFile(Filename, Kind); Second->visitModuleFile(Filename, Kind); } + bool ChainedASTReaderListener::visitInputFile(StringRef Filename, bool isSystem, bool isOverridden, @@ -336,11 +378,13 @@ bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts, } namespace { + typedef llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> > MacroDefinitionsMap; typedef llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > DeclsMap; -} + +} // end anonymous namespace static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags, DiagnosticsEngine &Diags, @@ -496,12 +540,16 @@ collectMacroDefinitions(const PreprocessorOptions &PPOpts, /// against the preprocessor options in an existing preprocessor. /// /// \param Diags If non-null, produce diagnostics for any mismatches incurred. +/// \param Validate If true, validate preprocessor options. If false, allow +/// macros defined by \p ExistingPPOpts to override those defined by +/// \p PPOpts in SuggestedPredefines. static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts, const PreprocessorOptions &ExistingPPOpts, DiagnosticsEngine *Diags, FileManager &FileMgr, std::string &SuggestedPredefines, - const LangOptions &LangOpts) { + const LangOptions &LangOpts, + bool Validate = true) { // Check macro definitions. MacroDefinitionsMap ASTFileMacros; collectMacroDefinitions(PPOpts, ASTFileMacros); @@ -517,7 +565,7 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts, // Check whether we know anything about this macro name or not. llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >::iterator Known = ASTFileMacros.find(MacroName); - if (Known == ASTFileMacros.end()) { + if (!Validate || Known == ASTFileMacros.end()) { // FIXME: Check whether this identifier was referenced anywhere in the // AST file. If so, we should reject the AST file. Unfortunately, this // information isn't in the control block. What shall we do about it? @@ -560,7 +608,7 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts, } // Check whether we're using predefines. - if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines) { + if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines && Validate) { if (Diags) { Diags->Report(diag::err_pch_undef) << ExistingPPOpts.UsePredefines; } @@ -569,7 +617,7 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts, // Detailed record is important since it is used for the module cache hash. if (LangOpts.Modules && - PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord) { + PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord && Validate) { if (Diags) { Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord; } @@ -618,6 +666,19 @@ bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, PP.getLangOpts()); } +bool SimpleASTReaderListener::ReadPreprocessorOptions( + const PreprocessorOptions &PPOpts, + bool Complain, + std::string &SuggestedPredefines) { + return checkPreprocessorOptions(PPOpts, + PP.getPreprocessorOpts(), + nullptr, + PP.getFileManager(), + SuggestedPredefines, + PP.getLangOpts(), + false); +} + /// Check the header search options deserialized from the control block /// against the header search options in an existing preprocessor. /// @@ -662,13 +723,10 @@ void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener, OwnsDeserializationListener = TakeOwnership; } - - unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) { return serialization::ComputeHash(Sel); } - std::pair<unsigned, unsigned> ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) { using namespace llvm::support; @@ -677,7 +735,7 @@ ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) { return std::make_pair(KeyLen, DataLen); } -ASTSelectorLookupTrait::internal_key_type +ASTSelectorLookupTrait::internal_key_type ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) { using namespace llvm::support; SelectorTable &SelTable = Reader.getContext().Selectors; @@ -698,8 +756,8 @@ ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) { return SelTable.getSelector(N, Args.data()); } -ASTSelectorLookupTrait::data_type -ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, +ASTSelectorLookupTrait::data_type +ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, unsigned DataLen) { using namespace llvm::support; @@ -1138,7 +1196,7 @@ bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) { RecordData Record; while (true) { llvm::BitstreamEntry E = SLocEntryCursor.advanceSkippingSubblocks(); - + switch (E.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. case llvm::BitstreamEntry::Error: @@ -1150,7 +1208,7 @@ bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) { // The interesting case. break; } - + // Read a record. Record.clear(); StringRef Blob; @@ -1246,7 +1304,7 @@ bool ASTReader::ReadSLocEntry(int ID) { Error("incorrectly-formatted source location entry in AST file"); return true; } - + RecordData Record; StringRef Blob; switch (SLocEntryCursor.readRecord(Entry.ID, Record, &Blob)) { @@ -1312,8 +1370,7 @@ bool ASTReader::ReadSLocEntry(int ID) { SrcMgr::CharacteristicKind FileCharacter = (SrcMgr::CharacteristicKind)Record[2]; SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]); - if (IncludeLoc.isInvalid() && - (F->Kind == MK_ImplicitModule || F->Kind == MK_ExplicitModule)) { + if (IncludeLoc.isInvalid() && F->isModule()) { IncludeLoc = getImportLocation(F); } @@ -1351,7 +1408,7 @@ std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) { // Find which module file this entry lands in. ModuleFile *M = GlobalSLocEntryMap.find(-ID)->second; - if (M->Kind != MK_ImplicitModule && M->Kind != MK_ExplicitModule) + if (!M->isModule()) return std::make_pair(SourceLocation(), ""); // FIXME: Can we map this down to a particular submodule? That would be @@ -1363,7 +1420,7 @@ std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) { SourceLocation ASTReader::getImportLocation(ModuleFile *F) { if (F->ImportLoc.isValid()) return F->ImportLoc; - + // Otherwise we have a PCH. It's considered to be "imported" at the first // location of its includer. if (F->ImportedBy.empty() || !F->ImportedBy[0]) { @@ -1425,7 +1482,7 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { // be able to reseek within the block and read entries. unsigned Flags = BitstreamCursor::AF_DontPopBlockAtEnd; llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(Flags); - + switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. case llvm::BitstreamEntry::Error: @@ -1517,13 +1574,13 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { } } -PreprocessedEntityID +PreprocessedEntityID ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const { - ContinuousRangeMap<uint32_t, int, 2>::const_iterator + ContinuousRangeMap<uint32_t, int, 2>::const_iterator I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS); - assert(I != M.PreprocessedEntityRemap.end() + assert(I != M.PreprocessedEntityRemap.end() && "Invalid index into preprocessed entity index remap"); - + return LocalID + I->second; } @@ -1531,22 +1588,21 @@ unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) { return llvm::hash_combine(ikey.Size, ikey.ModTime); } -HeaderFileInfoTrait::internal_key_type +HeaderFileInfoTrait::internal_key_type HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) { internal_key_type ikey = {FE->getSize(), M.HasTimestamps ? FE->getModificationTime() : 0, FE->getName(), /*Imported*/ false}; return ikey; } - + bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { if (a.Size != b.Size || (a.ModTime && b.ModTime && a.ModTime != b.ModTime)) return false; - if (llvm::sys::path::is_absolute(a.Filename) && - strcmp(a.Filename, b.Filename) == 0) + if (llvm::sys::path::is_absolute(a.Filename) && a.Filename == b.Filename) return true; - + // Determine whether the actual files are equivalent. FileManager &FileMgr = Reader.getFileManager(); auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* { @@ -1562,7 +1618,7 @@ bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { const FileEntry *FEB = GetFile(b); return FEA && FEA == FEB; } - + std::pair<unsigned, unsigned> HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) { using namespace llvm::support; @@ -1582,7 +1638,7 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) { return ikey; } -HeaderFileInfoTrait::data_type +HeaderFileInfoTrait::data_type HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, unsigned DataLen) { const unsigned char *End = d + DataLen; @@ -1602,7 +1658,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, M, endian::readNext<uint32_t, little, unaligned>(d)); if (unsigned FrameworkOffset = endian::readNext<uint32_t, little, unaligned>(d)) { - // The framework offset is 1 greater than the actual offset, + // The framework offset is 1 greater than the actual offset, // since 0 is used as an indicator for "no framework name". StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1); HFI.Framework = HS->getUniqueFrameworkName(FrameworkName); @@ -1655,7 +1711,7 @@ void ASTReader::ReadDefinedMacros() { BitstreamCursor &MacroCursor = I->MacroCursor; // If there was no preprocessor block, skip this file. - if (!MacroCursor.getBitStreamReader()) + if (MacroCursor.getBitcodeBytes().empty()) continue; BitstreamCursor Cursor = MacroCursor; @@ -1664,7 +1720,7 @@ void ASTReader::ReadDefinedMacros() { RecordData Record; while (true) { llvm::BitstreamEntry E = Cursor.advanceSkippingSubblocks(); - + switch (E.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. case llvm::BitstreamEntry::Error: @@ -1672,13 +1728,13 @@ void ASTReader::ReadDefinedMacros() { return; case llvm::BitstreamEntry::EndBlock: goto NextCursor; - + case llvm::BitstreamEntry::Record: Record.clear(); switch (Cursor.readRecord(E.ID, Record)) { default: // Default behavior: ignore. break; - + case PP_MACRO_OBJECT_LIKE: case PP_MACRO_FUNCTION_LIKE: { IdentifierInfo *II = getLocalIdentifier(*I, Record[0]); @@ -1686,7 +1742,7 @@ void ASTReader::ReadDefinedMacros() { updateOutOfDateIdentifier(*II); break; } - + case PP_TOKEN: // Ignore tokens. break; @@ -1699,6 +1755,7 @@ void ASTReader::ReadDefinedMacros() { } namespace { + /// \brief Visitor class used to look up identifirs in an AST file. class IdentifierLookupVisitor { StringRef Name; @@ -1737,7 +1794,7 @@ namespace { IdTable->find_hashed(Name, NameHash, &Trait); if (Pos == IdTable->end()) return false; - + // Dereferencing the iterator has the effect of building the // IdentifierInfo node and populating it with the various // declarations it needs. @@ -1745,12 +1802,13 @@ namespace { Found = *Pos; return true; } - + // \brief Retrieve the identifier info found within the module // files. IdentifierInfo *getIdentifierInfo() const { return Found; } }; -} + +} // end anonymous namespace void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) { // Note that we are loading an identifier. @@ -1780,7 +1838,7 @@ void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) { void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) { if (!II) return; - + II->setOutOfDate(false); // Update the generation for this identifier. @@ -1861,7 +1919,7 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, // 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) + if (M.isModule()) return; // Deserialize the macro directives history in reverse source-order. @@ -1895,7 +1953,7 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, } if (Latest) - PP.setLoadedMacroDirective(II, Latest); + PP.setLoadedMacroDirective(II, Earliest, Latest); } ASTReader::InputFileInfo @@ -1925,6 +1983,7 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) { return R; } +static unsigned moduleKindForDiagnostic(ModuleKind Kind); InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { // If this ID is bogus, just return an empty input file. if (ID == 0 || ID > F.InputFilesLoaded.size()) @@ -1941,7 +2000,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { BitstreamCursor &Cursor = F.InputFilesCursor; SavedStreamPosition SavedPosition(Cursor); Cursor.JumpToBit(F.InputFileOffsets[ID-1]); - + InputFileInfo FI = readInputFileInfo(F, ID); off_t StoredSize = FI.StoredSize; time_t StoredTime = FI.StoredTime; @@ -1974,7 +2033,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { ErrorStr += "' referenced by AST file '"; ErrorStr += F.FileName; ErrorStr += "'"; - Error(ErrorStr.c_str()); + Error(ErrorStr); } // Record that we didn't find the file. F.InputFilesLoaded[ID-1] = InputFile::getNotFound(); @@ -2021,7 +2080,13 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { // The top-level PCH is stale. StringRef TopLevelPCHName(ImportStack.back()->FileName); - Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName); + unsigned DiagnosticKind = moduleKindForDiagnostic(ImportStack.back()->Kind); + if (DiagnosticKind == 0) + Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName); + else if (DiagnosticKind == 1) + Error(diag::err_fe_module_file_modified, Filename, TopLevelPCHName); + else + Error(diag::err_fe_ast_file_modified, Filename, TopLevelPCHName); // Print the import stack. if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) { @@ -2084,16 +2149,16 @@ static bool isDiagnosedResult(ASTReader::ASTReadResult ARR, unsigned Caps) { ASTReader::ASTReadResult ASTReader::ReadOptionsBlock( BitstreamCursor &Stream, unsigned ClientLoadCapabilities, bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener, - std::string &SuggestedPredefines) { + std::string &SuggestedPredefines, bool ValidateDiagnosticOptions) { if (Stream.EnterSubBlock(OPTIONS_BLOCK_ID)) return Failure; // Read all of the records in the options block. RecordData Record; ASTReadResult Result = Success; - while (1) { + while (true) { llvm::BitstreamEntry Entry = Stream.advance(); - + switch (Entry.Kind) { case llvm::BitstreamEntry::Error: case llvm::BitstreamEntry::SubBlock: @@ -2128,7 +2193,8 @@ ASTReader::ASTReadResult ASTReader::ReadOptionsBlock( case DIAGNOSTIC_OPTIONS: { bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; - if (!AllowCompatibleConfigurationMismatch && + if (ValidateDiagnosticOptions && + !AllowCompatibleConfigurationMismatch && ParseDiagnosticOptions(Record, Complain, Listener)) return OutOfDate; break; @@ -2178,9 +2244,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, RecordData Record; unsigned NumInputs = 0; unsigned NumUserInputs = 0; - while (1) { + while (true) { llvm::BitstreamEntry Entry = Stream.advance(); - + switch (Entry.Kind) { case llvm::BitstreamEntry::Error: Error("malformed block record in AST file"); @@ -2193,7 +2259,8 @@ ASTReader::ReadControlBlock(ModuleFile &F, // All user input files reside at the index range [0, NumUserInputs), and // system input files reside at [NumUserInputs, NumInputs). For explicitly // loaded module files, ignore missing inputs. - if (!DisableValidation && F.Kind != MK_ExplicitModule) { + if (!DisableValidation && F.Kind != MK_ExplicitModule && + F.Kind != MK_PrebuiltModule) { bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; // If we are reading a module, we will create a verification timestamp, @@ -2224,7 +2291,8 @@ ASTReader::ReadControlBlock(ModuleFile &F, bool IsSystem = I >= NumUserInputs; InputFileInfo FI = readInputFileInfo(F, I+1); Listener->visitInputFile(FI.Filename, IsSystem, FI.Overridden, - F.Kind == MK_ExplicitModule); + F.Kind == MK_ExplicitModule || + F.Kind == MK_PrebuiltModule); } } @@ -2254,11 +2322,14 @@ ASTReader::ReadControlBlock(ModuleFile &F, // // FIXME: Allow this for files explicitly specified with -include-pch. bool AllowCompatibleConfigurationMismatch = - F.Kind == MK_ExplicitModule; + F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule; + const HeaderSearchOptions &HSOpts = + PP.getHeaderSearchInfo().getHeaderSearchOpts(); Result = ReadOptionsBlock(Stream, ClientLoadCapabilities, AllowCompatibleConfigurationMismatch, - *Listener, SuggestedPredefines); + *Listener, SuggestedPredefines, + HSOpts.ModulesValidateDiagnosticOptions); if (Result == Failure) { Error("malformed block record in AST file"); return Result; @@ -2278,7 +2349,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, return Failure; } continue; - + default: if (Stream.SkipBlock()) { Error("malformed block record in AST file"); @@ -2286,7 +2357,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, } continue; } - + case llvm::BitstreamEntry::Record: // The interesting case. break; @@ -2338,7 +2409,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, break; case IMPORTS: { - // Load each of the imported PCH files. + // Load each of the imported PCH files. unsigned Idx = 0, N = Record.size(); while (Idx < N) { // Read information about the AST file. @@ -2413,7 +2484,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, if (M && M->Directory) { // If we're implicitly loading a module, the base directory can't // change between the build and use. - if (F.Kind != MK_ExplicitModule) { + if (F.Kind != MK_ExplicitModule && F.Kind != MK_PrebuiltModule) { const DirectoryEntry *BuildDir = PP.getFileManager().getDirectory(Blob); if (!BuildDir || BuildDir != M->Directory) { @@ -2458,9 +2529,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // Read all of the records and blocks for the AST file. RecordData Record; - while (1) { + while (true) { llvm::BitstreamEntry Entry = Stream.advance(); - + switch (Entry.Kind) { case llvm::BitstreamEntry::Error: Error("error at end of module block in AST file"); @@ -2475,7 +2546,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { if (DC->hasExternalLexicalStorage() && !getContext().getLangOpts().CPlusPlus) DC->setMustBuildLookupTable(); - + return Success; } case llvm::BitstreamEntry::SubBlock: @@ -2498,7 +2569,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.MacroCursor = Stream; if (!PP.getExternalSource()) PP.setExternalSource(this); - + if (Stream.SkipBlock() || ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) { Error("malformed block record in AST file"); @@ -2506,7 +2577,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo(); break; - + case PREPROCESSOR_DETAIL_BLOCK_ID: F.PreprocessorDetailCursor = Stream; if (Stream.SkipBlock() || @@ -2517,23 +2588,23 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } F.PreprocessorDetailStartOffset = F.PreprocessorDetailCursor.GetCurrentBitNo(); - + if (!PP.getPreprocessingRecord()) PP.createPreprocessingRecord(); if (!PP.getPreprocessingRecord()->getExternalSource()) PP.getPreprocessingRecord()->SetExternalSource(*this); break; - + case SOURCE_MANAGER_BLOCK_ID: if (ReadSourceManagerBlock(F)) return Failure; break; - + case SUBMODULE_BLOCK_ID: if (ASTReadResult Result = ReadSubmoduleBlock(F, ClientLoadCapabilities)) return Result; break; - + case COMMENTS_BLOCK_ID: { BitstreamCursor C = Stream; if (Stream.SkipBlock() || @@ -2544,7 +2615,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { CommentsCursors.push_back(std::make_pair(C, &F)); break; } - + default: if (Stream.SkipBlock()) { Error("malformed block record in AST file"); @@ -2553,7 +2624,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } continue; - + case llvm::BitstreamEntry::Record: // The interesting case. break; @@ -2575,21 +2646,21 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.LocalNumTypes = Record[0]; unsigned LocalBaseTypeIndex = Record[1]; F.BaseTypeIndex = getTotalNumTypes(); - + if (F.LocalNumTypes > 0) { // Introduce the global -> local mapping for types within this module. GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F)); - + // Introduce the local -> global mapping for types within this module. F.TypeRemap.insertOrReplace( - std::make_pair(LocalBaseTypeIndex, + std::make_pair(LocalBaseTypeIndex, F.BaseTypeIndex - LocalBaseTypeIndex)); TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes); } break; } - + case DECL_OFFSET: { if (F.LocalNumDecls != 0) { Error("duplicate DECL_OFFSET record in AST file"); @@ -2599,18 +2670,18 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.LocalNumDecls = Record[0]; unsigned LocalBaseDeclID = Record[1]; F.BaseDeclID = getTotalNumDecls(); - + if (F.LocalNumDecls > 0) { - // Introduce the global -> local mapping for declarations within this + // Introduce the global -> local mapping for declarations within this // module. GlobalDeclMap.insert( std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F)); - + // Introduce the local -> global mapping for declarations within this // module. F.DeclRemap.insertOrReplace( std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID)); - + // Introduce the global -> local mapping for declarations within this // module. F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID; @@ -2619,7 +2690,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; } - + case TU_UPDATE_LEXICAL: { DeclContext *TU = Context.getTranslationUnitDecl(); LexicalContents Contents( @@ -2651,7 +2722,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { (const unsigned char *)F.IdentifierTableData + sizeof(uint32_t), (const unsigned char *)F.IdentifierTableData, ASTIdentifierLookupTrait(*this, F)); - + PP.getIdentifierTable().setExternalIdentifierLookup(this); } break; @@ -2665,13 +2736,13 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.LocalNumIdentifiers = Record[0]; unsigned LocalBaseIdentifierID = Record[1]; F.BaseIdentifierID = getTotalNumIdentifiers(); - + if (F.LocalNumIdentifiers > 0) { // Introduce the global -> local mapping for identifiers within this // module. - GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1, + GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1, &F)); - + // Introduce the local -> global mapping for identifiers within this // module. F.IdentifierRemap.insertOrReplace( @@ -2738,11 +2809,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Error("invalid weak identifiers record"); return Failure; } - - // FIXME: Ignore weak undeclared identifiers from non-original PCH + + // FIXME: Ignore weak undeclared identifiers from non-original PCH // files. This isn't the way to do it :) WeakUndeclaredIdentifiers.clear(); - + // Translate the weak, undeclared identifiers into global IDs. for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) { WeakUndeclaredIdentifiers.push_back( @@ -2760,13 +2831,13 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.LocalNumSelectors = Record[0]; unsigned LocalBaseSelectorID = Record[1]; F.BaseSelectorID = getTotalNumSelectors(); - + if (F.LocalNumSelectors > 0) { - // Introduce the global -> local mapping for selectors within this + // Introduce the global -> local mapping for selectors within this // module. GlobalSelectorMap.insert(std::make_pair(getTotalNumSelectors()+1, &F)); - - // Introduce the local -> global mapping for selectors within this + + // Introduce the local -> global mapping for selectors within this // module. F.SelectorRemap.insertOrReplace( std::make_pair(LocalBaseSelectorID, @@ -2776,7 +2847,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; } - + case METHOD_POOL: F.SelectorLookupTableData = (const unsigned char *)Blob.data(); if (Record[0]) @@ -2791,7 +2862,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case REFERENCED_SELECTOR_POOL: if (!Record.empty()) { for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) { - ReferencedSelectorsData.push_back(getGlobalSelectorID(F, + ReferencedSelectorsData.push_back(getGlobalSelectorID(F, Record[Idx++])); ReferencedSelectorsData.push_back(ReadSourceLocation(F, Record, Idx). getRawEncoding()); @@ -2803,7 +2874,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { if (!Record.empty() && Listener) Listener->ReadCounter(F, Record[0]); break; - + case FILE_SORTED_DECLS: F.FileSortedDecls = (const DeclID *)Blob.data(); F.NumFileSortedDecls = Record[0]; @@ -2840,7 +2911,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // This module. Base was 2 when being compiled. F.SLocRemap.insertOrReplace(std::make_pair(2U, static_cast<int>(F.SLocEntryBaseOffset - 2))); - + TotalNumSLocEntries += F.LocalNumSLocEntries; break; } @@ -2932,7 +3003,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file"); return Failure; } - + F.PreloadSLocEntries.swap(Record); break; } @@ -2947,12 +3018,12 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Error("Invalid VTABLE_USES record"); return Failure; } - + // Later tables overwrite earlier ones. // FIXME: Modules will have some trouble with this. This is clearly not // the right way to do this. VTableUses.clear(); - + for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) { VTableUses.push_back(getGlobalDeclID(F, Record[Idx++])); VTableUses.push_back( @@ -2980,7 +3051,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; case SEMA_DECL_REFS: - if (Record.size() != 2) { + if (Record.size() != 3) { Error("Invalid SEMA_DECL_REFS block"); return Failure; } @@ -2994,13 +3065,13 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.NumPreprocessedEntities = Blob.size() / sizeof(PPEntityOffset); unsigned LocalBasePreprocessedEntityID = Record[0]; - + unsigned StartingID; if (!PP.getPreprocessingRecord()) PP.createPreprocessingRecord(); if (!PP.getPreprocessingRecord()->getExternalSource()) PP.getPreprocessingRecord()->SetExternalSource(*this); - StartingID + StartingID = PP.getPreprocessingRecord() ->allocateLoadedEntities(F.NumPreprocessedEntities); F.BasePreprocessedEntityID = StartingID; @@ -3009,7 +3080,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // Introduce the global -> local mapping for preprocessed entities in // this module. GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F)); - + // Introduce the local -> global mapping for preprocessed entities in // this module. F.PreprocessedEntityRemap.insertOrReplace( @@ -3019,7 +3090,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - + case DECL_UPDATE_OFFSETS: { if (Record.size() % 2 != 0) { Error("invalid DECL_UPDATE_OFFSETS block in AST file"); @@ -3042,12 +3113,12 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Error("duplicate OBJC_CATEGORIES_MAP record in AST file"); return Failure; } - + F.LocalNumObjCCategoriesInMap = Record[0]; F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)Blob.data(); break; } - + case OBJC_CATEGORIES: F.ObjCCategories.swap(Record); break; @@ -3059,7 +3130,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.PragmaDiagMappings.insert(F.PragmaDiagMappings.end(), Record.begin(), Record.end()); break; - + case CUDA_SPECIAL_DECL_REFS: // Later tables overwrite earlier ones. // FIXME: Modules will have trouble with this. @@ -3076,32 +3147,62 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { = HeaderFileInfoLookupTable::Create( (const unsigned char *)F.HeaderFileInfoTableData + Record[0], (const unsigned char *)F.HeaderFileInfoTableData, - HeaderFileInfoTrait(*this, F, + HeaderFileInfoTrait(*this, F, &PP.getHeaderSearchInfo(), Blob.data() + Record[2])); - + PP.getHeaderSearchInfo().SetExternalSource(this); if (!PP.getHeaderSearchInfo().getExternalLookup()) PP.getHeaderSearchInfo().SetExternalLookup(this); } break; } - + case FP_PRAGMA_OPTIONS: // Later tables overwrite earlier ones. FPPragmaOptions.swap(Record); break; case OPENCL_EXTENSIONS: - // Later tables overwrite earlier ones. - OpenCLExtensions.swap(Record); + for (unsigned I = 0, E = Record.size(); I != E; ) { + auto Name = ReadString(Record, I); + auto &Opt = OpenCLExtensions.OptMap[Name]; + Opt.Supported = Record[I++] != 0; + Opt.Enabled = Record[I++] != 0; + Opt.Avail = Record[I++]; + Opt.Core = Record[I++]; + } + break; + + case OPENCL_EXTENSION_TYPES: + for (unsigned I = 0, E = Record.size(); I != E;) { + auto TypeID = static_cast<::TypeID>(Record[I++]); + auto *Type = GetType(TypeID).getTypePtr(); + auto NumExt = static_cast<unsigned>(Record[I++]); + for (unsigned II = 0; II != NumExt; ++II) { + auto Ext = ReadString(Record, I); + OpenCLTypeExtMap[Type].insert(Ext); + } + } + break; + + case OPENCL_EXTENSION_DECLS: + for (unsigned I = 0, E = Record.size(); I != E;) { + auto DeclID = static_cast<::DeclID>(Record[I++]); + auto *Decl = GetDecl(DeclID); + auto NumExt = static_cast<unsigned>(Record[I++]); + for (unsigned II = 0; II != NumExt; ++II) { + auto Ext = ReadString(Record, I); + OpenCLDeclExtMap[Decl].insert(Ext); + } + } break; case TENTATIVE_DEFINITIONS: for (unsigned I = 0, N = Record.size(); I != N; ++I) TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I])); break; - + case KNOWN_NAMESPACES: for (unsigned I = 0, N = Record.size(); I != N; ++I) KnownNamespaces.push_back(getGlobalDeclID(F, Record[I])); @@ -3137,7 +3238,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; case IMPORTED_MODULES: { - if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule) { + if (!F.isModule()) { // If we aren't loading a module (which has its own exports), make // all of the imported modules visible. // FIXME: Deal with macros-only imports. @@ -3210,6 +3311,14 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { UnusedLocalTypedefNameCandidates.push_back( getGlobalDeclID(F, Record[I])); break; + + case CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH: + if (Record.size() != 1) { + Error("invalid cuda pragma options record"); + return Failure; + } + ForceCUDAHostDeviceDepth = Record[0]; + break; } } } @@ -3221,7 +3330,7 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, unsigned Idx = 0; F.ModuleMapPath = ReadPath(F, Record, Idx); - if (F.Kind == MK_ExplicitModule) { + if (F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule) { // For an explicitly-loaded module, we don't care whether the original // module map file exists or matches. return Success; @@ -3404,6 +3513,31 @@ void ASTReader::makeModuleVisible(Module *Mod, } } +/// We've merged the definition \p MergedDef into the existing definition +/// \p Def. Ensure that \p Def is made visible whenever \p MergedDef is made +/// visible. +void ASTReader::mergeDefinitionVisibility(NamedDecl *Def, + NamedDecl *MergedDef) { + // FIXME: This doesn't correctly handle the case where MergedDef is visible + // in modules other than its owning module. We should instead give the + // ASTContext a list of merged definitions for Def. + if (Def->isHidden()) { + // If MergedDef is visible or becomes visible, make the definition visible. + if (!MergedDef->isHidden()) + Def->Hidden = false; + else if (getContext().getLangOpts().ModulesLocalVisibility) { + getContext().mergeDefinitionIntoModule( + Def, MergedDef->getImportedOwningModule(), + /*NotifyListeners*/ false); + PendingMergedDefinitionsToDeduplicate.insert(Def); + } else { + auto SubmoduleID = MergedDef->getOwningModuleID(); + assert(SubmoduleID && "hidden definition in no module"); + HiddenNamesMap[getSubmodule(SubmoduleID)].push_back(Def); + } + } +} + bool ASTReader::loadGlobalIndex() { if (GlobalIndex) return false; @@ -3411,7 +3545,7 @@ bool ASTReader::loadGlobalIndex() { if (TriedLoadingGlobalIndex || !UseGlobalIndex || !Context.getLangOpts().Modules) return true; - + // Try to load the global index. TriedLoadingGlobalIndex = true; StringRef ModuleCachePath @@ -3445,7 +3579,7 @@ static void updateModuleTimestamp(ModuleFile &MF) { /// cursor into the start of the given block ID, returning false on success and /// true on failure. static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) { - while (1) { + while (true) { llvm::BitstreamEntry Entry = Cursor.advance(); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: @@ -3474,7 +3608,8 @@ static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) { ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type, SourceLocation ImportLoc, - unsigned ClientLoadCapabilities) { + unsigned ClientLoadCapabilities, + SmallVectorImpl<ImportedSubmodule> *Imported) { llvm::SaveAndRestore<SourceLocation> SetCurImportLocRAII(CurrentImportLoc, ImportLoc); @@ -3534,12 +3669,12 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, return Result; } - // Once read, set the ModuleFile bit base offset and update the size in + // Once read, set the ModuleFile bit base offset and update the size in // bits of all files we've seen. F.GlobalBitOffset = TotalModulesSizeInBits; TotalModulesSizeInBits += F.SizeInBits; GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F)); - + // Preload SLocEntries. for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I) { int Index = int(F.PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID; @@ -3592,7 +3727,8 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, } if (!Context.getLangOpts().CPlusPlus || - (Type != MK_ImplicitModule && Type != MK_ExplicitModule)) { + (Type != MK_ImplicitModule && Type != MK_ExplicitModule && + Type != MK_PrebuiltModule)) { // Mark all of the identifiers in the identifier table as being out of date, // so that various accessors know to check the loaded modules when the // identifier is used. @@ -3608,7 +3744,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, // Mark selectors as out of date. for (auto Sel : SelectorGeneration) SelectorOutOfDate[Sel.first] = true; - + // Resolve any unresolved module exports. for (unsigned I = 0, N = UnresolvedModuleRefs.size(); I != N; ++I) { UnresolvedModuleRef &Unresolved = UnresolvedModuleRefs[I]; @@ -3639,10 +3775,14 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, } UnresolvedModuleRefs.clear(); + if (Imported) + Imported->append(ImportedModules.begin(), + ImportedModules.end()); + // FIXME: How do we load the 'use'd modules? They may not be submodules. // Might be unnecessary as use declarations are only used to build the // module itself. - + InitializeContext(); if (SemaObj) @@ -3653,7 +3793,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleFile &PrimaryModule = ModuleMgr.getPrimaryModule(); if (PrimaryModule.OriginalSourceFileID.isValid()) { - PrimaryModule.OriginalSourceFileID + PrimaryModule.OriginalSourceFileID = FileID::get(PrimaryModule.SLocEntryBaseID + PrimaryModule.OriginalSourceFileID.getOpaqueValue() - 1); @@ -3666,11 +3806,11 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, SourceMgr.setMainFileID(PrimaryModule.OriginalSourceFileID); } } - + // For any Objective-C class definitions we have already loaded, make sure // that we load any additional categories. for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) { - loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), + loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), ObjCClassesLoaded[I], PreviousGeneration); } @@ -3693,11 +3833,12 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, return Success; } -static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile); +static ASTFileSignature readASTFileSignature(StringRef PCH); /// \brief Whether \p Stream starts with the AST/PCH file magic number 'CPCH'. static bool startsWithASTFileMagic(BitstreamCursor &Stream) { - return Stream.Read(8) == 'C' && + return Stream.canSkipToPos(4) && + Stream.Read(8) == 'C' && Stream.Read(8) == 'P' && Stream.Read(8) == 'C' && Stream.Read(8) == 'H'; @@ -3709,6 +3850,7 @@ static unsigned moduleKindForDiagnostic(ModuleKind Kind) { return 0; // PCH case MK_ImplicitModule: case MK_ExplicitModule: + case MK_PrebuiltModule: return 1; // module case MK_MainFile: case MK_Preamble: @@ -3750,7 +3892,7 @@ ASTReader::ReadASTCore(StringRef FileName, // Otherwise, return an error. Diag(diag::err_module_file_not_found) << moduleKindForDiagnostic(Type) - << FileName << ErrorStr.empty() + << FileName << !ErrorStr.empty() << ErrorStr; return Failure; @@ -3762,7 +3904,7 @@ ASTReader::ReadASTCore(StringRef FileName, // Otherwise, return an error. Diag(diag::err_module_file_out_of_date) << moduleKindForDiagnostic(Type) - << FileName << ErrorStr.empty() + << FileName << !ErrorStr.empty() << ErrorStr; return Failure; } @@ -3778,10 +3920,9 @@ ASTReader::ReadASTCore(StringRef FileName, ModuleFile &F = *M; BitstreamCursor &Stream = F.Stream; - PCHContainerRdr.ExtractPCH(F.Buffer->getMemBufferRef(), F.StreamFile); - Stream.init(&F.StreamFile); + Stream = BitstreamCursor(PCHContainerRdr.ExtractPCH(*F.Buffer)); F.SizeInBits = F.Buffer->getBufferSize() * 8; - + // Sniff for the signature. if (!startsWithASTFileMagic(Stream)) { Diag(diag::err_module_file_invalid) << moduleKindForDiagnostic(Type) @@ -3791,16 +3932,16 @@ ASTReader::ReadASTCore(StringRef FileName, // This is used for compatibility with older PCH formats. bool HaveReadControlBlock = false; - while (1) { + while (true) { llvm::BitstreamEntry Entry = Stream.advance(); - + switch (Entry.Kind) { case llvm::BitstreamEntry::Error: case llvm::BitstreamEntry::Record: case llvm::BitstreamEntry::EndBlock: Error("invalid record at top-level of AST file"); return Failure; - + case llvm::BitstreamEntry::SubBlock: break; } @@ -3814,7 +3955,8 @@ ASTReader::ReadASTCore(StringRef FileName, // // FIXME: Should we also perform the converse check? Loading a module as // a PCH file sort of works, but it's a bit wonky. - if ((Type == MK_ImplicitModule || Type == MK_ExplicitModule) && + if ((Type == MK_ImplicitModule || Type == MK_ExplicitModule || + Type == MK_PrebuiltModule) && F.ModuleName.empty()) { auto Result = (Type == MK_ImplicitModule) ? OutOfDate : Failure; if (Result != OutOfDate || @@ -3930,26 +4072,26 @@ ASTReader::ASTReadResult ASTReader::ReadExtensionBlock(ModuleFile &F) { 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, + DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, Context.getTranslationUnitDecl()); // FIXME: Find a better way to deal with collisions between these // built-in types. Right now, we just ignore the problem. - + // Load the special types. if (SpecialTypes.size() >= NumSpecialTypeIDs) { if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) { if (!Context.CFConstantStringTypeDecl) Context.setCFConstantStringType(GetType(String)); } - + if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) { QualType FileType = GetType(File); if (FileType.isNull()) { Error("FILE type is NULL"); return; } - + if (!Context.FILEDecl) { if (const TypedefType *Typedef = FileType->getAs<TypedefType>()) Context.setFILEDecl(Typedef->getDecl()); @@ -3963,14 +4105,14 @@ void ASTReader::InitializeContext() { } } } - + if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) { QualType Jmp_bufType = GetType(Jmp_buf); if (Jmp_bufType.isNull()) { Error("jmp_buf type is NULL"); return; } - + if (!Context.jmp_bufDecl) { if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>()) Context.setjmp_bufDecl(Typedef->getDecl()); @@ -3984,14 +4126,14 @@ void ASTReader::InitializeContext() { } } } - + if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) { QualType Sigjmp_bufType = GetType(Sigjmp_buf); if (Sigjmp_bufType.isNull()) { Error("sigjmp_buf type is NULL"); return; } - + if (!Context.sigjmp_bufDecl) { if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>()) Context.setsigjmp_bufDecl(Typedef->getDecl()); @@ -4039,7 +4181,7 @@ void ASTReader::InitializeContext() { } } } - + ReadPragmaDiagnosticMappings(Context.getDiagnostics()); // If there were any CUDA special declarations, deserialize them. @@ -4067,10 +4209,10 @@ void ASTReader::finalizeForWriting() { // Nothing to do for now. } -/// \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); +/// \brief Reads and return the signature record from \p PCH's control block, or +/// else returns 0. +static ASTFileSignature readASTFileSignature(StringRef PCH) { + BitstreamCursor Stream(PCH); if (!startsWithASTFileMagic(Stream)) return 0; @@ -4080,10 +4222,9 @@ static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile){ // Scan for SIGNATURE inside the control block. ASTReader::RecordData Record; - while (1) { + while (true) { llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - if (Entry.Kind == llvm::BitstreamEntry::EndBlock || - Entry.Kind != llvm::BitstreamEntry::Record) + if (Entry.Kind != llvm::BitstreamEntry::Record) return 0; Record.clear(); @@ -4108,16 +4249,14 @@ std::string ASTReader::getOriginalSourceFile( } // Initialize the stream - llvm::BitstreamReader StreamFile; - PCHContainerRdr.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile); - BitstreamCursor Stream(StreamFile); + BitstreamCursor Stream(PCHContainerRdr.ExtractPCH(**Buffer)); // Sniff for the signature. if (!startsWithASTFileMagic(Stream)) { Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName; return std::string(); } - + // Scan for the CONTROL_BLOCK_ID block. if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) { Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName; @@ -4126,16 +4265,16 @@ std::string ASTReader::getOriginalSourceFile( // Scan for ORIGINAL_FILE inside the control block. RecordData Record; - while (1) { + while (true) { llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); if (Entry.Kind == llvm::BitstreamEntry::EndBlock) return std::string(); - + if (Entry.Kind != llvm::BitstreamEntry::Record) { Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName; return std::string(); } - + Record.clear(); StringRef Blob; if (Stream.readRecord(Entry.ID, Record, &Blob) == ORIGINAL_FILE) @@ -4144,6 +4283,7 @@ std::string ASTReader::getOriginalSourceFile( } namespace { + class SimplePCHValidator : public ASTReaderListener { const LangOptions &ExistingLangOpts; const TargetOptions &ExistingTargetOpts; @@ -4170,11 +4310,13 @@ namespace { return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr, AllowCompatibleDifferences); } + 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 { @@ -4182,6 +4324,7 @@ namespace { ExistingModuleCachePath, nullptr, ExistingLangOpts); } + bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, std::string &SuggestedPredefines) override { @@ -4189,13 +4332,14 @@ namespace { SuggestedPredefines, ExistingLangOpts); } }; -} + +} // end anonymous namespace bool ASTReader::readASTFileControlBlock( StringRef Filename, FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, - ASTReaderListener &Listener) { + ASTReaderListener &Listener, bool ValidateDiagnosticOptions) { // Open the AST file. // FIXME: This allows use of the VFS; we do not allow use of the // VFS when actually loading a module. @@ -4205,9 +4349,7 @@ bool ASTReader::readASTFileControlBlock( } // Initialize the stream - llvm::BitstreamReader StreamFile; - PCHContainerRdr.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile); - BitstreamCursor Stream(StreamFile); + BitstreamCursor Stream(PCHContainerRdr.ExtractPCH(**Buffer)); // Sniff for the signature. if (!startsWithASTFileMagic(Stream)) @@ -4235,7 +4377,8 @@ bool ASTReader::readASTFileControlBlock( std::string IgnoredSuggestedPredefines; if (ReadOptionsBlock(Stream, ARR_ConfigurationMismatch | ARR_OutOfDate, /*AllowCompatibleConfigurationMismatch*/ false, - Listener, IgnoredSuggestedPredefines) != Success) + Listener, IgnoredSuggestedPredefines, + ValidateDiagnosticOptions) != Success) return true; break; } @@ -4280,7 +4423,7 @@ bool ASTReader::readASTFileControlBlock( if (Listener.ReadFullVersionInformation(Blob)) return true; - + break; } case MODULE_NAME: @@ -4408,7 +4551,8 @@ bool ASTReader::isAcceptableASTFile( ExistingModuleCachePath, FileMgr); return !readASTFileControlBlock(Filename, FileMgr, PCHContainerRdr, /*FindModuleFileExtensions=*/false, - validator); + validator, + /*ValidateDiagnosticOptions=*/true); } ASTReader::ASTReadResult @@ -4425,7 +4569,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { RecordData Record; while (true) { llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks(); - + switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. case llvm::BitstreamEntry::Error: @@ -4523,7 +4667,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { CurrentModule->ConfigMacrosExhaustive = ConfigMacrosExhaustive; if (DeserializationListener) DeserializationListener->ModuleRead(GlobalID, CurrentModule); - + SubmodulesLoaded[GlobalIndex] = CurrentModule; // Clear out data that will be replaced by what is in the module file. @@ -4563,7 +4707,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; } - + case SUBMODULE_HEADER: case SUBMODULE_EXCLUDED_HEADER: case SUBMODULE_PRIVATE_HEADER: @@ -4597,17 +4741,17 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; } - + case SUBMODULE_METADATA: { F.BaseSubmoduleID = getTotalNumSubmodules(); F.LocalNumSubmodules = Record[0]; unsigned LocalBaseSubmoduleID = Record[1]; if (F.LocalNumSubmodules > 0) { - // Introduce the global -> local mapping for submodules within this + // Introduce the global -> local mapping for submodules within this // module. GlobalSubmoduleMap.insert(std::make_pair(getTotalNumSubmodules()+1,&F)); - - // Introduce the local -> global mapping for submodules within this + + // Introduce the local -> global mapping for submodules within this // module. F.SubmoduleRemap.insertOrReplace( std::make_pair(LocalBaseSubmoduleID, @@ -4617,7 +4761,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; } - + case SUBMODULE_IMPORTS: { for (unsigned Idx = 0; Idx != Record.size(); ++Idx) { UnresolvedModuleRef Unresolved; @@ -4641,8 +4785,8 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Unresolved.IsWildcard = Record[Idx + 1]; UnresolvedModuleRefs.push_back(Unresolved); } - - // Once we've loaded the set of exports, there's no reason to keep + + // Once we've loaded the set of exports, there's no reason to keep // the parsed, unresolved exports around. CurrentModule->UnresolvedExports.clear(); break; @@ -4673,6 +4817,13 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { UnresolvedModuleRefs.push_back(Unresolved); break; } + + case SUBMODULE_INITIALIZERS: + SmallVector<uint32_t, 16> Inits; + for (auto &ID : Record) + Inits.push_back(getGlobalDeclID(F, ID)); + Context.addLazyModuleInitializers(CurrentModule, Inits); + break; } } } @@ -4848,7 +4999,7 @@ std::pair<ModuleFile *, unsigned> ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) { GlobalPreprocessedEntityMapType::iterator I = GlobalPreprocessedEntityMap.find(GlobalIndex); - assert(I != GlobalPreprocessedEntityMap.end() && + assert(I != GlobalPreprocessedEntityMap.end() && "Corrupted global preprocessed entity map"); ModuleFile *M = I->second; unsigned LocalIndex = GlobalIndex - M->BasePreprocessedEntityID; @@ -4884,8 +5035,8 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { Error("no preprocessing record"); return nullptr; } - - SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor); + + SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor); M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset); llvm::BitstreamEntry Entry = @@ -4924,7 +5075,7 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { return ME; } - + case PPD_MACRO_DEFINITION: { // Decode the identifier info and then check again; if the macro is // still defined and associated with the identifier, @@ -4936,14 +5087,14 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { return MD; } - + case PPD_INCLUSION_DIRECTIVE: { const char *FullFileNameStart = Blob.data() + Record[0]; StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]); const FileEntry *File = nullptr; if (!FullFileName.empty()) File = PP.getFileManager().getFile(FullFileName); - + // FIXME: Stable encoding InclusionDirective::InclusionKind Kind = static_cast<InclusionDirective::InclusionKind>(Record[2]); @@ -5006,7 +5157,7 @@ struct PPEntityComp { } }; -} +} // end anonymous namespace PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const { @@ -5084,11 +5235,11 @@ Optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index, ModuleFile &M = *PPInfo.first; unsigned LocalIndex = PPInfo.second; const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex]; - + SourceLocation Loc = TranslateSourceLocation(M, PPOffs.getBegin()); if (Loc.isInvalid()) return false; - + if (SourceMgr.isInFileID(SourceMgr.getFileLoc(Loc), FID)) return true; else @@ -5096,12 +5247,13 @@ Optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index, } namespace { + /// \brief Visitor used to search for information about a header file. class HeaderFileInfoVisitor { const FileEntry *FE; - + Optional<HeaderFileInfo> HFI; - + public: explicit HeaderFileInfoVisitor(const FileEntry *FE) : FE(FE) { } @@ -5120,17 +5272,18 @@ namespace { HFI = *Pos; return true; } - + Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; } }; -} + +} // end anonymous namespace HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { HeaderFileInfoVisitor Visitor(FE); ModuleMgr.visit(Visitor); if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo()) return *HFI; - + return HeaderFileInfo(); } @@ -5152,7 +5305,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) { FullSourceLoc(Loc, SourceMgr))); continue; } - + assert(DiagStateID == 0); // A new DiagState was created here. Diag.DiagStates.push_back(*Diag.GetCurDiagState()); @@ -5161,7 +5314,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) { Diag.DiagStatePoints.push_back( DiagnosticsEngine::DiagStatePoint(NewState, FullSourceLoc(Loc, SourceMgr))); - while (1) { + while (true) { assert(Idx < F.PragmaDiagMappings.size() && "Invalid data, didn't find '-1' marking end of diag/map pairs"); if (Idx >= F.PragmaDiagMappings.size()) { @@ -5298,7 +5451,7 @@ QualType ASTReader::readTypeRecord(unsigned Index) { QualType ClassType = readType(*Loc.F, Record, Idx); if (PointeeType.isNull() || ClassType.isNull()) return QualType(); - + return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr()); } @@ -5408,7 +5561,7 @@ QualType ASTReader::readTypeRecord(unsigned Index) { return Context.getTypeDeclType( ReadDeclAs<UnresolvedUsingTypenameDecl>(*Loc.F, Record, Idx)); } - + case TYPE_TYPEDEF: { if (Record.size() != 2) { Error("incorrect encoding of typedef type"); @@ -5529,6 +5682,16 @@ QualType ASTReader::readTypeRecord(unsigned Index) { return Context.getObjCInterfaceType(ItfD->getCanonicalDecl()); } + case TYPE_OBJC_TYPE_PARAM: { + unsigned Idx = 0; + ObjCTypeParamDecl *Decl + = ReadDeclAs<ObjCTypeParamDecl>(*Loc.F, Record, Idx); + unsigned NumProtos = Record[Idx++]; + SmallVector<ObjCProtocolDecl*, 4> Protos; + for (unsigned I = 0; I != NumProtos; ++I) + Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx)); + return Context.getObjCTypeParamType(Decl, Protos); + } case TYPE_OBJC_OBJECT: { unsigned Idx = 0; QualType Base = readType(*Loc.F, Record, Idx); @@ -5666,15 +5829,17 @@ QualType ASTReader::readTypeRecord(unsigned Index) { } case TYPE_PIPE: { - if (Record.size() != 1) { + if (Record.size() != 2) { Error("Incorrect encoding of pipe type"); return QualType(); } // Reading the pipe element type. QualType ElementType = readType(*Loc.F, Record, Idx); - return Context.getPipeType(ElementType); + unsigned ReadOnly = Record[1]; + return Context.getPipeType(ElementType, ReadOnly); } + } llvm_unreachable("Invalid TypeCode!"); } @@ -5701,26 +5866,27 @@ void ASTReader::readExceptionSpec(ModuleFile &ModuleFile, } class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> { - ASTReader &Reader; - ModuleFile &F; + ModuleFile *F; + ASTReader *Reader; const ASTReader::RecordData &Record; unsigned &Idx; - SourceLocation ReadSourceLocation(const ASTReader::RecordData &R, - unsigned &I) { - return Reader.ReadSourceLocation(F, R, I); + SourceLocation ReadSourceLocation() { + return Reader->ReadSourceLocation(*F, Record, Idx); } - template<typename T> - T *ReadDeclAs(const ASTReader::RecordData &Record, unsigned &Idx) { - return Reader.ReadDeclAs<T>(F, Record, Idx); + TypeSourceInfo *GetTypeSourceInfo() { + return Reader->GetTypeSourceInfo(*F, Record, Idx); } - + + NestedNameSpecifierLoc ReadNestedNameSpecifierLoc() { + return Reader->ReadNestedNameSpecifierLoc(*F, Record, Idx); + } + public: - TypeLocReader(ASTReader &Reader, ModuleFile &F, + TypeLocReader(ModuleFile &F, ASTReader &Reader, const ASTReader::RecordData &Record, unsigned &Idx) - : Reader(Reader), F(F), Record(Record), Idx(Idx) - { } + : F(&F), Reader(&Reader), Record(Record), Idx(Idx) {} // We want compile-time assurance that we've enumerated all of // these, so unfortunately we have to declare them first, then @@ -5737,8 +5903,9 @@ public: void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { // nothing to do } + void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { - TL.setBuiltinLoc(ReadSourceLocation(Record, Idx)); + TL.setBuiltinLoc(ReadSourceLocation()); if (TL.needsExtraLocalData()) { TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++])); TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++])); @@ -5746,219 +5913,264 @@ void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { TL.setModeAttr(Record[Idx++]); } } + void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) { - TL.setStarLoc(ReadSourceLocation(Record, Idx)); + TL.setStarLoc(ReadSourceLocation()); } + void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) { // nothing to do } + void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { // nothing to do } + void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { - TL.setCaretLoc(ReadSourceLocation(Record, Idx)); + TL.setCaretLoc(ReadSourceLocation()); } + void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { - TL.setAmpLoc(ReadSourceLocation(Record, Idx)); + TL.setAmpLoc(ReadSourceLocation()); } + void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { - TL.setAmpAmpLoc(ReadSourceLocation(Record, Idx)); + TL.setAmpAmpLoc(ReadSourceLocation()); } + void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { - TL.setStarLoc(ReadSourceLocation(Record, Idx)); - TL.setClassTInfo(Reader.GetTypeSourceInfo(F, Record, Idx)); + TL.setStarLoc(ReadSourceLocation()); + TL.setClassTInfo(GetTypeSourceInfo()); } + void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) { - TL.setLBracketLoc(ReadSourceLocation(Record, Idx)); - TL.setRBracketLoc(ReadSourceLocation(Record, Idx)); + TL.setLBracketLoc(ReadSourceLocation()); + TL.setRBracketLoc(ReadSourceLocation()); if (Record[Idx++]) - TL.setSizeExpr(Reader.ReadExpr(F)); + TL.setSizeExpr(Reader->ReadExpr(*F)); else TL.setSizeExpr(nullptr); } + void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { VisitArrayTypeLoc(TL); } + void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { VisitArrayTypeLoc(TL); } + void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { VisitArrayTypeLoc(TL); } + void TypeLocReader::VisitDependentSizedArrayTypeLoc( DependentSizedArrayTypeLoc TL) { VisitArrayTypeLoc(TL); } + void TypeLocReader::VisitDependentSizedExtVectorTypeLoc( DependentSizedExtVectorTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) { - TL.setLocalRangeBegin(ReadSourceLocation(Record, Idx)); - TL.setLParenLoc(ReadSourceLocation(Record, Idx)); - TL.setRParenLoc(ReadSourceLocation(Record, Idx)); - TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx)); + TL.setLocalRangeBegin(ReadSourceLocation()); + TL.setLParenLoc(ReadSourceLocation()); + TL.setRParenLoc(ReadSourceLocation()); + TL.setLocalRangeEnd(ReadSourceLocation()); for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) { - TL.setParam(i, ReadDeclAs<ParmVarDecl>(Record, Idx)); + TL.setParam(i, Reader->ReadDeclAs<ParmVarDecl>(*F, Record, Idx)); } } + void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { VisitFunctionTypeLoc(TL); } + void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { VisitFunctionTypeLoc(TL); } void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { - TL.setTypeofLoc(ReadSourceLocation(Record, Idx)); - TL.setLParenLoc(ReadSourceLocation(Record, Idx)); - TL.setRParenLoc(ReadSourceLocation(Record, Idx)); + TL.setTypeofLoc(ReadSourceLocation()); + TL.setLParenLoc(ReadSourceLocation()); + TL.setRParenLoc(ReadSourceLocation()); } void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { - TL.setTypeofLoc(ReadSourceLocation(Record, Idx)); - TL.setLParenLoc(ReadSourceLocation(Record, Idx)); - TL.setRParenLoc(ReadSourceLocation(Record, Idx)); - TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx)); + TL.setTypeofLoc(ReadSourceLocation()); + TL.setLParenLoc(ReadSourceLocation()); + TL.setRParenLoc(ReadSourceLocation()); + TL.setUnderlyingTInfo(GetTypeSourceInfo()); } void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { - TL.setKWLoc(ReadSourceLocation(Record, Idx)); - TL.setLParenLoc(ReadSourceLocation(Record, Idx)); - TL.setRParenLoc(ReadSourceLocation(Record, Idx)); - TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx)); + TL.setKWLoc(ReadSourceLocation()); + TL.setLParenLoc(ReadSourceLocation()); + TL.setRParenLoc(ReadSourceLocation()); + TL.setUnderlyingTInfo(GetTypeSourceInfo()); } + void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) { - TL.setAttrNameLoc(ReadSourceLocation(Record, Idx)); + TL.setAttrNameLoc(ReadSourceLocation()); if (TL.hasAttrOperand()) { SourceRange range; - range.setBegin(ReadSourceLocation(Record, Idx)); - range.setEnd(ReadSourceLocation(Record, Idx)); + range.setBegin(ReadSourceLocation()); + range.setEnd(ReadSourceLocation()); TL.setAttrOperandParensRange(range); } if (TL.hasAttrExprOperand()) { if (Record[Idx++]) - TL.setAttrExprOperand(Reader.ReadExpr(F)); + TL.setAttrExprOperand(Reader->ReadExpr(*F)); else TL.setAttrExprOperand(nullptr); } else if (TL.hasAttrEnumOperand()) - TL.setAttrEnumOperandLoc(ReadSourceLocation(Record, Idx)); + TL.setAttrEnumOperandLoc(ReadSourceLocation()); } + void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc( SubstTemplateTypeParmTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc( SubstTemplateTypeParmPackTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } void TypeLocReader::VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TL) { - TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx)); - TL.setLAngleLoc(ReadSourceLocation(Record, Idx)); - TL.setRAngleLoc(ReadSourceLocation(Record, Idx)); + TL.setTemplateKeywordLoc(ReadSourceLocation()); + TL.setTemplateNameLoc(ReadSourceLocation()); + TL.setLAngleLoc(ReadSourceLocation()); + TL.setRAngleLoc(ReadSourceLocation()); for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) - TL.setArgLocInfo(i, - Reader.GetTemplateArgumentLocInfo(F, - TL.getTypePtr()->getArg(i).getKind(), - Record, Idx)); + TL.setArgLocInfo( + i, + Reader->GetTemplateArgumentLocInfo( + *F, TL.getTypePtr()->getArg(i).getKind(), Record, Idx)); } void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) { - TL.setLParenLoc(ReadSourceLocation(Record, Idx)); - TL.setRParenLoc(ReadSourceLocation(Record, Idx)); + TL.setLParenLoc(ReadSourceLocation()); + TL.setRParenLoc(ReadSourceLocation()); } + void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx)); + TL.setElaboratedKeywordLoc(ReadSourceLocation()); + TL.setQualifierLoc(ReadNestedNameSpecifierLoc()); } + void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { - TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx)); - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setElaboratedKeywordLoc(ReadSourceLocation()); + TL.setQualifierLoc(ReadNestedNameSpecifierLoc()); + TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc TL) { - TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx)); - TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx)); - TL.setLAngleLoc(ReadSourceLocation(Record, Idx)); - TL.setRAngleLoc(ReadSourceLocation(Record, Idx)); + TL.setElaboratedKeywordLoc(ReadSourceLocation()); + TL.setQualifierLoc(ReadNestedNameSpecifierLoc()); + TL.setTemplateKeywordLoc(ReadSourceLocation()); + TL.setTemplateNameLoc(ReadSourceLocation()); + TL.setLAngleLoc(ReadSourceLocation()); + TL.setRAngleLoc(ReadSourceLocation()); for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) - TL.setArgLocInfo(I, - Reader.GetTemplateArgumentLocInfo(F, - TL.getTypePtr()->getArg(I).getKind(), - Record, Idx)); + TL.setArgLocInfo( + I, + Reader->GetTemplateArgumentLocInfo( + *F, TL.getTypePtr()->getArg(I).getKind(), Record, Idx)); } + void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { - TL.setEllipsisLoc(ReadSourceLocation(Record, Idx)); + TL.setEllipsisLoc(ReadSourceLocation()); } + void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { - TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setNameLoc(ReadSourceLocation()); } + +void TypeLocReader::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) { + if (TL.getNumProtocols()) { + TL.setProtocolLAngleLoc(ReadSourceLocation()); + TL.setProtocolRAngleLoc(ReadSourceLocation()); + } + for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) + TL.setProtocolLoc(i, ReadSourceLocation()); +} + void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { TL.setHasBaseTypeAsWritten(Record[Idx++]); - TL.setTypeArgsLAngleLoc(ReadSourceLocation(Record, Idx)); - TL.setTypeArgsRAngleLoc(ReadSourceLocation(Record, Idx)); + TL.setTypeArgsLAngleLoc(ReadSourceLocation()); + TL.setTypeArgsRAngleLoc(ReadSourceLocation()); for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i) - TL.setTypeArgTInfo(i, Reader.GetTypeSourceInfo(F, Record, Idx)); - TL.setProtocolLAngleLoc(ReadSourceLocation(Record, Idx)); - TL.setProtocolRAngleLoc(ReadSourceLocation(Record, Idx)); + TL.setTypeArgTInfo(i, GetTypeSourceInfo()); + TL.setProtocolLAngleLoc(ReadSourceLocation()); + TL.setProtocolRAngleLoc(ReadSourceLocation()); for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) - TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx)); + TL.setProtocolLoc(i, ReadSourceLocation()); } + void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { - TL.setStarLoc(ReadSourceLocation(Record, Idx)); + TL.setStarLoc(ReadSourceLocation()); } + void TypeLocReader::VisitAtomicTypeLoc(AtomicTypeLoc TL) { - TL.setKWLoc(ReadSourceLocation(Record, Idx)); - TL.setLParenLoc(ReadSourceLocation(Record, Idx)); - TL.setRParenLoc(ReadSourceLocation(Record, Idx)); + TL.setKWLoc(ReadSourceLocation()); + TL.setLParenLoc(ReadSourceLocation()); + TL.setRParenLoc(ReadSourceLocation()); } + void TypeLocReader::VisitPipeTypeLoc(PipeTypeLoc TL) { - TL.setKWLoc(ReadSourceLocation(Record, Idx)); + TL.setKWLoc(ReadSourceLocation()); } -TypeSourceInfo *ASTReader::GetTypeSourceInfo(ModuleFile &F, - const RecordData &Record, - unsigned &Idx) { +TypeSourceInfo * +ASTReader::GetTypeSourceInfo(ModuleFile &F, const ASTReader::RecordData &Record, + unsigned &Idx) { QualType InfoTy = readType(F, Record, Idx); if (InfoTy.isNull()) return nullptr; TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy); - TypeLocReader TLR(*this, F, Record, Idx); + TypeLocReader TLR(F, *this, Record, Idx); for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) TLR.Visit(TL); return TInfo; @@ -6141,18 +6353,18 @@ QualType ASTReader::getLocalType(ModuleFile &F, unsigned LocalID) { return GetType(getGlobalTypeID(F, LocalID)); } -serialization::TypeID +serialization::TypeID ASTReader::getGlobalTypeID(ModuleFile &F, unsigned LocalID) const { unsigned FastQuals = LocalID & Qualifiers::FastMask; unsigned LocalIndex = LocalID >> Qualifiers::FastWidth; - + if (LocalIndex < NUM_PREDEF_TYPE_IDS) return LocalID; ContinuousRangeMap<uint32_t, int, 2>::iterator I = F.TypeRemap.find(LocalIndex - NUM_PREDEF_TYPE_IDS); assert(I != F.TypeRemap.end() && "Invalid index into type index remap"); - + unsigned GlobalIndex = LocalIndex + I->second; return (GlobalIndex << Qualifiers::FastWidth) | FastQuals; } @@ -6168,18 +6380,18 @@ ASTReader::GetTemplateArgumentLocInfo(ModuleFile &F, case TemplateArgument::Type: return GetTypeSourceInfo(F, Record, Index); case TemplateArgument::Template: { - NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, + NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Index); SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index); return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, SourceLocation()); } case TemplateArgument::TemplateExpansion: { - NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, + NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Index); SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index); SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index); - return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, + return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc); } case TemplateArgument::Null: @@ -6324,7 +6536,7 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { return Bases; } -serialization::DeclID +serialization::DeclID ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const { if (LocalID < NUM_PREDEF_DECL_IDS) return LocalID; @@ -6332,7 +6544,7 @@ ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const { ContinuousRangeMap<uint32_t, int, 2>::iterator I = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS); assert(I != F.DeclRemap.end() && "Invalid index into decl index remap"); - + return LocalID + I->second; } @@ -6342,7 +6554,7 @@ bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID, if (ID < NUM_PREDEF_DECL_IDS) return false; - return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && + return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && ID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls; } @@ -6474,11 +6686,11 @@ Decl *ASTReader::GetDecl(DeclID ID) { return DeclsLoaded[Index]; } -DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, +DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, DeclID GlobalID) { if (GlobalID < NUM_PREDEF_DECL_IDS) return GlobalID; - + GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); ModuleFile *Owner = I->second; @@ -6487,18 +6699,18 @@ DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, = M.GlobalToLocalDeclIDs.find(Owner); if (Pos == M.GlobalToLocalDeclIDs.end()) return 0; - + return GlobalID - Owner->BaseDeclID + Pos->second; } -serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F, +serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordData &Record, unsigned &Idx) { if (Idx >= Record.size()) { Error("Corrupted AST file"); return 0; } - + return getGlobalDeclID(F, Record[Idx++]); } @@ -6591,7 +6803,7 @@ public: } }; -} +} // end anonymous namespace void ASTReader::FindFileRegionDecls(FileID File, unsigned Offset, unsigned Length, @@ -6630,7 +6842,7 @@ void ASTReader::FindFileRegionDecls(FileID File, EndLoc, DIDComp); if (EndIt != DInfo.Decls.end()) ++EndIt; - + for (ArrayRef<serialization::LocalDeclID>::iterator DIt = BeginIt; DIt != EndIt; ++DIt) Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt))); @@ -6841,23 +7053,23 @@ void ASTReader::PrintStats() { std::fprintf(stderr, "\n"); GlobalIndex->printStats(); } - + std::fprintf(stderr, "\n"); dump(); std::fprintf(stderr, "\n"); } template<typename Key, typename ModuleFile, unsigned InitialCapacity> -static void +static void dumpModuleIDMap(StringRef Name, - const ContinuousRangeMap<Key, ModuleFile *, + const ContinuousRangeMap<Key, ModuleFile *, InitialCapacity> &Map) { if (Map.begin() == Map.end()) return; - + typedef ContinuousRangeMap<Key, ModuleFile *, InitialCapacity> MapType; llvm::errs() << Name << ":\n"; - for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); + for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); I != IEnd; ++I) { llvm::errs() << " " << I->first << " -> " << I->second->FileName << "\n"; @@ -6874,11 +7086,11 @@ LLVM_DUMP_METHOD void ASTReader::dump() { dumpModuleIDMap("Global macro map", GlobalMacroMap); dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap); dumpModuleIDMap("Global selector map", GlobalSelectorMap); - dumpModuleIDMap("Global preprocessed entity map", + dumpModuleIDMap("Global preprocessed entity map", GlobalPreprocessedEntityMap); - + llvm::errs() << "\n*** PCH/Modules Loaded:"; - for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(), + for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(), MEnd = ModuleMgr.end(); M != MEnd; ++M) (*M)->dump(); @@ -6921,14 +7133,9 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0]; } - // FIXME: What happens if these are changed by a module import? - if (!OpenCLExtensions.empty()) { - unsigned I = 0; -#define OPENCLEXT(nm) SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++]; -#include "clang/Basic/OpenCLExtensions.def" - - assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS"); - } + SemaObj->OpenCLFeatures.copy(OpenCLExtensions); + SemaObj->OpenCLTypeExtMap = OpenCLTypeExtMap; + SemaObj->OpenCLDeclExtMap = OpenCLDeclExtMap; UpdateSema(); } @@ -6939,12 +7146,14 @@ void ASTReader::UpdateSema() { // Load the offsets of the declarations that Sema references. // They will be lazily deserialized when needed. if (!SemaDeclRefs.empty()) { - assert(SemaDeclRefs.size() % 2 == 0); - for (unsigned I = 0; I != SemaDeclRefs.size(); I += 2) { + assert(SemaDeclRefs.size() % 3 == 0); + for (unsigned I = 0; I != SemaDeclRefs.size(); I += 3) { if (!SemaObj->StdNamespace) SemaObj->StdNamespace = SemaDeclRefs[I]; if (!SemaObj->StdBadAlloc) SemaObj->StdBadAlloc = SemaDeclRefs[I+1]; + if (!SemaObj->StdAlignValT) + SemaObj->StdAlignValT = SemaDeclRefs[I+2]; } SemaDeclRefs.clear(); } @@ -6961,6 +7170,7 @@ void ASTReader::UpdateSema() { PragmaMSPointersToMembersState, PointersToMembersPragmaLocation); } + SemaObj->ForceCUDAHostDeviceDepth = ForceCUDAHostDeviceDepth; } IdentifierInfo *ASTReader::get(StringRef Name) { @@ -6999,6 +7209,7 @@ IdentifierInfo *ASTReader::get(StringRef Name) { } namespace clang { + /// \brief An identifier-lookup iterator that enumerates all of the /// identifiers stored within a set of AST files. class ASTIdentifierIterator : public IdentifierIterator { @@ -7026,7 +7237,8 @@ namespace clang { StringRef Next() override; }; -} + +} // end namespace clang ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader, bool SkipModules) @@ -7058,6 +7270,7 @@ StringRef ASTIdentifierIterator::Next() { } namespace { + /// A utility for appending two IdentifierIterators. class ChainedIdentifierIterator : public IdentifierIterator { std::unique_ptr<IdentifierIterator> Current; @@ -7082,6 +7295,7 @@ public: return Next(); } }; + } // end anonymous namespace. IdentifierIterator *ASTReader::getIdentifiers() { @@ -7097,7 +7311,9 @@ IdentifierIterator *ASTReader::getIdentifiers() { return new ASTIdentifierIterator(*this); } -namespace clang { namespace serialization { +namespace clang { +namespace serialization { + class ReadMethodPoolVisitor { ASTReader &Reader; Selector Sel; @@ -7119,7 +7335,7 @@ namespace clang { namespace serialization { bool operator()(ModuleFile &M) { if (!M.SelectorLookupTable) return false; - + // If we've already searched this module file, skip it now. if (M.Generation <= PriorGeneration) return true; @@ -7149,14 +7365,14 @@ namespace clang { namespace serialization { FactoryHasMoreThanOneDecl = Data.FactoryHasMoreThanOneDecl; return true; } - + /// \brief Retrieve the instance methods found by this visitor. - ArrayRef<ObjCMethodDecl *> getInstanceMethods() const { - return InstanceMethods; + ArrayRef<ObjCMethodDecl *> getInstanceMethods() const { + return InstanceMethods; } /// \brief Retrieve the instance methods found by this visitor. - ArrayRef<ObjCMethodDecl *> getFactoryMethods() const { + ArrayRef<ObjCMethodDecl *> getFactoryMethods() const { return FactoryMethods; } @@ -7167,7 +7383,9 @@ namespace clang { namespace serialization { } bool factoryHasMoreThanOneDecl() const { return FactoryHasMoreThanOneDecl; } }; -} } // end namespace clang::serialization + +} // end namespace serialization +} // end namespace clang /// \brief Add the given set of methods to the method list. static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods, @@ -7176,14 +7394,14 @@ static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods, S.addMethodToGlobalList(&List, Methods[I]); } } - + void ASTReader::ReadMethodPool(Selector Sel) { // Get the selector generation and update it to the current generation. unsigned &Generation = SelectorGeneration[Sel]; unsigned PriorGeneration = Generation; Generation = getGeneration(); SelectorOutOfDate[Sel] = false; - + // Search for methods defined with this selector. ++NumMethodPoolLookups; ReadMethodPoolVisitor Visitor(*this, Sel, PriorGeneration); @@ -7197,7 +7415,7 @@ void ASTReader::ReadMethodPool(Selector Sel) { if (!getSema()) return; - + Sema &S = *getSema(); Sema::GlobalMethodPool::iterator Pos = S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethods())).first; @@ -7222,9 +7440,9 @@ void ASTReader::updateOutOfDateSelector(Selector Sel) { void ASTReader::ReadKnownNamespaces( SmallVectorImpl<NamespaceDecl *> &Namespaces) { Namespaces.clear(); - + for (unsigned I = 0, N = KnownNamespaces.size(); I != N; ++I) { - if (NamespaceDecl *Namespace + if (NamespaceDecl *Namespace = dyn_cast_or_null<NamespaceDecl>(GetDecl(KnownNamespaces[I]))) Namespaces.push_back(Namespace); } @@ -7313,7 +7531,7 @@ void ASTReader::ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) { if (ReferencedSelectorsData.empty()) return; - + // If there are @selector references added them to its pool. This is for // implementation of -Wselector. unsigned int DataSize = ReferencedSelectorsData.size()-1; @@ -7333,9 +7551,9 @@ void ASTReader::ReadWeakUndeclaredIdentifiers( return; for (unsigned I = 0, N = WeakUndeclaredIdentifiers.size(); I < N; /*none*/) { - IdentifierInfo *WeakId + IdentifierInfo *WeakId = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]); - IdentifierInfo *AliasId + IdentifierInfo *AliasId = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]); SourceLocation Loc = SourceLocation::getFromRawEncoding(WeakUndeclaredIdentifiers[I++]); @@ -7355,7 +7573,7 @@ void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) { VT.DefinitionRequired = VTableUses[Idx++]; VTables.push_back(VT); } - + VTableUses.clear(); } @@ -7367,17 +7585,18 @@ void ASTReader::ReadPendingInstantiations( = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]); Pending.push_back(std::make_pair(D, Loc)); - } + } PendingInstantiations.clear(); } void ASTReader::ReadLateParsedTemplates( - llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) { + llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>> + &LPTMap) { for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N; /* In loop */) { FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++])); - LateParsedTemplate *LT = new LateParsedTemplate; + auto LT = llvm::make_unique<LateParsedTemplate>(); LT->D = GetDecl(LateParsedTemplates[Idx++]); ModuleFile *F = getOwningModuleFile(LT->D); @@ -7388,7 +7607,7 @@ void ASTReader::ReadLateParsedTemplates( for (unsigned T = 0; T < TokN; ++T) LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx)); - LPTMap.insert(std::make_pair(FD, LT)); + LPTMap.insert(std::make_pair(FD, std::move(LT))); } LateParsedTemplates.clear(); @@ -7498,12 +7717,12 @@ IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, unsigned LocalID) { IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) { if (LocalID < NUM_PREDEF_IDENT_IDS) return LocalID; - + ContinuousRangeMap<uint32_t, int, 2>::iterator I = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS); - assert(I != M.IdentifierRemap.end() + assert(I != M.IdentifierRemap.end() && "Invalid index into identifier index remap"); - + return LocalID + I->second; } @@ -7524,7 +7743,7 @@ MacroInfo *ASTReader::getMacro(MacroID ID) { ModuleFile *M = I->second; unsigned Index = ID - M->BaseMacroID; MacrosLoaded[ID] = ReadMacroRecord(*M, M->MacroOffsets[Index]); - + if (DeserializationListener) DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS, MacrosLoaded[ID]); @@ -7548,12 +7767,12 @@ serialization::SubmoduleID ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) { if (LocalID < NUM_PREDEF_SUBMODULE_IDS) return LocalID; - + ContinuousRangeMap<uint32_t, int, 2>::iterator I = M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS); - assert(I != M.SubmoduleRemap.end() + assert(I != M.SubmoduleRemap.end() && "Invalid index into submodule index remap"); - + return LocalID + I->second; } @@ -7562,12 +7781,12 @@ Module *ASTReader::getSubmodule(SubmoduleID GlobalID) { assert(GlobalID == 0 && "Unhandled global submodule ID"); return nullptr; } - + if (GlobalID > SubmodulesLoaded.size()) { Error("submodule ID out of range in AST file"); return nullptr; } - + return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS]; } @@ -7664,17 +7883,17 @@ serialization::SelectorID ASTReader::getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const { if (LocalID < NUM_PREDEF_SELECTOR_IDS) return LocalID; - + ContinuousRangeMap<uint32_t, int, 2>::iterator I = M.SelectorRemap.find(LocalID - NUM_PREDEF_SELECTOR_IDS); - assert(I != M.SelectorRemap.end() + assert(I != M.SelectorRemap.end() && "Invalid index into selector index remap"); - + return LocalID + I->second; } DeclarationName -ASTReader::ReadDeclarationName(ModuleFile &F, +ASTReader::ReadDeclarationName(ModuleFile &F, const RecordData &Record, unsigned &Idx) { DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++]; switch (Kind) { @@ -7762,13 +7981,13 @@ void ASTReader::ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info, Info.NumTemplParamLists = NumTPLists; if (NumTPLists) { Info.TemplParamLists = new (Context) TemplateParameterList*[NumTPLists]; - for (unsigned i=0; i != NumTPLists; ++i) + for (unsigned i = 0; i != NumTPLists; ++i) Info.TemplParamLists[i] = ReadTemplateParameterList(F, Record, Idx); } } TemplateName -ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record, +ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record, unsigned &Idx) { TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++]; switch (Kind) { @@ -7795,7 +8014,7 @@ ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record, NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx); if (Record[Idx++]) // isIdentifier return Context.getDependentTemplateName(NNS, - GetIdentifierInfo(F, Record, + GetIdentifierInfo(F, Record, Idx)); return Context.getDependentTemplateName(NNS, (OverloadedOperatorKind)Record[Idx++]); @@ -7808,17 +8027,17 @@ ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record, TemplateName replacement = ReadTemplateName(F, Record, Idx); return Context.getSubstTemplateTemplateParm(param, replacement); } - + case TemplateName::SubstTemplateTemplateParmPack: { - TemplateTemplateParmDecl *Param + TemplateTemplateParmDecl *Param = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx); if (!Param) return TemplateName(); - + TemplateArgument ArgPack = ReadTemplateArgument(F, Record, Idx); if (ArgPack.getKind() != TemplateArgument::Pack) return TemplateName(); - + return Context.getSubstTemplateTemplateParmPack(Param, ArgPack); } } @@ -7856,7 +8075,7 @@ TemplateArgument ASTReader::ReadTemplateArgument(ModuleFile &F, QualType T = readType(F, Record, Idx); return TemplateArgument(Context, Value, T); } - case TemplateArgument::Template: + case TemplateArgument::Template: return TemplateArgument(ReadTemplateName(F, Record, Idx)); case TemplateArgument::TemplateExpansion: { TemplateName Name = ReadTemplateName(F, Record, Idx); @@ -7892,9 +8111,10 @@ ASTReader::ReadTemplateParameterList(ModuleFile &F, while (NumParams--) Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx)); + // TODO: Concepts TemplateParameterList* TemplateParams = TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc, - Params, RAngleLoc); + Params, RAngleLoc, nullptr); return TemplateParams; } @@ -7931,7 +8151,7 @@ ASTReader::ReadCXXBaseSpecifier(ModuleFile &F, TypeSourceInfo *TInfo = GetTypeSourceInfo(F, Record, Idx); SourceRange Range = ReadSourceRange(F, Record, Idx); SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Idx); - CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo, + CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo, EllipsisLoc); Result.setInheritConstructors(inheritConstructors); return Result; @@ -7973,49 +8193,29 @@ ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, 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) { + if (Type == CTOR_INITIALIZER_BASE) BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, IsBaseVirtual, LParenLoc, Init, RParenLoc, MemberOrEllipsisLoc); - } else if (Type == CTOR_INITIALIZER_DELEGATING) { + 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 { - BOMInit = CXXCtorInitializer::Create( - Context, Member, MemberOrEllipsisLoc, LParenLoc, Init, RParenLoc, - Indices.data(), Indices.size()); - } + else if (Member) + BOMInit = new (Context) + CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc, LParenLoc, + Init, RParenLoc); + else + BOMInit = new (Context) + CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc, + LParenLoc, Init, RParenLoc); + + if (/*IsWritten*/Record[Idx++]) { + unsigned SourceOrder = Record[Idx++]; + BOMInit->setSourceOrder(SourceOrder); } - if (IsWritten) - BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices); CtorInitializers[i] = BOMInit; } @@ -8078,7 +8278,7 @@ ASTReader::ReadNestedNameSpecifier(ModuleFile &F, } NestedNameSpecifierLoc -ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record, +ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record, unsigned &Idx) { unsigned N = Record[Idx++]; NestedNameSpecifierLocBuilder Builder; @@ -8087,7 +8287,7 @@ ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record, = (NestedNameSpecifier::SpecifierKind)Record[Idx++]; switch (Kind) { case NestedNameSpecifier::Identifier: { - IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx); + IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx); SourceRange Range = ReadSourceRange(F, Record, Idx); Builder.Extend(Context, II, Range.getBegin(), Range.getEnd()); break; @@ -8116,7 +8316,7 @@ ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record, SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx); // FIXME: 'template' keyword location not saved anywhere, so we fake it. - Builder.Extend(Context, + Builder.Extend(Context, Template? T->getTypeLoc().getBeginLoc() : SourceLocation(), T->getTypeLoc(), ColonColonLoc); break; @@ -8185,7 +8385,7 @@ std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record, return Filename; } -VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, +VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, unsigned &Idx) { unsigned Major = Record[Idx++]; unsigned Minor = Record[Idx++]; @@ -8197,7 +8397,7 @@ VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, return VersionTuple(Major, Minor - 1, Subminor - 1); } -CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F, +CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F, const RecordData &Record, unsigned &Idx) { CXXDestructorDecl *Decl = ReadDeclAs<CXXDestructorDecl>(F, Record, Idx); @@ -8283,6 +8483,10 @@ void ASTReader::ReadComments() { } } NextCursor: + // De-serialized SourceLocations get negative FileIDs for other modules, + // potentially invalidating the original order. Sort it again. + std::sort(Comments.begin(), Comments.end(), + BeforeThanCompare<RawComment>(SourceMgr)); Context.Comments.addDeserializedComments(Comments); } } @@ -8350,16 +8554,14 @@ void ASTReader::finishPendingActions() { for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs; ++IDIdx) { const PendingMacroInfo &Info = GlobalIDs[IDIdx]; - if (Info.M->Kind != MK_ImplicitModule && - Info.M->Kind != MK_ExplicitModule) + if (!Info.M->isModule()) resolvePendingMacro(II, Info); } // Handle module imports. for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs; ++IDIdx) { const PendingMacroInfo &Info = GlobalIDs[IDIdx]; - if (Info.M->Kind == MK_ImplicitModule || - Info.M->Kind == MK_ExplicitModule) + if (Info.M->isModule()) resolvePendingMacro(II, Info); } } @@ -8390,7 +8592,7 @@ void ASTReader::finishPendingActions() { // 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 + // that all redeclarations point to the definitions. Note that this can only // happen now, after the redeclaration chains have been fully wired. for (Decl *D : PendingDefinitions) { if (TagDecl *TD = dyn_cast<TagDecl>(D)) { @@ -8446,8 +8648,11 @@ void ASTReader::finishPendingActions() { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) { // FIXME: Check for =delete/=default? // FIXME: Complain about ODR violations here? - if (!getContext().getLangOpts().Modules || !FD->hasBody()) + const FunctionDecl *Defn = nullptr; + if (!getContext().getLangOpts().Modules || !FD->hasBody(Defn)) FD->setLazyBody(PB->second); + else + mergeDefinitionVisibility(const_cast<FunctionDecl*>(Defn), FD); continue; } @@ -8542,7 +8747,7 @@ 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); @@ -8617,7 +8822,7 @@ void ASTReader::diagnoseOdrViolations() { } void ASTReader::StartedDeserializing() { - if (++NumCurrentElementsDeserializing == 1 && ReadTimer.get()) + if (++NumCurrentElementsDeserializing == 1 && ReadTimer.get()) ReadTimer->startTimer(); } @@ -8694,7 +8899,10 @@ ASTReader::ASTReader( bool AllowConfigurationMismatch, bool ValidateSystemInputs, bool UseGlobalIndex, std::unique_ptr<llvm::Timer> ReadTimer) - : Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr), + : Listener(DisableValidation ? + cast<ASTReaderListener>(new SimpleASTReaderListener(PP)) : + cast<ASTReaderListener>(new PCHValidator(PP, *this))), + DeserializationListener(nullptr), OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context), @@ -8743,3 +8951,10 @@ ASTReader::~ASTReader() { IdentifierResolver &ASTReader::getIdResolver() { return SemaObj ? SemaObj->IdResolver : DummyIdResolver; } + +unsigned ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor, + unsigned AbbrevID) { + Idx = 0; + Record.clear(); + return Cursor.readRecord(AbbrevID, Record); +} |