diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp | 1317 |
1 files changed, 862 insertions, 455 deletions
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp index 490b8cb10a48..2d8f5a801f0e 100644 --- a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp +++ b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp @@ -31,7 +31,7 @@ #include "clang/AST/ExternalASTSource.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/ODRDiagsEmitter.h" -#include "clang/AST/ODRHash.h" +#include "clang/AST/OpenACCClause.h" #include "clang/AST/OpenMPClause.h" #include "clang/AST/RawCommentList.h" #include "clang/AST/TemplateBase.h" @@ -40,9 +40,11 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeLocVisitor.h" #include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Basic/CommentOptions.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticError.h" +#include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/ExceptionSpecificationType.h" @@ -53,6 +55,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/OpenACCKinds.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/PragmaKinds.h" @@ -76,6 +79,8 @@ #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Scope.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaCUDA.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/Weak.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTDeserializationListener.h" @@ -827,36 +832,37 @@ bool SimpleASTReaderListener::ReadPreprocessorOptions( OptionValidateNone); } -/// Check the header search options deserialized from the control block -/// against the header search options in an existing preprocessor. +/// Check that the specified and the existing module cache paths are equivalent. /// /// \param Diags If non-null, produce diagnostics for any mismatches incurred. -static bool checkHeaderSearchOptions(const HeaderSearchOptions &HSOpts, - StringRef SpecificModuleCachePath, - StringRef ExistingModuleCachePath, - DiagnosticsEngine *Diags, - const LangOptions &LangOpts, - const PreprocessorOptions &PPOpts) { - if (LangOpts.Modules) { - if (SpecificModuleCachePath != ExistingModuleCachePath && - !PPOpts.AllowPCHWithDifferentModulesCachePath) { - if (Diags) - Diags->Report(diag::err_pch_modulecache_mismatch) - << SpecificModuleCachePath << ExistingModuleCachePath; - return true; - } - } - - return false; +/// \returns true when the module cache paths differ. +static bool checkModuleCachePath(llvm::vfs::FileSystem &VFS, + StringRef SpecificModuleCachePath, + StringRef ExistingModuleCachePath, + DiagnosticsEngine *Diags, + const LangOptions &LangOpts, + const PreprocessorOptions &PPOpts) { + if (!LangOpts.Modules || PPOpts.AllowPCHWithDifferentModulesCachePath || + SpecificModuleCachePath == ExistingModuleCachePath) + return false; + auto EqualOrErr = + VFS.equivalent(SpecificModuleCachePath, ExistingModuleCachePath); + if (EqualOrErr && *EqualOrErr) + return false; + if (Diags) + Diags->Report(diag::err_pch_modulecache_mismatch) + << SpecificModuleCachePath << ExistingModuleCachePath; + return true; } bool PCHValidator::ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath, bool Complain) { - return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath, - PP.getHeaderSearchInfo().getModuleCachePath(), - Complain ? &Reader.Diags : nullptr, - PP.getLangOpts(), PP.getPreprocessorOpts()); + return checkModuleCachePath(Reader.getFileManager().getVirtualFileSystem(), + SpecificModuleCachePath, + PP.getHeaderSearchInfo().getModuleCachePath(), + Complain ? &Reader.Diags : nullptr, + PP.getLangOpts(), PP.getPreprocessorOpts()); } void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) { @@ -902,6 +908,39 @@ unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) { return serialization::ComputeHash(Sel); } +LocalDeclID LocalDeclID::get(ASTReader &Reader, ModuleFile &MF, DeclID Value) { + LocalDeclID ID(Value); +#ifndef NDEBUG + if (!MF.ModuleOffsetMap.empty()) + Reader.ReadModuleOffsetMap(MF); + + unsigned ModuleFileIndex = ID.getModuleFileIndex(); + unsigned LocalDeclID = ID.getLocalDeclIndex(); + + assert(ModuleFileIndex <= MF.TransitiveImports.size()); + + ModuleFile *OwningModuleFile = + ModuleFileIndex == 0 ? &MF : MF.TransitiveImports[ModuleFileIndex - 1]; + assert(OwningModuleFile); + + unsigned LocalNumDecls = OwningModuleFile->LocalNumDecls; + + if (!ModuleFileIndex) + LocalNumDecls += NUM_PREDEF_DECL_IDS; + + assert(LocalDeclID < LocalNumDecls); +#endif + (void)Reader; + (void)MF; + return ID; +} + +LocalDeclID LocalDeclID::get(ASTReader &Reader, ModuleFile &MF, + unsigned ModuleFileIndex, unsigned LocalDeclID) { + DeclID Value = (DeclID)ModuleFileIndex << 32 | (DeclID)LocalDeclID; + return LocalDeclID::get(Reader, MF, Value); +} + std::pair<unsigned, unsigned> ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) { return readULEBKeyDataLength(d); @@ -912,20 +951,19 @@ ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) { using namespace llvm::support; SelectorTable &SelTable = Reader.getContext().Selectors; - unsigned N = - endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d); - IdentifierInfo *FirstII = Reader.getLocalIdentifier( - F, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)); + unsigned N = endian::readNext<uint16_t, llvm::endianness::little>(d); + const IdentifierInfo *FirstII = Reader.getLocalIdentifier( + F, endian::readNext<IdentifierID, llvm::endianness::little>(d)); if (N == 0) return SelTable.getNullarySelector(FirstII); else if (N == 1) return SelTable.getUnarySelector(FirstII); - SmallVector<IdentifierInfo *, 16> Args; + SmallVector<const IdentifierInfo *, 16> Args; Args.push_back(FirstII); for (unsigned I = 1; I != N; ++I) Args.push_back(Reader.getLocalIdentifier( - F, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d))); + F, endian::readNext<IdentifierID, llvm::endianness::little>(d))); return SelTable.getSelector(N, Args.data()); } @@ -938,11 +976,11 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, data_type Result; Result.ID = Reader.getGlobalSelectorID( - F, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)); + F, endian::readNext<uint32_t, llvm::endianness::little>(d)); unsigned FullInstanceBits = - endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d); + endian::readNext<uint16_t, llvm::endianness::little>(d); unsigned FullFactoryBits = - endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d); + endian::readNext<uint16_t, llvm::endianness::little>(d); Result.InstanceBits = FullInstanceBits & 0x3; Result.InstanceHasMoreThanOneDecl = (FullInstanceBits >> 2) & 0x1; Result.FactoryBits = FullFactoryBits & 0x3; @@ -953,16 +991,18 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, // Load instance methods for (unsigned I = 0; I != NumInstanceMethods; ++I) { if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>( - F, - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d))) + F, LocalDeclID::get( + Reader, F, + endian::readNext<DeclID, llvm::endianness::little>(d)))) Result.Instance.push_back(Method); } // Load factory methods for (unsigned I = 0; I != NumFactoryMethods; ++I) { if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>( - F, - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d))) + F, LocalDeclID::get( + Reader, F, + endian::readNext<DeclID, llvm::endianness::little>(d)))) Result.Factory.push_back(Method); } @@ -985,11 +1025,14 @@ ASTIdentifierLookupTraitBase::ReadKey(const unsigned char* d, unsigned n) { } /// Whether the given identifier is "interesting". -static bool isInterestingIdentifier(ASTReader &Reader, IdentifierInfo &II, +static bool isInterestingIdentifier(ASTReader &Reader, const IdentifierInfo &II, bool IsModule) { + bool IsInteresting = + II.getNotableIdentifierID() != tok::NotableIdentifierKind::not_notable || + II.getBuiltinID() != Builtin::ID::NotBuiltin || + II.getObjCKeywordID() != tok::ObjCKeywordKind::objc_not_keyword; return II.hadMacroDefinition() || II.isPoisoned() || - (!IsModule && II.getObjCOrBuiltinID()) || - II.hasRevertedTokenIDToIdentifier() || + (!IsModule && IsInteresting) || II.hasRevertedTokenIDToIdentifier() || (!(IsModule && Reader.getPreprocessor().getLangOpts().CPlusPlus) && II.getFETokenInfo()); } @@ -1000,11 +1043,11 @@ static bool readBit(unsigned &Bits) { return Value; } -IdentID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) { +IdentifierID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) { using namespace llvm::support; - unsigned RawID = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d); + IdentifierID RawID = + endian::readNext<IdentifierID, llvm::endianness::little>(d); return Reader.getGlobalIdentifierID(F, RawID >> 1); } @@ -1022,10 +1065,12 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, unsigned DataLen) { using namespace llvm::support; - unsigned RawID = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d); + IdentifierID RawID = + endian::readNext<IdentifierID, llvm::endianness::little>(d); bool IsInteresting = RawID & 0x01; + DataLen -= sizeof(IdentifierID); + // Wipe out the "is interesting" bit. RawID = RawID >> 1; @@ -1038,7 +1083,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, markIdentifierFromAST(Reader, *II); Reader.markIdentifierUpToDate(II); - IdentID ID = Reader.getGlobalIdentifierID(F, RawID); + IdentifierID ID = Reader.getGlobalIdentifierID(F, RawID); if (!IsInteresting) { // For uninteresting identifiers, there's nothing else to do. Just notify // the reader that we've finished loading this identifier. @@ -1047,9 +1092,8 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, } unsigned ObjCOrBuiltinID = - endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d); - unsigned Bits = - endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d); + endian::readNext<uint16_t, llvm::endianness::little>(d); + unsigned Bits = endian::readNext<uint16_t, llvm::endianness::little>(d); bool CPlusPlusOperatorKeyword = readBit(Bits); bool HasRevertedTokenIDToIdentifier = readBit(Bits); bool Poisoned = readBit(Bits); @@ -1057,7 +1101,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, bool HadMacroDefinition = readBit(Bits); assert(Bits == 0 && "Extra bits in the identifier?"); - DataLen -= 8; + DataLen -= sizeof(uint16_t) * 2; // Set or check the various bits in the IdentifierInfo structure. // Token IDs are read-only. @@ -1078,7 +1122,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, // definition. if (HadMacroDefinition) { uint32_t MacroDirectivesOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d); + endian::readNext<uint32_t, llvm::endianness::little>(d); DataLen -= 4; Reader.addPendingMacro(II, &F, MacroDirectivesOffset); @@ -1089,11 +1133,12 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, // Read all of the declarations visible at global scope with this // name. if (DataLen > 0) { - SmallVector<uint32_t, 4> DeclIDs; - for (; DataLen > 0; DataLen -= 4) + SmallVector<GlobalDeclID, 4> DeclIDs; + for (; DataLen > 0; DataLen -= sizeof(DeclID)) DeclIDs.push_back(Reader.getGlobalDeclID( - F, - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d))); + F, LocalDeclID::get( + Reader, F, + endian::readNext<DeclID, llvm::endianness::little>(d)))); Reader.SetGloballyVisibleDecls(II, DeclIDs); } @@ -1155,7 +1200,7 @@ unsigned DeclarationNameKey::getHash() const { break; } - return ID.ComputeHash(); + return ID.computeStableHash(); } ModuleFile * @@ -1163,7 +1208,7 @@ ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) { using namespace llvm::support; uint32_t ModuleFileID = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d); + endian::readNext<uint32_t, llvm::endianness::little>(d); return Reader.getLocalModuleFile(F, ModuleFileID); } @@ -1183,18 +1228,15 @@ ASTDeclContextNameLookupTrait::ReadKey(const unsigned char *d, unsigned) { case DeclarationName::CXXLiteralOperatorName: case DeclarationName::CXXDeductionGuideName: Data = (uint64_t)Reader.getLocalIdentifier( - F, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)); + F, endian::readNext<IdentifierID, llvm::endianness::little>(d)); break; case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: - Data = - (uint64_t)Reader - .getLocalSelector( - F, - endian::readNext<uint32_t, llvm::endianness::little, unaligned>( - d)) - .getAsOpaquePtr(); + Data = (uint64_t)Reader + .getLocalSelector( + F, endian::readNext<uint32_t, llvm::endianness::little>(d)) + .getAsOpaquePtr(); break; case DeclarationName::CXXOperatorName: Data = *d++; // OverloadedOperatorKind @@ -1216,10 +1258,10 @@ void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type, data_type_builder &Val) { using namespace llvm::support; - for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls) { - uint32_t LocalID = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d); - Val.insert(Reader.getGlobalDeclID(F, LocalID)); + for (unsigned NumDecls = DataLen / sizeof(DeclID); NumDecls; --NumDecls) { + LocalDeclID ID = LocalDeclID::get( + Reader, F, endian::readNext<DeclID, llvm::endianness::little>(d)); + Val.insert(Reader.getGlobalDeclID(F, ID)); } } @@ -1265,9 +1307,8 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M, if (!Lex.first) { Lex = std::make_pair( &M, llvm::ArrayRef( - reinterpret_cast<const llvm::support::unaligned_uint32_t *>( - Blob.data()), - Blob.size() / 4)); + reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()), + Blob.size() / sizeof(DeclID))); } DC->setHasExternalLexicalStorage(true); return false; @@ -1276,7 +1317,7 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M, bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M, BitstreamCursor &Cursor, uint64_t Offset, - DeclID ID) { + GlobalDeclID ID) { assert(Offset != 0); SavedStreamPosition SavedPosition(Cursor); @@ -1651,15 +1692,14 @@ bool ASTReader::ReadSLocEntry(int ID) { FileCharacter = (SrcMgr::CharacteristicKind)Record[2]; FileID FID = SourceMgr.createFileID(*File, IncludeLoc, FileCharacter, ID, BaseOffset + Record[0]); - SrcMgr::FileInfo &FileInfo = - const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile()); + SrcMgr::FileInfo &FileInfo = SourceMgr.getSLocEntry(FID).getFile(); FileInfo.NumCreatedFIDs = Record[5]; if (Record[3]) FileInfo.setHasLineDirectives(); unsigned NumFileDecls = Record[7]; if (NumFileDecls && ContextObj) { - const DeclID *FirstDecl = F->FileSortedDecls + Record[6]; + const unaligned_decl_id_t *FirstDecl = F->FileSortedDecls + Record[6]; assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?"); FileDeclIDs[FID] = FileDeclsInfo(F, llvm::ArrayRef(FirstDecl, NumFileDecls)); @@ -1695,8 +1735,7 @@ bool ASTReader::ReadSLocEntry(int ID) { FileID FID = SourceMgr.createFileID(std::move(Buffer), FileCharacter, ID, BaseOffset + Offset, IncludeLoc); if (Record[3]) { - auto &FileInfo = - const_cast<SrcMgr::FileInfo &>(SourceMgr.getSLocEntry(FID).getFile()); + auto &FileInfo = SourceMgr.getSLocEntry(FID).getFile(); FileInfo.setHasLineDirectives(); } break; @@ -1993,7 +2032,10 @@ const FileEntry *HeaderFileInfoTrait::getFile(const internal_key_type &Key) { } unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) { - return llvm::hash_combine(ikey.Size, ikey.ModTime); + uint8_t buf[sizeof(ikey.Size) + sizeof(ikey.ModTime)]; + memcpy(buf, &ikey.Size, sizeof(ikey.Size)); + memcpy(buf + sizeof(ikey.Size), &ikey.ModTime, sizeof(ikey.ModTime)); + return llvm::xxh3_64bits(buf); } HeaderFileInfoTrait::internal_key_type @@ -2027,10 +2069,9 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) { using namespace llvm::support; internal_key_type ikey; - ikey.Size = - off_t(endian::readNext<uint64_t, llvm::endianness::little, unaligned>(d)); - ikey.ModTime = time_t( - endian::readNext<uint64_t, llvm::endianness::little, unaligned>(d)); + ikey.Size = off_t(endian::readNext<uint64_t, llvm::endianness::little>(d)); + ikey.ModTime = + time_t(endian::readNext<uint64_t, llvm::endianness::little>(d)); ikey.Filename = (const char *)d; ikey.Imported = true; return ikey; @@ -2057,10 +2098,10 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, HFI.isPragmaOnce |= (Flags >> 4) & 0x01; HFI.DirInfo = (Flags >> 1) & 0x07; HFI.IndexHeaderMapHeader = Flags & 0x01; - HFI.ControllingMacroID = Reader.getGlobalIdentifierID( - M, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)); + HFI.LazyControllingMacro = Reader.getGlobalIdentifierID( + M, endian::readNext<IdentifierID, llvm::endianness::little>(d)); if (unsigned FrameworkOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)) { + endian::readNext<uint32_t, llvm::endianness::little>(d)) { // 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); @@ -2071,7 +2112,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, "Wrong data length in HeaderFileInfo deserialization"); while (d != End) { uint32_t LocalSMID = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d); + endian::readNext<uint32_t, llvm::endianness::little>(d); auto HeaderRole = static_cast<ModuleMap::ModuleHeaderRole>(LocalSMID & 7); LocalSMID >>= 3; @@ -2091,7 +2132,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, Module::Header H = {std::string(key.Filename), "", *FE}; ModMap.addHeader(Mod, H, HeaderRole, /*Imported=*/true); } - HFI.isModuleHeader |= ModuleMap::isModular(HeaderRole); + HFI.mergeModuleMembership(HeaderRole); } // This HeaderFileInfo was externally loaded. @@ -2224,7 +2265,7 @@ namespace { } // namespace -void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) { +void ASTReader::updateOutOfDateIdentifier(const IdentifierInfo &II) { // Note that we are loading an identifier. Deserializing AnIdentifier(this); @@ -2249,11 +2290,11 @@ void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) { markIdentifierUpToDate(&II); } -void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) { +void ASTReader::markIdentifierUpToDate(const IdentifierInfo *II) { if (!II) return; - II->setOutOfDate(false); + const_cast<IdentifierInfo *>(II)->setOutOfDate(false); // Update the generation for this identifier. if (getContext().getLangOpts().Modules) @@ -2587,7 +2628,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { "We should only check the content of the inputs with " "ValidateASTInputFilesContent enabled."); - if (StoredContentHash == static_cast<uint64_t>(llvm::hash_code(-1))) + if (StoredContentHash == 0) return OriginalChange; auto MemBuffOrError = FileMgr.getBufferForFile(*File); @@ -2601,8 +2642,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { return OriginalChange; } - // FIXME: hash_value is not guaranteed to be stable! - auto ContentHash = hash_value(MemBuffOrError.get()->getBuffer()); + auto ContentHash = xxh3_64bits(MemBuffOrError.get()->getBuffer()); if (StoredContentHash == static_cast<uint64_t>(ContentHash)) return Change{Change::None}; @@ -2635,6 +2675,14 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { F.StandardCXXModule && FileChange.Kind == Change::None) FileChange = HasInputContentChanged(FileChange); + // When we have StoredTime equal to zero and ValidateASTInputFilesContent, + // it is better to check the content of the input files because we cannot rely + // on the file modification time, which will be the same (zero) for these + // files. + if (!StoredTime && ValidateASTInputFilesContent && + FileChange.Kind == Change::None) + FileChange = HasInputContentChanged(FileChange); + // For an overridden file, there is nothing to validate. if (!Overridden && FileChange.Kind != Change::None) { if (Complain && !Diags.isDiagnosticInFlight()) { @@ -3035,8 +3083,10 @@ ASTReader::ReadControlBlock(ModuleFile &F, // The import location will be the local one for now; we will adjust // all import locations of module imports after the global source // location info are setup, in ReadAST. - SourceLocation ImportLoc = + auto [ImportLoc, ImportModuleFileIndex] = ReadUntranslatedSourceLocation(Record[Idx++]); + // The import location must belong to the current module file itself. + assert(ImportModuleFileIndex == 0); off_t StoredSize = !IsImportingStdCXXModule ? (off_t)Record[Idx++] : 0; time_t StoredModTime = !IsImportingStdCXXModule ? (time_t)Record[Idx++] : 0; @@ -3344,22 +3394,13 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, return llvm::createStringError( std::errc::illegal_byte_sequence, "duplicate TYPE_OFFSET record in AST file"); - F.TypeOffsets = reinterpret_cast<const UnderalignedInt64 *>(Blob.data()); + F.TypeOffsets = reinterpret_cast<const UnalignedUInt64 *>(Blob.data()); 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, - F.BaseTypeIndex - LocalBaseTypeIndex)); - + if (F.LocalNumTypes > 0) TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes); - } + break; } @@ -3370,35 +3411,19 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, "duplicate DECL_OFFSET record in AST file"); F.DeclOffsets = (const DeclOffset *)Blob.data(); F.LocalNumDecls = Record[0]; - unsigned LocalBaseDeclID = Record[1]; - F.BaseDeclID = getTotalNumDecls(); - - if (F.LocalNumDecls > 0) { - // 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; + F.BaseDeclIndex = getTotalNumDecls(); + if (F.LocalNumDecls > 0) DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls); - } + break; } case TU_UPDATE_LEXICAL: { DeclContext *TU = ContextObj->getTranslationUnitDecl(); LexicalContents Contents( - reinterpret_cast<const llvm::support::unaligned_uint32_t *>( - Blob.data()), - static_cast<unsigned int>(Blob.size() / 4)); + reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()), + static_cast<unsigned int>(Blob.size() / sizeof(DeclID))); TULexicalDecls.push_back(std::make_pair(&F, Contents)); TU->setHasExternalLexicalStorage(true); break; @@ -3406,7 +3431,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case UPDATE_VISIBLE: { unsigned Idx = 0; - serialization::DeclID ID = ReadDeclID(F, Record, Idx); + GlobalDeclID ID = ReadDeclID(F, Record, Idx); auto *Data = (const unsigned char*)Blob.data(); PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&F, Data}); // If we've already loaded the decl, perform the updates when we finish @@ -3438,24 +3463,11 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, "duplicate IDENTIFIER_OFFSET record in AST file"); F.IdentifierOffsets = (const uint32_t *)Blob.data(); 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, - &F)); - - // Introduce the local -> global mapping for identifiers within this - // module. - F.IdentifierRemap.insertOrReplace( - std::make_pair(LocalBaseIdentifierID, - F.BaseIdentifierID - LocalBaseIdentifierID)); - + if (F.LocalNumIdentifiers > 0) IdentifiersLoaded.resize(IdentifiersLoaded.size() + F.LocalNumIdentifiers); - } break; } @@ -3466,8 +3478,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case EAGERLY_DESERIALIZED_DECLS: // FIXME: Skip reading this record if our ASTConsumer doesn't care // about "interesting" decls (for instance, if we're building a module). - for (unsigned I = 0, N = Record.size(); I != N; ++I) - EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + EagerlyDeserializedDecls.push_back(ReadDeclID(F, Record, I)); break; case MODULAR_CODEGEN_DECLS: @@ -3475,8 +3487,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, // them (ie: if we're not codegenerating this module). if (F.Kind == MK_MainFile || getContext().getLangOpts().BuildingPCHWithObjectFile) - for (unsigned I = 0, N = Record.size(); I != N; ++I) - EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + EagerlyDeserializedDecls.push_back(ReadDeclID(F, Record, I)); break; case SPECIAL_TYPES: @@ -3507,13 +3519,13 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case UNUSED_FILESCOPED_DECLS: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + UnusedFileScopedDecls.push_back(ReadDeclID(F, Record, I)); break; case DELEGATING_CTORS: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + DelegatingCtorDecls.push_back(ReadDeclID(F, Record, I)); break; case WEAK_UNDECLARED_IDENTIFIERS: @@ -3588,6 +3600,17 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; } + case PP_UNSAFE_BUFFER_USAGE: { + if (!Record.empty()) { + SmallVector<SourceLocation, 64> SrcLocs; + unsigned Idx = 0; + while (Idx < Record.size()) + SrcLocs.push_back(ReadSourceLocation(F, Record, Idx)); + PP.setDeserializedSafeBufferOptOutMap(SrcLocs); + } + break; + } + case PP_CONDITIONAL_STACK: if (!Record.empty()) { unsigned Idx = 0, End = Record.size() - 1; @@ -3621,7 +3644,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case FILE_SORTED_DECLS: - F.FileSortedDecls = (const DeclID *)Blob.data(); + F.FileSortedDecls = (const unaligned_decl_id_t *)Blob.data(); F.NumFileSortedDecls = Record[0]; break; @@ -3655,13 +3678,6 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset - SLocSpaceSize,&F)); - // Initialize the remapping table. - // Invalid stays invalid. - F.SLocRemap.insertOrReplace(std::make_pair(0U, 0)); - // This module. Base was 2 when being compiled. - F.SLocRemap.insertOrReplace(std::make_pair( - 2U, static_cast<SourceLocation::IntTy>(F.SLocEntryBaseOffset - 2))); - TotalNumSLocEntries += F.LocalNumSLocEntries; break; } @@ -3675,8 +3691,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case EXT_VECTOR_DECLS: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + ExtVectorDecls.push_back(ReadDeclID(F, Record, I)); break; case VTABLE_USES: @@ -3690,18 +3706,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, VTableUses.clear(); for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) { - VTableUses.push_back(getGlobalDeclID(F, Record[Idx++])); VTableUses.push_back( - ReadSourceLocation(F, Record, Idx).getRawEncoding()); - VTableUses.push_back(Record[Idx++]); + {ReadDeclID(F, Record, Idx), + ReadSourceLocation(F, Record, Idx).getRawEncoding(), + (bool)Record[Idx++]}); } break; case PENDING_IMPLICIT_INSTANTIATIONS: - if (PendingInstantiations.size() % 2 != 0) - return llvm::createStringError( - std::errc::illegal_byte_sequence, - "Invalid existing PendingInstantiations"); if (Record.size() % 2 != 0) return llvm::createStringError( @@ -3709,9 +3721,9 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, "Invalid PENDING_IMPLICIT_INSTANTIATIONS block"); for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) { - PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++])); PendingInstantiations.push_back( - ReadSourceLocation(F, Record, I).getRawEncoding()); + {ReadDeclID(F, Record, I), + ReadSourceLocation(F, Record, I).getRawEncoding()}); } break; @@ -3719,8 +3731,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, if (Record.size() != 3) return llvm::createStringError(std::errc::illegal_byte_sequence, "Invalid SEMA_DECL_REFS block"); - for (unsigned I = 0, N = Record.size(); I != N; ++I) - SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + SemaDeclRefs.push_back(ReadDeclID(F, Record, I)); break; case PPD_ENTITIES_OFFSETS: { @@ -3778,9 +3790,9 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, return llvm::createStringError( std::errc::illegal_byte_sequence, "invalid DECL_UPDATE_OFFSETS block in AST file"); - for (unsigned I = 0, N = Record.size(); I != N; I += 2) { - GlobalDeclID ID = getGlobalDeclID(F, Record[I]); - DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) { + GlobalDeclID ID = ReadDeclID(F, Record, I); + DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I++])); // If we've already loaded the decl, perform the updates when we finish // loading this block. @@ -3790,6 +3802,33 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, } break; + case DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD: { + if (Record.size() % 3 != 0) + return llvm::createStringError( + std::errc::illegal_byte_sequence, + "invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST " + "file"); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) { + GlobalDeclID ID = ReadDeclID(F, Record, I); + + uint64_t BaseOffset = F.DeclsBlockStartOffset; + assert(BaseOffset && "Invalid DeclsBlockStartOffset for module file!"); + uint64_t LocalLexicalOffset = Record[I++]; + uint64_t LexicalOffset = + LocalLexicalOffset ? BaseOffset + LocalLexicalOffset : 0; + uint64_t LocalVisibleOffset = Record[I++]; + uint64_t VisibleOffset = + LocalVisibleOffset ? BaseOffset + LocalVisibleOffset : 0; + + DelayedNamespaceOffsetMap[ID] = {LexicalOffset, VisibleOffset}; + + assert(!GetExistingDecl(ID) && + "We shouldn't load the namespace in the front of delayed " + "namespace lexical and visible block"); + } + break; + } + case OBJC_CATEGORIES_MAP: if (F.LocalNumObjCCategoriesInMap != 0) return llvm::createStringError( @@ -3808,8 +3847,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, // Later tables overwrite earlier ones. // FIXME: Modules will have trouble with this. CUDASpecialDeclRefs.clear(); - for (unsigned I = 0, N = Record.size(); I != N; ++I) - CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + CUDASpecialDeclRefs.push_back(ReadDeclID(F, Record, I)); break; case HEADER_SEARCH_TABLE: @@ -3849,33 +3888,29 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case TENTATIVE_DEFINITIONS: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + TentativeDefinitions.push_back(ReadDeclID(F, Record, I)); break; case KNOWN_NAMESPACES: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - KnownNamespaces.push_back(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + KnownNamespaces.push_back(ReadDeclID(F, Record, I)); break; case UNDEFINED_BUT_USED: - if (UndefinedButUsed.size() % 2 != 0) - return llvm::createStringError(std::errc::illegal_byte_sequence, - "Invalid existing UndefinedButUsed"); - if (Record.size() % 2 != 0) return llvm::createStringError(std::errc::illegal_byte_sequence, "invalid undefined-but-used record"); for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) { - UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++])); UndefinedButUsed.push_back( - ReadSourceLocation(F, Record, I).getRawEncoding()); + {ReadDeclID(F, Record, I), + ReadSourceLocation(F, Record, I).getRawEncoding()}); } break; case DELETE_EXPRS_TO_ANALYZE: for (unsigned I = 0, N = Record.size(); I != N;) { - DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++])); + DelayedDeleteExprs.push_back(ReadDeclID(F, Record, I).getRawValue()); const uint64_t Count = Record[I++]; DelayedDeleteExprs.push_back(Count); for (uint64_t C = 0; C < Count; ++C) { @@ -3886,6 +3921,13 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, } break; + case VTABLES_TO_EMIT: + if (F.Kind == MK_MainFile || + getContext().getLangOpts().BuildingPCHWithObjectFile) + for (unsigned I = 0, N = Record.size(); I != N;) + VTablesToEmit.push_back(ReadDeclID(F, Record, I)); + break; + case IMPORTED_MODULES: if (!F.isModule()) { // If we aren't loading a module (which has its own exports), make @@ -3958,16 +4000,15 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - UnusedLocalTypedefNameCandidates.push_back( - getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + UnusedLocalTypedefNameCandidates.push_back(ReadDeclID(F, Record, I)); break; case CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH: if (Record.size() != 1) return llvm::createStringError(std::errc::illegal_byte_sequence, "invalid cuda pragma options record"); - ForceCUDAHostDeviceDepth = Record[0]; + ForceHostDeviceDepth = Record[0]; break; case ALIGN_PACK_PRAGMA_OPTIONS: { @@ -4015,8 +4056,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, } case DECLS_TO_CHECK_FOR_DEFERRED_DIAGS: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - DeclsToCheckForDeferredDiags.insert(getGlobalDeclID(F, Record[I])); + for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) + DeclsToCheckForDeferredDiags.insert(ReadDeclID(F, Record, I)); break; } } @@ -4030,25 +4071,14 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { const unsigned char *DataEnd = Data + F.ModuleOffsetMap.size(); F.ModuleOffsetMap = StringRef(); - // If we see this entry before SOURCE_LOCATION_OFFSETS, add placeholders. - if (F.SLocRemap.find(0) == F.SLocRemap.end()) { - F.SLocRemap.insert(std::make_pair(0U, 0)); - F.SLocRemap.insert(std::make_pair(2U, 1)); - } - - // Continuous range maps we may be updating in our module. - using SLocRemapBuilder = - ContinuousRangeMap<SourceLocation::UIntTy, SourceLocation::IntTy, - 2>::Builder; using RemapBuilder = ContinuousRangeMap<uint32_t, int, 2>::Builder; - SLocRemapBuilder SLocRemap(F.SLocRemap); - RemapBuilder IdentifierRemap(F.IdentifierRemap); RemapBuilder MacroRemap(F.MacroRemap); RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap); RemapBuilder SubmoduleRemap(F.SubmoduleRemap); RemapBuilder SelectorRemap(F.SelectorRemap); - RemapBuilder DeclRemap(F.DeclRemap); - RemapBuilder TypeRemap(F.TypeRemap); + + auto &ImportedModuleVector = F.TransitiveImports; + assert(ImportedModuleVector.empty()); while (Data < DataEnd) { // FIXME: Looking up dependency modules by filename is horrible. Let's @@ -4056,9 +4086,8 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { // how it goes... using namespace llvm::support; ModuleKind Kind = static_cast<ModuleKind>( - endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data)); - uint16_t Len = - endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data); + endian::readNext<uint8_t, llvm::endianness::little>(Data)); + uint16_t Len = endian::readNext<uint16_t, llvm::endianness::little>(Data); StringRef Name = StringRef((const char*)Data, Len); Data += Len; ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule || @@ -4066,29 +4095,22 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { ? ModuleMgr.lookupByModuleName(Name) : ModuleMgr.lookupByFileName(Name)); if (!OM) { - std::string Msg = - "SourceLocation remap refers to unknown module, cannot find "; + std::string Msg = "refers to unknown module, cannot find "; Msg.append(std::string(Name)); Error(Msg); return; } - SourceLocation::UIntTy SLocOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data); - uint32_t IdentifierIDOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data); + ImportedModuleVector.push_back(OM); + uint32_t MacroIDOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data); + endian::readNext<uint32_t, llvm::endianness::little>(Data); uint32_t PreprocessedEntityIDOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data); + endian::readNext<uint32_t, llvm::endianness::little>(Data); uint32_t SubmoduleIDOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data); + endian::readNext<uint32_t, llvm::endianness::little>(Data); uint32_t SelectorIDOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data); - uint32_t DeclIDOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data); - uint32_t TypeIndexOffset = - endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data); + endian::readNext<uint32_t, llvm::endianness::little>(Data); auto mapOffset = [&](uint32_t Offset, uint32_t BaseOffset, RemapBuilder &Remap) { @@ -4098,24 +4120,11 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { static_cast<int>(BaseOffset - Offset))); }; - constexpr SourceLocation::UIntTy SLocNone = - std::numeric_limits<SourceLocation::UIntTy>::max(); - if (SLocOffset != SLocNone) - SLocRemap.insert(std::make_pair( - SLocOffset, static_cast<SourceLocation::IntTy>( - OM->SLocEntryBaseOffset - SLocOffset))); - - mapOffset(IdentifierIDOffset, OM->BaseIdentifierID, IdentifierRemap); mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap); mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID, PreprocessedEntityRemap); mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap); mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap); - mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap); - mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap); - - // Global -> local mappings. - F.GlobalToLocalDeclIDs[OM] = DeclIDOffset; } } @@ -4229,9 +4238,9 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, /// Move the given method to the back of the global list of methods. static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { // Find the entry for this selector in the method pool. - Sema::GlobalMethodPool::iterator Known - = S.MethodPool.find(Method->getSelector()); - if (Known == S.MethodPool.end()) + SemaObjC::GlobalMethodPool::iterator Known = + S.ObjC().MethodPool.find(Method->getSelector()); + if (Known == S.ObjC().MethodPool.end()) return; // Retrieve the appropriate method list. @@ -4641,8 +4650,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type, if (ContextObj) { for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) { loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), - ObjCClassesLoaded[I], - PreviousGeneration); + ObjCClassesLoaded[I], PreviousGeneration); } } @@ -4977,7 +4985,7 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( } case HEADER_SEARCH_PATHS: { bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; - if (!AllowCompatibleConfigurationMismatch && + if (Listener && !AllowCompatibleConfigurationMismatch && ParseHeaderSearchPaths(Record, Complain, *Listener)) Result = ConfigurationMismatch; break; @@ -4992,15 +5000,12 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( Record.begin(), Record.end()); break; case HEADER_SEARCH_ENTRY_USAGE: - if (!F) - break; - unsigned Count = Record[0]; - const char *Byte = Blob.data(); - F->SearchPathUsage = llvm::BitVector(Count, false); - for (unsigned I = 0; I < Count; ++Byte) - for (unsigned Bit = 0; Bit < 8 && I < Count; ++Bit, ++I) - if (*Byte & (1 << Bit)) - F->SearchPathUsage[I] = true; + if (F) + F->SearchPathUsage = ReadBitVector(Record, Blob); + break; + case VFS_USAGE: + if (F) + F->VFSUsage = ReadBitVector(Record, Blob); break; } } @@ -5089,20 +5094,21 @@ 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, - Context.getTranslationUnitDecl()); + DeserializationListener->DeclRead( + GlobalDeclID(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 (TypeID String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) { if (!Context.CFConstantStringTypeDecl) Context.setCFConstantStringType(GetType(String)); } - if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) { + if (TypeID File = SpecialTypes[SPECIAL_TYPE_FILE]) { QualType FileType = GetType(File); if (FileType.isNull()) { Error("FILE type is NULL"); @@ -5123,7 +5129,7 @@ void ASTReader::InitializeContext() { } } - if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) { + if (TypeID Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) { QualType Jmp_bufType = GetType(Jmp_buf); if (Jmp_bufType.isNull()) { Error("jmp_buf type is NULL"); @@ -5144,7 +5150,7 @@ void ASTReader::InitializeContext() { } } - if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) { + if (TypeID Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) { QualType Sigjmp_bufType = GetType(Sigjmp_buf); if (Sigjmp_bufType.isNull()) { Error("sigjmp_buf type is NULL"); @@ -5162,25 +5168,24 @@ void ASTReader::InitializeContext() { } } - if (unsigned ObjCIdRedef - = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) { + if (TypeID ObjCIdRedef = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) { if (Context.ObjCIdRedefinitionType.isNull()) Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef); } - if (unsigned ObjCClassRedef - = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) { + if (TypeID ObjCClassRedef = + SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) { if (Context.ObjCClassRedefinitionType.isNull()) Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef); } - if (unsigned ObjCSelRedef - = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) { + if (TypeID ObjCSelRedef = + SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) { if (Context.ObjCSelRedefinitionType.isNull()) Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef); } - if (unsigned Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) { + if (TypeID Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) { QualType Ucontext_tType = GetType(Ucontext_t); if (Ucontext_tType.isNull()) { Error("ucontext_t type is NULL"); @@ -5376,9 +5381,9 @@ namespace { bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath, bool Complain) override { - return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath, - ExistingModuleCachePath, nullptr, - ExistingLangOpts, ExistingPPOpts); + return checkModuleCachePath( + FileMgr.getVirtualFileSystem(), SpecificModuleCachePath, + ExistingModuleCachePath, nullptr, ExistingLangOpts, ExistingPPOpts); } bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, @@ -5398,7 +5403,8 @@ bool ASTReader::readASTFileControlBlock( StringRef Filename, FileManager &FileMgr, const InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, - ASTReaderListener &Listener, bool ValidateDiagnosticOptions) { + ASTReaderListener &Listener, bool ValidateDiagnosticOptions, + unsigned ClientLoadCapabilities) { // Open the AST file. std::unique_ptr<llvm::MemoryBuffer> OwnedBuffer; llvm::MemoryBuffer *Buffer = ModuleCache.lookupPCM(Filename); @@ -5453,7 +5459,7 @@ bool ASTReader::readASTFileControlBlock( switch (Entry.ID) { case OPTIONS_BLOCK_ID: { std::string IgnoredSuggestedPredefines; - if (ReadOptionsBlock(Stream, ARR_ConfigurationMismatch | ARR_OutOfDate, + if (ReadOptionsBlock(Stream, ClientLoadCapabilities, /*AllowCompatibleConfigurationMismatch*/ false, Listener, IgnoredSuggestedPredefines) != Success) return true; @@ -5679,7 +5685,7 @@ bool ASTReader::readASTFileControlBlock( // Scan for the UNHASHED_CONTROL_BLOCK_ID block. if (readUnhashedControlBlockImpl( - nullptr, Bytes, ARR_ConfigurationMismatch | ARR_OutOfDate, + nullptr, Bytes, ClientLoadCapabilities, /*AllowCompatibleConfigurationMismatch*/ false, &Listener, ValidateDiagnosticOptions) != Success) return true; @@ -5997,9 +6003,9 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F, case SUBMODULE_INITIALIZERS: { if (!ContextObj) break; - SmallVector<uint32_t, 16> Inits; - for (auto &ID : Record) - Inits.push_back(getGlobalDeclID(F, ID)); + SmallVector<GlobalDeclID, 16> Inits; + for (unsigned I = 0; I < Record.size(); /*in loop*/) + Inits.push_back(ReadDeclID(F, Record, I)); ContextObj->addLazyModuleInitializers(CurrentModule, Inits); break; } @@ -6242,8 +6248,8 @@ SourceRange ASTReader::ReadSkippedRange(unsigned GlobalIndex) { unsigned LocalIndex = GlobalIndex - M->BasePreprocessedSkippedRangeID; assert(LocalIndex < M->NumPreprocessedSkippedRanges); PPSkippedRange RawRange = M->PreprocessedSkippedRangeOffsets[LocalIndex]; - SourceRange Range(TranslateSourceLocation(*M, RawRange.getBegin()), - TranslateSourceLocation(*M, RawRange.getEnd())); + SourceRange Range(ReadSourceLocation(*M, RawRange.getBegin()), + ReadSourceLocation(*M, RawRange.getEnd())); assert(Range.isValid()); return Range; } @@ -6262,7 +6268,7 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor); if (llvm::Error Err = M.PreprocessorDetailCursor.JumpToBit( - M.MacroOffsetsBase + PPOffs.BitOffset)) { + M.MacroOffsetsBase + PPOffs.getOffset())) { Error(std::move(Err)); return nullptr; } @@ -6279,8 +6285,8 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { return nullptr; // Read the record. - SourceRange Range(TranslateSourceLocation(M, PPOffs.getBegin()), - TranslateSourceLocation(M, PPOffs.getEnd())); + SourceRange Range(ReadSourceLocation(M, PPOffs.getBegin()), + ReadSourceLocation(M, PPOffs.getEnd())); PreprocessingRecord &PPRec = *PP.getPreprocessingRecord(); StringRef Blob; RecordData Record; @@ -6392,7 +6398,7 @@ struct PPEntityComp { } SourceLocation getLoc(const PPEntityOffset &PPE) const { - return Reader.TranslateSourceLocation(M, PPE.getBegin()); + return Reader.ReadSourceLocation(M, PPE.getBegin()); } }; @@ -6436,7 +6442,7 @@ PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc, PPI = First; std::advance(PPI, Half); if (SourceMgr.isBeforeInTranslationUnit( - TranslateSourceLocation(M, PPI->getEnd()), Loc)) { + ReadSourceLocation(M, PPI->getEnd()), Loc)) { First = PPI; ++First; Count = Count - Half - 1; @@ -6477,7 +6483,7 @@ std::optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index, unsigned LocalIndex = PPInfo.second; const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex]; - SourceLocation Loc = TranslateSourceLocation(M, PPOffs.getBegin()); + SourceLocation Loc = ReadSourceLocation(M, PPOffs.getBegin()); if (Loc.isInvalid()) return false; @@ -6621,17 +6627,15 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) { while (NumLocations--) { assert(Idx < Record.size() && "Invalid data, missing pragma diagnostic states"); - SourceLocation Loc = ReadSourceLocation(F, Record[Idx++]); - auto IDAndOffset = SourceMgr.getDecomposedLoc(Loc); - assert(IDAndOffset.first.isValid() && "invalid FileID for transition"); - assert(IDAndOffset.second == 0 && "not a start location for a FileID"); + FileID FID = ReadFileID(F, Record, Idx); + assert(FID.isValid() && "invalid FileID for transition"); unsigned Transitions = Record[Idx++]; // Note that we don't need to set up Parent/ParentOffset here, because // we won't be changing the diagnostic state within imported FileIDs // (other than perhaps appending to the main source file, which has no // parent). - auto &F = Diag.DiagStatesByLoc.Files[IDAndOffset.first]; + auto &F = Diag.DiagStatesByLoc.Files[FID]; F.StateTransitions.reserve(F.StateTransitions.size() + Transitions); for (unsigned I = 0; I != Transitions; ++I) { unsigned Offset = Record[Idx++]; @@ -6666,13 +6670,10 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) { } /// Get the correct cursor and offset for loading a type. -ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) { - GlobalTypeMapType::iterator I = GlobalTypeMap.find(Index); - assert(I != GlobalTypeMap.end() && "Corrupted global type map"); - ModuleFile *M = I->second; - return RecordLocation( - M, M->TypeOffsets[Index - M->BaseTypeIndex].getBitOffset() + - M->DeclsBlockStartOffset); +ASTReader::RecordLocation ASTReader::TypeCursorForIndex(TypeID ID) { + auto [M, Index] = translateTypeIDToIndex(ID); + return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex].get() + + M->DeclsBlockStartOffset); } static std::optional<Type::TypeClass> getTypeClassForCode(TypeCode code) { @@ -6691,10 +6692,10 @@ static std::optional<Type::TypeClass> getTypeClassForCode(TypeCode code) { /// routine actually reads the record corresponding to the type at the given /// location. It is a helper routine for GetType, which deals with reading type /// IDs. -QualType ASTReader::readTypeRecord(unsigned Index) { +QualType ASTReader::readTypeRecord(TypeID ID) { assert(ContextObj && "reading type with no AST context"); ASTContext &Context = *ContextObj; - RecordLocation Loc = TypeCursorForIndex(Index); + RecordLocation Loc = TypeCursorForIndex(ID); BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor; // Keep track of where we are in the stream, then jump back there @@ -6809,6 +6810,10 @@ void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { // nothing to do } +void TypeLocReader::VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) { + // nothing to do +} + void TypeLocReader::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { TL.setExpansionLoc(readSourceLocation()); } @@ -6946,6 +6951,10 @@ void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { TL.setRParenLoc(readSourceLocation()); } +void TypeLocReader::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) { + TL.setEllipsisLoc(readSourceLocation()); +} + void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { TL.setKWLoc(readSourceLocation()); TL.setLParenLoc(readSourceLocation()); @@ -6990,6 +6999,10 @@ void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) { TL.setAttr(ReadAttr()); } +void TypeLocReader::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) { + // Nothing to do +} + void TypeLocReader::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { // Nothing to do. } @@ -7123,15 +7136,44 @@ TypeSourceInfo *ASTRecordReader::readTypeSourceInfo() { return TInfo; } +static unsigned getIndexForTypeID(serialization::TypeID ID) { + return (ID & llvm::maskTrailingOnes<TypeID>(32)) >> Qualifiers::FastWidth; +} + +static unsigned getModuleFileIndexForTypeID(serialization::TypeID ID) { + return ID >> 32; +} + +static bool isPredefinedType(serialization::TypeID ID) { + // We don't need to erase the higher bits since if these bits are not 0, + // it must be larger than NUM_PREDEF_TYPE_IDS. + return (ID >> Qualifiers::FastWidth) < NUM_PREDEF_TYPE_IDS; +} + +std::pair<ModuleFile *, unsigned> +ASTReader::translateTypeIDToIndex(serialization::TypeID ID) const { + assert(!isPredefinedType(ID) && + "Predefined type shouldn't be in TypesLoaded"); + unsigned ModuleFileIndex = getModuleFileIndexForTypeID(ID); + assert(ModuleFileIndex && "Untranslated Local Decl?"); + + ModuleFile *OwningModuleFile = &getModuleManager()[ModuleFileIndex - 1]; + assert(OwningModuleFile && + "untranslated type ID or local type ID shouldn't be in TypesLoaded"); + + return {OwningModuleFile, + OwningModuleFile->BaseTypeIndex + getIndexForTypeID(ID)}; +} + QualType ASTReader::GetType(TypeID ID) { assert(ContextObj && "reading type with no AST context"); ASTContext &Context = *ContextObj; unsigned FastQuals = ID & Qualifiers::FastMask; - unsigned Index = ID >> Qualifiers::FastWidth; - if (Index < NUM_PREDEF_TYPE_IDS) { + if (isPredefinedType(ID)) { QualType T; + unsigned Index = getIndexForTypeID(ID); switch ((PredefinedTypeIDs)Index) { case PREDEF_TYPE_LAST_ID: // We should never use this one. @@ -7288,6 +7330,9 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_OVERLOAD_ID: T = Context.OverloadTy; break; + case PREDEF_TYPE_UNRESOLVED_TEMPLATE: + T = Context.UnresolvedTemplateTy; + break; case PREDEF_TYPE_BOUND_MEMBER: T = Context.BoundMemberTy; break; @@ -7361,11 +7406,11 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_INCOMPLETE_MATRIX_IDX: T = Context.IncompleteMatrixIdxTy; break; - case PREDEF_TYPE_OMP_ARRAY_SECTION: - T = Context.OMPArraySectionTy; + case PREDEF_TYPE_ARRAY_SECTION: + T = Context.ArraySectionTy; break; case PREDEF_TYPE_OMP_ARRAY_SHAPING: - T = Context.OMPArraySectionTy; + T = Context.OMPArrayShapingTy; break; case PREDEF_TYPE_OMP_ITERATOR: T = Context.OMPIteratorTy; @@ -7390,16 +7435,22 @@ QualType ASTReader::GetType(TypeID ID) { T = Context.SingletonId; \ break; #include "clang/Basic/WebAssemblyReferenceTypes.def" +#define AMDGPU_TYPE(Name, Id, SingletonId) \ + case PREDEF_TYPE_##Id##_ID: \ + T = Context.SingletonId; \ + break; +#include "clang/Basic/AMDGPUTypes.def" } assert(!T.isNull() && "Unknown predefined type"); return T.withFastQualifiers(FastQuals); } - Index -= NUM_PREDEF_TYPE_IDS; + unsigned Index = translateTypeIDToIndex(ID).second; + assert(Index < TypesLoaded.size() && "Type index out-of-range"); if (TypesLoaded[Index].isNull()) { - TypesLoaded[Index] = readTypeRecord(Index); + TypesLoaded[Index] = readTypeRecord(ID); if (TypesLoaded[Index].isNull()) return QualType(); @@ -7412,27 +7463,28 @@ QualType ASTReader::GetType(TypeID ID) { return TypesLoaded[Index].withFastQualifiers(FastQuals); } -QualType ASTReader::getLocalType(ModuleFile &F, unsigned LocalID) { +QualType ASTReader::getLocalType(ModuleFile &F, LocalTypeID LocalID) { return GetType(getGlobalTypeID(F, LocalID)); } -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) +serialization::TypeID ASTReader::getGlobalTypeID(ModuleFile &F, + LocalTypeID LocalID) const { + if (isPredefinedType(LocalID)) return LocalID; if (!F.ModuleOffsetMap.empty()) ReadModuleOffsetMap(F); - 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 ModuleFileIndex = getModuleFileIndexForTypeID(LocalID); + LocalID &= llvm::maskTrailingOnes<TypeID>(32); + + if (ModuleFileIndex == 0) + LocalID -= NUM_PREDEF_TYPE_IDS << Qualifiers::FastWidth; - unsigned GlobalIndex = LocalIndex + I->second; - return (GlobalIndex << Qualifiers::FastWidth) | FastQuals; + ModuleFile &MF = + ModuleFileIndex ? *F.TransitiveImports[ModuleFileIndex - 1] : F; + ModuleFileIndex = MF.Index + 1; + return ((uint64_t)ModuleFileIndex << 32) | LocalID; } TemplateArgumentLocInfo @@ -7494,9 +7546,7 @@ ASTRecordReader::readASTTemplateArgumentListInfo() { return ASTTemplateArgumentListInfo::Create(getContext(), Result); } -Decl *ASTReader::GetExternalDecl(uint32_t ID) { - return GetDecl(ID); -} +Decl *ASTReader::GetExternalDecl(GlobalDeclID ID) { return GetDecl(ID); } void ASTReader::CompleteRedeclChain(const Decl *D) { if (NumCurrentElementsDeserializing) { @@ -7629,51 +7679,61 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { return Bases; } -serialization::DeclID -ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const { +GlobalDeclID ASTReader::getGlobalDeclID(ModuleFile &F, + LocalDeclID LocalID) const { if (LocalID < NUM_PREDEF_DECL_IDS) - return LocalID; + return GlobalDeclID(LocalID.getRawValue()); + + unsigned OwningModuleFileIndex = LocalID.getModuleFileIndex(); + DeclID ID = LocalID.getLocalDeclIndex(); if (!F.ModuleOffsetMap.empty()) ReadModuleOffsetMap(F); - 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"); + ModuleFile *OwningModuleFile = + OwningModuleFileIndex == 0 + ? &F + : F.TransitiveImports[OwningModuleFileIndex - 1]; - return LocalID + I->second; + if (OwningModuleFileIndex == 0) + ID -= NUM_PREDEF_DECL_IDS; + + uint64_t NewModuleFileIndex = OwningModuleFile->Index + 1; + return GlobalDeclID(NewModuleFileIndex, ID); } -bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID, - ModuleFile &M) const { +bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { // Predefined decls aren't from any module. if (ID < NUM_PREDEF_DECL_IDS) return false; - return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && - ID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls; + unsigned ModuleFileIndex = ID.getModuleFileIndex(); + return M.Index == ModuleFileIndex - 1; +} + +ModuleFile *ASTReader::getOwningModuleFile(GlobalDeclID ID) const { + // Predefined decls aren't from any module. + if (ID < NUM_PREDEF_DECL_IDS) + return nullptr; + + uint64_t ModuleFileIndex = ID.getModuleFileIndex(); + assert(ModuleFileIndex && "Untranslated Local Decl?"); + + return &getModuleManager()[ModuleFileIndex - 1]; } -ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) { +ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) const { if (!D->isFromASTFile()) return nullptr; - GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID()); - assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); - return I->second; + + return getOwningModuleFile(D->getGlobalID()); } SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { if (ID < NUM_PREDEF_DECL_IDS) return SourceLocation(); - unsigned Index = ID - NUM_PREDEF_DECL_IDS; - - if (Index > DeclsLoaded.size()) { - Error("declaration ID out-of-range for AST file"); - return SourceLocation(); - } - - if (Decl *D = DeclsLoaded[Index]) + if (Decl *D = GetExistingDecl(ID)) return D->getLocation(); SourceLocation Loc; @@ -7681,7 +7741,10 @@ SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { return Loc; } -static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { +Decl *ASTReader::getPredefinedDecl(PredefinedDeclIDs ID) { + assert(ContextObj && "reading predefined decl without AST context"); + ASTContext &Context = *ContextObj; + Decl *NewLoaded = nullptr; switch (ID) { case PREDEF_DECL_NULL_ID: return nullptr; @@ -7690,60 +7753,123 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { return Context.getTranslationUnitDecl(); case PREDEF_DECL_OBJC_ID_ID: - return Context.getObjCIdDecl(); + if (Context.ObjCIdDecl) + return Context.ObjCIdDecl; + NewLoaded = Context.getObjCIdDecl(); + break; case PREDEF_DECL_OBJC_SEL_ID: - return Context.getObjCSelDecl(); + if (Context.ObjCSelDecl) + return Context.ObjCSelDecl; + NewLoaded = Context.getObjCSelDecl(); + break; case PREDEF_DECL_OBJC_CLASS_ID: - return Context.getObjCClassDecl(); + if (Context.ObjCClassDecl) + return Context.ObjCClassDecl; + NewLoaded = Context.getObjCClassDecl(); + break; case PREDEF_DECL_OBJC_PROTOCOL_ID: - return Context.getObjCProtocolDecl(); + if (Context.ObjCProtocolClassDecl) + return Context.ObjCProtocolClassDecl; + NewLoaded = Context.getObjCProtocolDecl(); + break; case PREDEF_DECL_INT_128_ID: - return Context.getInt128Decl(); + if (Context.Int128Decl) + return Context.Int128Decl; + NewLoaded = Context.getInt128Decl(); + break; case PREDEF_DECL_UNSIGNED_INT_128_ID: - return Context.getUInt128Decl(); + if (Context.UInt128Decl) + return Context.UInt128Decl; + NewLoaded = Context.getUInt128Decl(); + break; case PREDEF_DECL_OBJC_INSTANCETYPE_ID: - return Context.getObjCInstanceTypeDecl(); + if (Context.ObjCInstanceTypeDecl) + return Context.ObjCInstanceTypeDecl; + NewLoaded = Context.getObjCInstanceTypeDecl(); + break; case PREDEF_DECL_BUILTIN_VA_LIST_ID: - return Context.getBuiltinVaListDecl(); + if (Context.BuiltinVaListDecl) + return Context.BuiltinVaListDecl; + NewLoaded = Context.getBuiltinVaListDecl(); + break; case PREDEF_DECL_VA_LIST_TAG: - return Context.getVaListTagDecl(); + if (Context.VaListTagDecl) + return Context.VaListTagDecl; + NewLoaded = Context.getVaListTagDecl(); + break; case PREDEF_DECL_BUILTIN_MS_VA_LIST_ID: - return Context.getBuiltinMSVaListDecl(); + if (Context.BuiltinMSVaListDecl) + return Context.BuiltinMSVaListDecl; + NewLoaded = Context.getBuiltinMSVaListDecl(); + break; case PREDEF_DECL_BUILTIN_MS_GUID_ID: + // ASTContext::getMSGuidTagDecl won't create MSGuidTagDecl conditionally. return Context.getMSGuidTagDecl(); case PREDEF_DECL_EXTERN_C_CONTEXT_ID: - return Context.getExternCContextDecl(); + if (Context.ExternCContext) + return Context.ExternCContext; + NewLoaded = Context.getExternCContextDecl(); + break; case PREDEF_DECL_MAKE_INTEGER_SEQ_ID: - return Context.getMakeIntegerSeqDecl(); + if (Context.MakeIntegerSeqDecl) + return Context.MakeIntegerSeqDecl; + NewLoaded = Context.getMakeIntegerSeqDecl(); + break; case PREDEF_DECL_CF_CONSTANT_STRING_ID: - return Context.getCFConstantStringDecl(); + if (Context.CFConstantStringTypeDecl) + return Context.CFConstantStringTypeDecl; + NewLoaded = Context.getCFConstantStringDecl(); + break; case PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID: - return Context.getCFConstantStringTagDecl(); + if (Context.CFConstantStringTagDecl) + return Context.CFConstantStringTagDecl; + NewLoaded = Context.getCFConstantStringTagDecl(); + break; case PREDEF_DECL_TYPE_PACK_ELEMENT_ID: - return Context.getTypePackElementDecl(); + if (Context.TypePackElementDecl) + return Context.TypePackElementDecl; + NewLoaded = Context.getTypePackElementDecl(); + break; + } + + assert(NewLoaded && "Failed to load predefined decl?"); + + if (DeserializationListener) + DeserializationListener->PredefinedDeclBuilt(ID, NewLoaded); + + return NewLoaded; +} + +unsigned ASTReader::translateGlobalDeclIDToIndex(GlobalDeclID GlobalID) const { + ModuleFile *OwningModuleFile = getOwningModuleFile(GlobalID); + if (!OwningModuleFile) { + assert(GlobalID < NUM_PREDEF_DECL_IDS && "Untransalted Global ID?"); + return GlobalID.getRawValue(); } - llvm_unreachable("PredefinedDeclIDs unknown enum value"); + + return OwningModuleFile->BaseDeclIndex + GlobalID.getLocalDeclIndex(); } -Decl *ASTReader::GetExistingDecl(DeclID ID) { +Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { assert(ContextObj && "reading decl with no AST context"); + if (ID < NUM_PREDEF_DECL_IDS) { - Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID); + Decl *D = getPredefinedDecl((PredefinedDeclIDs)ID); if (D) { // Track that we have merged the declaration with ID \p ID into the // pre-existing predefined declaration \p D. @@ -7754,7 +7880,7 @@ Decl *ASTReader::GetExistingDecl(DeclID ID) { return D; } - unsigned Index = ID - NUM_PREDEF_DECL_IDS; + unsigned Index = translateGlobalDeclIDToIndex(ID); if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7765,11 +7891,11 @@ Decl *ASTReader::GetExistingDecl(DeclID ID) { return DeclsLoaded[Index]; } -Decl *ASTReader::GetDecl(DeclID ID) { +Decl *ASTReader::GetDecl(GlobalDeclID ID) { if (ID < NUM_PREDEF_DECL_IDS) return GetExistingDecl(ID); - unsigned Index = ID - NUM_PREDEF_DECL_IDS; + unsigned Index = translateGlobalDeclIDToIndex(ID); if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7786,32 +7912,43 @@ Decl *ASTReader::GetDecl(DeclID ID) { return DeclsLoaded[Index]; } -DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, - DeclID GlobalID) { +LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + GlobalDeclID GlobalID) { if (GlobalID < NUM_PREDEF_DECL_IDS) - return GlobalID; + return LocalDeclID::get(*this, M, GlobalID.getRawValue()); - GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); - assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); - ModuleFile *Owner = I->second; + if (!M.ModuleOffsetMap.empty()) + ReadModuleOffsetMap(M); - llvm::DenseMap<ModuleFile *, serialization::DeclID>::iterator Pos - = M.GlobalToLocalDeclIDs.find(Owner); - if (Pos == M.GlobalToLocalDeclIDs.end()) - return 0; + ModuleFile *Owner = getOwningModuleFile(GlobalID); + DeclID ID = GlobalID.getLocalDeclIndex(); - return GlobalID - Owner->BaseDeclID + Pos->second; + if (Owner == &M) { + ID += NUM_PREDEF_DECL_IDS; + return LocalDeclID::get(*this, M, ID); + } + + uint64_t OrignalModuleFileIndex = 0; + for (unsigned I = 0; I < M.TransitiveImports.size(); I++) + if (M.TransitiveImports[I] == Owner) { + OrignalModuleFileIndex = I + 1; + break; + } + + if (!OrignalModuleFileIndex) + return LocalDeclID(); + + return LocalDeclID::get(*this, M, OrignalModuleFileIndex, ID); } -serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F, - const RecordData &Record, - unsigned &Idx) { +GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordDataImpl &Record, + unsigned &Idx) { if (Idx >= Record.size()) { Error("Corrupted AST file"); - return 0; + return GlobalDeclID(0); } - return getGlobalDeclID(F, Record[Idx++]); + return getGlobalDeclID(F, LocalDeclID::get(*this, F, Record[Idx++])); } /// Resolve the offset of a statement into a statement. @@ -7847,7 +7984,7 @@ void ASTReader::FindExternalLexicalDecls( if (!IsKindWeWant(K)) continue; - auto ID = (serialization::DeclID)+LexicalDecls[I + 1]; + auto ID = (DeclID) + LexicalDecls[I + 1]; // Don't add predefined declarations to the lexical context more // than once. @@ -7858,7 +7995,7 @@ void ASTReader::FindExternalLexicalDecls( PredefsVisited[ID] = true; } - if (Decl *D = GetLocalDecl(*M, ID)) { + if (Decl *D = GetLocalDecl(*M, LocalDeclID::get(*this, *M, ID))) { assert(D->getKind() == K && "wrong kind for lexical decl"); if (!DC->isDeclInLexicalTraversal(D)) Decls.push_back(D); @@ -7880,32 +8017,34 @@ void ASTReader::FindExternalLexicalDecls( namespace { -class DeclIDComp { +class UnalignedDeclIDComp { ASTReader &Reader; ModuleFile &Mod; public: - DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {} + UnalignedDeclIDComp(ASTReader &Reader, ModuleFile &M) + : Reader(Reader), Mod(M) {} - bool operator()(LocalDeclID L, LocalDeclID R) const { + bool operator()(unaligned_decl_id_t L, unaligned_decl_id_t R) const { SourceLocation LHS = getLocation(L); SourceLocation RHS = getLocation(R); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - bool operator()(SourceLocation LHS, LocalDeclID R) const { + bool operator()(SourceLocation LHS, unaligned_decl_id_t R) const { SourceLocation RHS = getLocation(R); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - bool operator()(LocalDeclID L, SourceLocation RHS) const { + bool operator()(unaligned_decl_id_t L, SourceLocation RHS) const { SourceLocation LHS = getLocation(L); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - SourceLocation getLocation(LocalDeclID ID) const { + SourceLocation getLocation(unaligned_decl_id_t ID) const { return Reader.getSourceManager().getFileLoc( - Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID))); + Reader.getSourceLocationForDeclID( + Reader.getGlobalDeclID(Mod, LocalDeclID::get(Reader, Mod, ID)))); } }; @@ -7928,8 +8067,8 @@ void ASTReader::FindFileRegionDecls(FileID File, BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset); SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length); - DeclIDComp DIDComp(*this, *DInfo.Mod); - ArrayRef<serialization::LocalDeclID>::iterator BeginIt = + UnalignedDeclIDComp DIDComp(*this, *DInfo.Mod); + ArrayRef<unaligned_decl_id_t>::iterator BeginIt = llvm::lower_bound(DInfo.Decls, BeginLoc, DIDComp); if (BeginIt != DInfo.Decls.begin()) --BeginIt; @@ -7938,18 +8077,20 @@ void ASTReader::FindFileRegionDecls(FileID File, // to backtrack until we find it otherwise we will fail to report that the // region overlaps with an objc container. while (BeginIt != DInfo.Decls.begin() && - GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt)) + GetDecl(getGlobalDeclID(*DInfo.Mod, + LocalDeclID::get(*this, *DInfo.Mod, *BeginIt))) ->isTopLevelDeclInObjCContainer()) --BeginIt; - ArrayRef<serialization::LocalDeclID>::iterator EndIt = + ArrayRef<unaligned_decl_id_t>::iterator EndIt = llvm::upper_bound(DInfo.Decls, 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))); + for (ArrayRef<unaligned_decl_id_t>::iterator DIt = BeginIt; DIt != EndIt; + ++DIt) + Decls.push_back(GetDecl(getGlobalDeclID( + *DInfo.Mod, LocalDeclID::get(*this, *DInfo.Mod, *DIt)))); } bool @@ -7969,7 +8110,8 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, // Load the list of declarations. SmallVector<NamedDecl *, 64> Decls; llvm::SmallPtrSet<NamedDecl *, 8> Found; - for (DeclID ID : It->second.Table.find(Name)) { + + for (GlobalDeclID ID : It->second.Table.find(Name)) { NamedDecl *ND = cast<NamedDecl>(GetDecl(ID)); if (ND->getDeclName() == Name && Found.insert(ND).second) Decls.push_back(ND); @@ -7990,7 +8132,7 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) { DeclsMap Decls; - for (DeclID ID : It->second.Table.findAll()) { + for (GlobalDeclID ID : It->second.Table.findAll()) { NamedDecl *ND = cast<NamedDecl>(GetDecl(ID)); Decls[ND->getDeclName()].push_back(ND); } @@ -8030,6 +8172,10 @@ void ASTReader::PassInterestingDeclToConsumer(Decl *D) { Consumer->HandleInterestingDecl(DeclGroupRef(D)); } +void ASTReader::PassVTableToConsumer(CXXRecordDecl *RD) { + Consumer->HandleVTable(RD); +} + void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) { this->Consumer = Consumer; @@ -8140,19 +8286,15 @@ dumpModuleIDMap(StringRef Name, llvm::errs() << Name << ":\n"; for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); - I != IEnd; ++I) { - llvm::errs() << " " << I->first << " -> " << I->second->FileName - << "\n"; - } + I != IEnd; ++I) + llvm::errs() << " " << (DeclID)I->first << " -> " << I->second->FileName + << "\n"; } LLVM_DUMP_METHOD void ASTReader::dump() { llvm::errs() << "*** PCH/ModuleFile Remappings:\n"; dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap); dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap); - dumpModuleIDMap("Global type map", GlobalTypeMap); - dumpModuleIDMap("Global declaration map", GlobalDeclMap); - dumpModuleIDMap("Global identifier map", GlobalIdentifierMap); dumpModuleIDMap("Global macro map", GlobalMacroMap); dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap); dumpModuleIDMap("Global selector map", GlobalSelectorMap); @@ -8188,7 +8330,7 @@ void ASTReader::InitializeSema(Sema &S) { // Makes sure any declarations that were deserialized "too early" // still get added to the identifier's declaration chains. - for (uint64_t ID : PreloadedDeclIDs) { + for (GlobalDeclID ID : PreloadedDeclIDs) { NamedDecl *D = cast<NamedDecl>(GetDecl(ID)); pushExternalDeclIntoScope(D, D->getDeclName()); } @@ -8217,11 +8359,11 @@ void ASTReader::UpdateSema() { assert(SemaDeclRefs.size() % 3 == 0); for (unsigned I = 0; I != SemaDeclRefs.size(); I += 3) { if (!SemaObj->StdNamespace) - SemaObj->StdNamespace = SemaDeclRefs[I]; + SemaObj->StdNamespace = SemaDeclRefs[I].getRawValue(); if (!SemaObj->StdBadAlloc) - SemaObj->StdBadAlloc = SemaDeclRefs[I+1]; + SemaObj->StdBadAlloc = SemaDeclRefs[I + 1].getRawValue(); if (!SemaObj->StdAlignValT) - SemaObj->StdAlignValT = SemaDeclRefs[I+2]; + SemaObj->StdAlignValT = SemaDeclRefs[I + 2].getRawValue(); } SemaDeclRefs.clear(); } @@ -8238,7 +8380,7 @@ void ASTReader::UpdateSema() { PragmaMSPointersToMembersState, PointersToMembersPragmaLocation); } - SemaObj->ForceCUDAHostDeviceDepth = ForceCUDAHostDeviceDepth; + SemaObj->CUDA().ForceHostDeviceDepth = ForceHostDeviceDepth; if (PragmaAlignPackCurrentValue) { // The bottom of the stack might have a default value. It must be adjusted @@ -8534,7 +8676,7 @@ namespace serialization { static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods, ObjCMethodList &List) { for (ObjCMethodDecl *M : llvm::reverse(Methods)) - S.addMethodToGlobalList(&List, M); + S.ObjC().addMethodToGlobalList(&List, M); } void ASTReader::ReadMethodPool(Selector Sel) { @@ -8559,8 +8701,10 @@ void ASTReader::ReadMethodPool(Selector Sel) { return; Sema &S = *getSema(); - Sema::GlobalMethodPool::iterator Pos = - S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethodPool::Lists())) + SemaObjC::GlobalMethodPool::iterator Pos = + S.ObjC() + .MethodPool + .insert(std::make_pair(Sel, SemaObjC::GlobalMethodPool::Lists())) .first; Pos->second.first.setBits(Visitor.getInstanceBits()); @@ -8594,18 +8738,20 @@ void ASTReader::ReadKnownNamespaces( void ASTReader::ReadUndefinedButUsed( llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) { for (unsigned Idx = 0, N = UndefinedButUsed.size(); Idx != N;) { - NamedDecl *D = cast<NamedDecl>(GetDecl(UndefinedButUsed[Idx++])); - SourceLocation Loc = - SourceLocation::getFromRawEncoding(UndefinedButUsed[Idx++]); + UndefinedButUsedDecl &U = UndefinedButUsed[Idx++]; + NamedDecl *D = cast<NamedDecl>(GetDecl(U.ID)); + SourceLocation Loc = SourceLocation::getFromRawEncoding(U.RawLoc); Undefined.insert(std::make_pair(D, Loc)); } + UndefinedButUsed.clear(); } void ASTReader::ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & Exprs) { for (unsigned Idx = 0, N = DelayedDeleteExprs.size(); Idx != N;) { - FieldDecl *FD = cast<FieldDecl>(GetDecl(DelayedDeleteExprs[Idx++])); + FieldDecl *FD = + cast<FieldDecl>(GetDecl(GlobalDeclID(DelayedDeleteExprs[Idx++]))); uint64_t Count = DelayedDeleteExprs[Idx++]; for (uint64_t C = 0; C < Count; ++C) { SourceLocation DeleteLoc = @@ -8719,9 +8865,10 @@ void ASTReader::ReadWeakUndeclaredIdentifiers( void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) { for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) { ExternalVTableUse VT; - VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(VTableUses[Idx++])); - VT.Location = SourceLocation::getFromRawEncoding(VTableUses[Idx++]); - VT.DefinitionRequired = VTableUses[Idx++]; + VTableUse &TableInfo = VTableUses[Idx++]; + VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(TableInfo.ID)); + VT.Location = SourceLocation::getFromRawEncoding(TableInfo.RawLoc); + VT.DefinitionRequired = TableInfo.Used; VTables.push_back(VT); } @@ -8731,9 +8878,9 @@ void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) { void ASTReader::ReadPendingInstantiations( SmallVectorImpl<std::pair<ValueDecl *, SourceLocation>> &Pending) { for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) { - ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++])); - SourceLocation Loc - = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]); + PendingInstantiation &Inst = PendingInstantiations[Idx++]; + ValueDecl *D = cast<ValueDecl>(GetDecl(Inst.ID)); + SourceLocation Loc = SourceLocation::getFromRawEncoding(Inst.RawLoc); Pending.push_back(std::make_pair(D, Loc)); } @@ -8748,11 +8895,10 @@ void ASTReader::ReadLateParsedTemplates( RecordDataImpl &LateParsed = LPT.second; for (unsigned Idx = 0, N = LateParsed.size(); Idx < N; /* In loop */) { - FunctionDecl *FD = - cast<FunctionDecl>(GetLocalDecl(*FMod, LateParsed[Idx++])); + FunctionDecl *FD = ReadDeclAs<FunctionDecl>(*FMod, LateParsed, Idx); auto LT = std::make_unique<LateParsedTemplate>(); - LT->D = GetLocalDecl(*FMod, LateParsed[Idx++]); + LT->D = ReadDecl(*FMod, LateParsed, Idx); LT->FPO = FPOptions::getFromOpaqueInt(LateParsed[Idx++]); ModuleFile *F = getOwningModuleFile(LT->D); @@ -8788,8 +8934,9 @@ void ASTReader::LoadSelector(Selector Sel) { void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) { assert(ID && "Non-zero identifier ID required"); - assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range"); - IdentifiersLoaded[ID - 1] = II; + unsigned Index = translateIdentifierIDToIndex(ID).second; + assert(Index < IdentifiersLoaded.size() && "identifier ID out of range"); + IdentifiersLoaded[Index] = II; if (DeserializationListener) DeserializationListener->IdentifierRead(ID, II); } @@ -8810,10 +8957,9 @@ void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) { /// \param Decls if non-null, this vector will be populated with the set of /// deserialized declarations. These declarations will not be pushed into /// scope. -void -ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II, - const SmallVectorImpl<uint32_t> &DeclIDs, - SmallVectorImpl<Decl *> *Decls) { +void ASTReader::SetGloballyVisibleDecls( + IdentifierInfo *II, const SmallVectorImpl<GlobalDeclID> &DeclIDs, + SmallVectorImpl<Decl *> *Decls) { if (NumCurrentElementsDeserializing && !Decls) { PendingIdentifierInfos[II].append(DeclIDs.begin(), DeclIDs.end()); return; @@ -8843,6 +8989,22 @@ ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II, } } +std::pair<ModuleFile *, unsigned> +ASTReader::translateIdentifierIDToIndex(IdentifierID ID) const { + if (ID == 0) + return {nullptr, 0}; + + unsigned ModuleFileIndex = ID >> 32; + unsigned LocalID = ID & llvm::maskTrailingOnes<IdentifierID>(32); + + assert(ModuleFileIndex && "not translating loaded IdentifierID?"); + assert(getModuleManager().size() > ModuleFileIndex - 1); + + ModuleFile &MF = getModuleManager()[ModuleFileIndex - 1]; + assert(LocalID < MF.LocalNumIdentifiers); + return {&MF, MF.BaseIdentifierID + LocalID}; +} + IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) { if (ID == 0) return nullptr; @@ -8852,45 +9014,48 @@ IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) { return nullptr; } - ID -= 1; - if (!IdentifiersLoaded[ID]) { - GlobalIdentifierMapType::iterator I = GlobalIdentifierMap.find(ID + 1); - assert(I != GlobalIdentifierMap.end() && "Corrupted global identifier map"); - ModuleFile *M = I->second; - unsigned Index = ID - M->BaseIdentifierID; + auto [M, Index] = translateIdentifierIDToIndex(ID); + if (!IdentifiersLoaded[Index]) { + assert(M != nullptr && "Untranslated Identifier ID?"); + assert(Index >= M->BaseIdentifierID); + unsigned LocalIndex = Index - M->BaseIdentifierID; const unsigned char *Data = - M->IdentifierTableData + M->IdentifierOffsets[Index]; + M->IdentifierTableData + M->IdentifierOffsets[LocalIndex]; ASTIdentifierLookupTrait Trait(*this, *M); auto KeyDataLen = Trait.ReadKeyDataLength(Data); auto Key = Trait.ReadKey(Data, KeyDataLen.first); auto &II = PP.getIdentifierTable().get(Key); - IdentifiersLoaded[ID] = &II; + IdentifiersLoaded[Index] = &II; markIdentifierFromAST(*this, II); if (DeserializationListener) - DeserializationListener->IdentifierRead(ID + 1, &II); + DeserializationListener->IdentifierRead(ID, &II); } - return IdentifiersLoaded[ID]; + return IdentifiersLoaded[Index]; } -IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, unsigned LocalID) { +IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, uint64_t LocalID) { return DecodeIdentifierInfo(getGlobalIdentifierID(M, LocalID)); } -IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) { +IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, uint64_t LocalID) { if (LocalID < NUM_PREDEF_IDENT_IDS) return LocalID; if (!M.ModuleOffsetMap.empty()) ReadModuleOffsetMap(M); - ContinuousRangeMap<uint32_t, int, 2>::iterator I - = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS); - assert(I != M.IdentifierRemap.end() - && "Invalid index into identifier index remap"); + unsigned ModuleFileIndex = LocalID >> 32; + LocalID &= llvm::maskTrailingOnes<IdentifierID>(32); + ModuleFile *MF = + ModuleFileIndex ? M.TransitiveImports[ModuleFileIndex - 1] : &M; + assert(MF && "malformed identifier ID encoding?"); - return LocalID + I->second; + if (!ModuleFileIndex) + LocalID -= NUM_PREDEF_IDENT_IDS; + + return ((IdentifierID)(MF->Index + 1) << 32) | LocalID; } MacroInfo *ASTReader::getMacro(MacroID ID) { @@ -8935,7 +9100,7 @@ MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) { } serialization::SubmoduleID -ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) { +ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) const { if (LocalID < NUM_PREDEF_SUBMODULE_IDS) return LocalID; @@ -8968,7 +9133,7 @@ Module *ASTReader::getModule(unsigned ID) { return getSubmodule(ID); } -ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &M, unsigned ID) { +ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &M, unsigned ID) const { if (ID & 1) { // It's a module, look it up by submodule ID. auto I = GlobalSubmoduleMap.find(getGlobalSubmoduleID(M, ID >> 1)); @@ -9111,6 +9276,10 @@ DeclarationNameInfo ASTRecordReader::readDeclarationNameInfo() { return NameInfo; } +TypeCoupledDeclRefInfo ASTRecordReader::readTypeCoupledDeclRefInfo() { + return TypeCoupledDeclRefInfo(readDeclAs<ValueDecl>(), readBool()); +} + void ASTRecordReader::readQualifierInfo(QualifierInfo &Info) { Info.QualifierLoc = readNestedNameSpecifierLoc(); unsigned NumTPLists = readInt(); @@ -9157,7 +9326,7 @@ void ASTRecordReader::readUnresolvedSet(LazyASTUnresolvedSet &Set) { unsigned NumDecls = readInt(); Set.reserve(getContext(), NumDecls); while (NumDecls--) { - DeclID ID = readDeclID(); + GlobalDeclID ID = readDeclID(); AccessSpecifier AS = (AccessSpecifier) readInt(); Set.addLazyDecl(getContext(), ID, AS); } @@ -9312,6 +9481,18 @@ SourceRange ASTReader::ReadSourceRange(ModuleFile &F, const RecordData &Record, return SourceRange(beg, end); } +llvm::BitVector ASTReader::ReadBitVector(const RecordData &Record, + const StringRef Blob) { + unsigned Count = Record[0]; + const char *Byte = Blob.data(); + llvm::BitVector Ret = llvm::BitVector(Count, false); + for (unsigned I = 0; I < Count; ++Byte) + for (unsigned Bit = 0; Bit < 8 && I < Count; ++Bit, ++I) + if (*Byte & (1 << Bit)) + Ret[I] = true; + return Ret; +} + /// Read a floating-point value llvm::APFloat ASTRecordReader::readAPFloat(const llvm::fltSemantics &Sem) { return llvm::APFloat(Sem, readAPInt()); @@ -9367,6 +9548,20 @@ DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) const { return Diags.Report(Loc, DiagID); } +void ASTReader::warnStackExhausted(SourceLocation Loc) { + // When Sema is available, avoid duplicate errors. + if (SemaObj) { + SemaObj->warnStackExhausted(Loc); + return; + } + + if (WarnedStackExhausted) + return; + WarnedStackExhausted = true; + + Diag(Loc, diag::warn_stack_exhausted); +} + /// Retrieve the identifier table associated with the /// preprocessor. IdentifierTable &ASTReader::getIdentifierTable() { @@ -9521,7 +9716,7 @@ void ASTReader::finishPendingActions() { while (!PendingIdentifierInfos.empty()) { IdentifierInfo *II = PendingIdentifierInfos.back().first; - SmallVector<uint32_t, 4> DeclIDs = + SmallVector<GlobalDeclID, 4> DeclIDs = std::move(PendingIdentifierInfos.back().second); PendingIdentifierInfos.pop_back(); @@ -9745,7 +9940,8 @@ void ASTReader::finishPendingActions() { !NonConstDefn->isLateTemplateParsed() && // We only perform ODR checks for decls not in the explicit // global module fragment. - !FD->shouldSkipCheckingODR() && + !shouldSkipCheckingODR(FD) && + !shouldSkipCheckingODR(NonConstDefn) && FD->getODRHash() != NonConstDefn->getODRHash()) { if (!isa<CXXMethodDecl>(FD)) { PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn); @@ -10139,7 +10335,7 @@ void ASTReader::FinishedDeserializing() { } void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { - if (IdentifierInfo *II = Name.getAsIdentifierInfo()) { + if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) { // Remove any fake results before adding any real ones. auto It = PendingFakeLookupResults.find(II); if (It != PendingFakeLookupResults.end()) { @@ -10335,6 +10531,9 @@ OMPClause *OMPClauseReader::readClause() { case llvm::omp::OMPC_relaxed: C = new (Context) OMPRelaxedClause(); break; + case llvm::omp::OMPC_weak: + C = new (Context) OMPWeakClause(); + break; case llvm::omp::OMPC_threads: C = new (Context) OMPThreadsClause(); break; @@ -10733,6 +10932,8 @@ void OMPClauseReader::VisitOMPReleaseClause(OMPReleaseClause *) {} void OMPClauseReader::VisitOMPRelaxedClause(OMPRelaxedClause *) {} +void OMPClauseReader::VisitOMPWeakClause(OMPWeakClause *) {} + void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {} void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {} @@ -11717,3 +11918,209 @@ void ASTRecordReader::readOMPChildren(OMPChildren *Data) { for (unsigned I = 0, E = Data->getNumChildren(); I < E; ++I) Data->getChildren()[I] = readStmt(); } + +SmallVector<Expr *> ASTRecordReader::readOpenACCVarList() { + unsigned NumVars = readInt(); + llvm::SmallVector<Expr *> VarList; + for (unsigned I = 0; I < NumVars; ++I) + VarList.push_back(readSubExpr()); + return VarList; +} + +SmallVector<Expr *> ASTRecordReader::readOpenACCIntExprList() { + unsigned NumExprs = readInt(); + llvm::SmallVector<Expr *> ExprList; + for (unsigned I = 0; I < NumExprs; ++I) + ExprList.push_back(readSubExpr()); + return ExprList; +} + +OpenACCClause *ASTRecordReader::readOpenACCClause() { + OpenACCClauseKind ClauseKind = readEnum<OpenACCClauseKind>(); + SourceLocation BeginLoc = readSourceLocation(); + SourceLocation EndLoc = readSourceLocation(); + + switch (ClauseKind) { + case OpenACCClauseKind::Default: { + SourceLocation LParenLoc = readSourceLocation(); + OpenACCDefaultClauseKind DCK = readEnum<OpenACCDefaultClauseKind>(); + return OpenACCDefaultClause::Create(getContext(), DCK, BeginLoc, LParenLoc, + EndLoc); + } + case OpenACCClauseKind::If: { + SourceLocation LParenLoc = readSourceLocation(); + Expr *CondExpr = readSubExpr(); + return OpenACCIfClause::Create(getContext(), BeginLoc, LParenLoc, CondExpr, + EndLoc); + } + case OpenACCClauseKind::Self: { + SourceLocation LParenLoc = readSourceLocation(); + Expr *CondExpr = readBool() ? readSubExpr() : nullptr; + return OpenACCSelfClause::Create(getContext(), BeginLoc, LParenLoc, + CondExpr, EndLoc); + } + case OpenACCClauseKind::NumGangs: { + SourceLocation LParenLoc = readSourceLocation(); + unsigned NumClauses = readInt(); + llvm::SmallVector<Expr *> IntExprs; + for (unsigned I = 0; I < NumClauses; ++I) + IntExprs.push_back(readSubExpr()); + return OpenACCNumGangsClause::Create(getContext(), BeginLoc, LParenLoc, + IntExprs, EndLoc); + } + case OpenACCClauseKind::NumWorkers: { + SourceLocation LParenLoc = readSourceLocation(); + Expr *IntExpr = readSubExpr(); + return OpenACCNumWorkersClause::Create(getContext(), BeginLoc, LParenLoc, + IntExpr, EndLoc); + } + case OpenACCClauseKind::VectorLength: { + SourceLocation LParenLoc = readSourceLocation(); + Expr *IntExpr = readSubExpr(); + return OpenACCVectorLengthClause::Create(getContext(), BeginLoc, LParenLoc, + IntExpr, EndLoc); + } + case OpenACCClauseKind::Private: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCPrivateClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } + case OpenACCClauseKind::FirstPrivate: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCFirstPrivateClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } + case OpenACCClauseKind::Attach: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCAttachClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } + case OpenACCClauseKind::DevicePtr: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCDevicePtrClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } + case OpenACCClauseKind::NoCreate: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCNoCreateClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } + case OpenACCClauseKind::Present: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCPresentClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } + case OpenACCClauseKind::PCopy: + case OpenACCClauseKind::PresentOrCopy: + case OpenACCClauseKind::Copy: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCCopyClause::Create(getContext(), ClauseKind, BeginLoc, + LParenLoc, VarList, EndLoc); + } + case OpenACCClauseKind::CopyIn: + case OpenACCClauseKind::PCopyIn: + case OpenACCClauseKind::PresentOrCopyIn: { + SourceLocation LParenLoc = readSourceLocation(); + bool IsReadOnly = readBool(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCCopyInClause::Create(getContext(), ClauseKind, BeginLoc, + LParenLoc, IsReadOnly, VarList, EndLoc); + } + case OpenACCClauseKind::CopyOut: + case OpenACCClauseKind::PCopyOut: + case OpenACCClauseKind::PresentOrCopyOut: { + SourceLocation LParenLoc = readSourceLocation(); + bool IsZero = readBool(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCCopyOutClause::Create(getContext(), ClauseKind, BeginLoc, + LParenLoc, IsZero, VarList, EndLoc); + } + case OpenACCClauseKind::Create: + case OpenACCClauseKind::PCreate: + case OpenACCClauseKind::PresentOrCreate: { + SourceLocation LParenLoc = readSourceLocation(); + bool IsZero = readBool(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCCreateClause::Create(getContext(), ClauseKind, BeginLoc, + LParenLoc, IsZero, VarList, EndLoc); + } + case OpenACCClauseKind::Async: { + SourceLocation LParenLoc = readSourceLocation(); + Expr *AsyncExpr = readBool() ? readSubExpr() : nullptr; + return OpenACCAsyncClause::Create(getContext(), BeginLoc, LParenLoc, + AsyncExpr, EndLoc); + } + case OpenACCClauseKind::Wait: { + SourceLocation LParenLoc = readSourceLocation(); + Expr *DevNumExpr = readBool() ? readSubExpr() : nullptr; + SourceLocation QueuesLoc = readSourceLocation(); + llvm::SmallVector<Expr *> QueueIdExprs = readOpenACCIntExprList(); + return OpenACCWaitClause::Create(getContext(), BeginLoc, LParenLoc, + DevNumExpr, QueuesLoc, QueueIdExprs, + EndLoc); + } + case OpenACCClauseKind::DeviceType: + case OpenACCClauseKind::DType: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector<DeviceTypeArgument> Archs; + unsigned NumArchs = readInt(); + + for (unsigned I = 0; I < NumArchs; ++I) { + IdentifierInfo *Ident = readBool() ? readIdentifier() : nullptr; + SourceLocation Loc = readSourceLocation(); + Archs.emplace_back(Ident, Loc); + } + + return OpenACCDeviceTypeClause::Create(getContext(), ClauseKind, BeginLoc, + LParenLoc, Archs, EndLoc); + } + case OpenACCClauseKind::Reduction: { + SourceLocation LParenLoc = readSourceLocation(); + OpenACCReductionOperator Op = readEnum<OpenACCReductionOperator>(); + llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + return OpenACCReductionClause::Create(getContext(), BeginLoc, LParenLoc, Op, + VarList, EndLoc); + } + case OpenACCClauseKind::Seq: + return OpenACCSeqClause::Create(getContext(), BeginLoc, EndLoc); + case OpenACCClauseKind::Independent: + return OpenACCIndependentClause::Create(getContext(), BeginLoc, EndLoc); + case OpenACCClauseKind::Auto: + return OpenACCAutoClause::Create(getContext(), BeginLoc, EndLoc); + + case OpenACCClauseKind::Finalize: + case OpenACCClauseKind::IfPresent: + case OpenACCClauseKind::Worker: + case OpenACCClauseKind::Vector: + case OpenACCClauseKind::NoHost: + case OpenACCClauseKind::UseDevice: + case OpenACCClauseKind::Delete: + case OpenACCClauseKind::Detach: + case OpenACCClauseKind::Device: + case OpenACCClauseKind::DeviceResident: + case OpenACCClauseKind::Host: + case OpenACCClauseKind::Link: + case OpenACCClauseKind::Collapse: + case OpenACCClauseKind::Bind: + case OpenACCClauseKind::DeviceNum: + case OpenACCClauseKind::DefaultAsync: + case OpenACCClauseKind::Tile: + case OpenACCClauseKind::Gang: + case OpenACCClauseKind::Invalid: + llvm_unreachable("Clause serialization not yet implemented"); + } + llvm_unreachable("Invalid Clause Kind"); +} + +void ASTRecordReader::readOpenACCClauseList( + MutableArrayRef<const OpenACCClause *> Clauses) { + for (unsigned I = 0; I < Clauses.size(); ++I) + Clauses[I] = readOpenACCClause(); +} |