diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:09 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:09 +0000 |
commit | 519fc96c475680de2cc49e7811dbbfadb912cbcc (patch) | |
tree | 310ca684459b7e9ae13c9a3b9abf308b3a634afe /lib/Serialization | |
parent | 2298981669bf3bd63335a4be179bc0f96823a8f4 (diff) |
Notes
Diffstat (limited to 'lib/Serialization')
-rw-r--r-- | lib/Serialization/ASTCommon.cpp | 5 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 223 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 171 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 86 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 174 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 15 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 50 | ||||
-rw-r--r-- | lib/Serialization/GlobalModuleIndex.cpp | 49 | ||||
-rw-r--r-- | lib/Serialization/ModuleManager.cpp | 35 | ||||
-rw-r--r-- | lib/Serialization/PCHContainerOperations.cpp | 6 |
10 files changed, 494 insertions, 320 deletions
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index aa3477a7d35e6..dd06e0582ac56 100644 --- a/lib/Serialization/ASTCommon.cpp +++ b/lib/Serialization/ASTCommon.cpp @@ -232,6 +232,11 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::OCLReserveID: ID = PREDEF_TYPE_RESERVE_ID_ID; break; +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: \ + ID = PREDEF_TYPE_##Id##_ID; \ + break; +#include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::BuiltinFn: ID = PREDEF_TYPE_BUILTIN_FN; break; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 7f2c7f09e8a3e..2d3884ebe0211 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1247,6 +1247,12 @@ void ASTReader::Error(unsigned DiagID, Diag(DiagID) << Arg1 << Arg2; } +void ASTReader::Error(unsigned DiagID, StringRef Arg1, StringRef Arg2, + unsigned Select) const { + if (!Diags.isDiagnosticInFlight()) + Diag(DiagID) << Arg1 << Arg2 << Select; +} + void ASTReader::Error(llvm::Error &&Err) const { Error(toString(std::move(Err))); } @@ -1514,6 +1520,7 @@ bool ASTReader::ReadSLocEntry(int ID) { } SrcMgr::CharacteristicKind FileCharacter = (SrcMgr::CharacteristicKind)Record[2]; + // FIXME: The FileID should be created from the FileEntryRef. FileID FID = SourceMgr.createFileID(File, IncludeLoc, FileCharacter, ID, BaseOffset + Record[0]); SrcMgr::FileInfo &FileInfo = @@ -1522,9 +1529,9 @@ bool ASTReader::ReadSLocEntry(int ID) { if (Record[3]) FileInfo.setHasLineDirectives(); - const DeclID *FirstDecl = F->FileSortedDecls + Record[6]; unsigned NumFileDecls = Record[7]; if (NumFileDecls && ContextObj) { + const DeclID *FirstDecl = F->FileSortedDecls + Record[6]; assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?"); FileDeclIDs[FID] = FileDeclsInfo(F, llvm::makeArrayRef(FirstDecl, NumFileDecls)); @@ -1822,12 +1829,17 @@ bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { // Determine whether the actual files are equivalent. FileManager &FileMgr = Reader.getFileManager(); auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* { - if (!Key.Imported) - return FileMgr.getFile(Key.Filename); + if (!Key.Imported) { + if (auto File = FileMgr.getFile(Key.Filename)) + return *File; + return nullptr; + } std::string Resolved = Key.Filename; Reader.ResolveImportedPath(M, Resolved); - return FileMgr.getFile(Resolved); + if (auto File = FileMgr.getFile(Resolved)) + return *File; + return nullptr; }; const FileEntry *FEA = GetFile(a); @@ -1904,7 +1916,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, // FIXME: This is not always the right filename-as-written, but we're not // going to use this information to rebuild the module, so it doesn't make // a lot of difference. - Module::Header H = { key.Filename, FileMgr.getFile(Filename) }; + Module::Header H = { key.Filename, *FileMgr.getFile(Filename) }; ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true); HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader); } @@ -2235,6 +2247,24 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) { R.TopLevelModuleMap = static_cast<bool>(Record[5]); R.Filename = Blob; ResolveImportedPath(F, R.Filename); + + Expected<llvm::BitstreamEntry> MaybeEntry = Cursor.advance(); + if (!MaybeEntry) // FIXME this drops errors on the floor. + consumeError(MaybeEntry.takeError()); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + assert(Entry.Kind == llvm::BitstreamEntry::Record && + "expected record type for input file hash"); + + Record.clear(); + if (Expected<unsigned> Maybe = Cursor.readRecord(Entry.ID, Record)) + assert(static_cast<InputFileRecordTypes>(Maybe.get()) == INPUT_FILE_HASH && + "invalid record type for input file hash"); + else { + // FIXME this drops errors on the floor. + consumeError(Maybe.takeError()); + } + R.ContentHash = (static_cast<uint64_t>(Record[1]) << 32) | + static_cast<uint64_t>(Record[0]); return R; } @@ -2265,8 +2295,12 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { bool Overridden = FI.Overridden; bool Transient = FI.Transient; StringRef Filename = FI.Filename; + uint64_t StoredContentHash = FI.ContentHash; + + const FileEntry *File = nullptr; + if (auto FE = FileMgr.getFile(Filename, /*OpenFile=*/false)) + File = *FE; - const FileEntry *File = FileMgr.getFile(Filename, /*OpenFile=*/false); // If we didn't find the file, resolve it relative to the // original directory from which this AST file was created. if (File == nullptr && !F.OriginalDir.empty() && !F.BaseDirectory.empty() && @@ -2274,7 +2308,8 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { std::string Resolved = resolveFileRelativeToOriginalDir( Filename, F.OriginalDir, F.BaseDirectory); if (!Resolved.empty()) - File = FileMgr.getFile(Resolved); + if (auto FE = FileMgr.getFile(Resolved)) + File = *FE; } // For an overridden file, create a virtual file with the stored @@ -2305,29 +2340,56 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { if ((!Overridden && !Transient) && SM.isFileOverridden(File)) { if (Complain) Error(diag::err_fe_pch_file_overridden, Filename); - // After emitting the diagnostic, recover by disabling the override so - // that the original file will be used. - // - // FIXME: This recovery is just as broken as the original state; there may - // be another precompiled module that's using the overridden contents, or - // we might be half way through parsing it. Instead, we should treat the - // overridden contents as belonging to a separate FileEntry. - SM.disableFileContentsOverride(File); - // The FileEntry is a virtual file entry with the size of the contents - // that would override the original contents. Set it to the original's - // size/time. - FileMgr.modifyFileEntry(const_cast<FileEntry*>(File), - StoredSize, StoredTime); + + // After emitting the diagnostic, bypass the overriding file to recover + // (this creates a separate FileEntry). + File = SM.bypassFileContentsOverride(*File); + if (!File) { + F.InputFilesLoaded[ID - 1] = InputFile::getNotFound(); + return InputFile(); + } } - bool IsOutOfDate = false; + enum ModificationType { + Size, + ModTime, + Content, + None, + }; + auto HasInputFileChanged = [&]() { + if (StoredSize != File->getSize()) + return ModificationType::Size; + if (!DisableValidation && StoredTime && + StoredTime != File->getModificationTime()) { + // In case the modification time changes but not the content, + // accept the cached file as legit. + if (ValidateASTInputFilesContent && + StoredContentHash != static_cast<uint64_t>(llvm::hash_code(-1))) { + auto MemBuffOrError = FileMgr.getBufferForFile(File); + if (!MemBuffOrError) { + if (!Complain) + return ModificationType::ModTime; + std::string ErrorStr = "could not get buffer for file '"; + ErrorStr += File->getName(); + ErrorStr += "'"; + Error(ErrorStr); + return ModificationType::ModTime; + } + auto ContentHash = hash_value(MemBuffOrError.get()->getBuffer()); + if (StoredContentHash == static_cast<uint64_t>(ContentHash)) + return ModificationType::None; + return ModificationType::Content; + } + return ModificationType::ModTime; + } + return ModificationType::None; + }; + + bool IsOutOfDate = false; + auto FileChange = HasInputFileChanged(); // For an overridden file, there is nothing to validate. - if (!Overridden && // - (StoredSize != File->getSize() || - (StoredTime && StoredTime != File->getModificationTime() && - !DisableValidation) - )) { + if (!Overridden && FileChange != ModificationType::None) { if (Complain) { // Build a list of the PCH imports that got us here (in reverse). SmallVector<ModuleFile *, 4> ImportStack(1, &F); @@ -2336,13 +2398,17 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { // The top-level PCH is stale. StringRef TopLevelPCHName(ImportStack.back()->FileName); - unsigned DiagnosticKind = moduleKindForDiagnostic(ImportStack.back()->Kind); + unsigned DiagnosticKind = + moduleKindForDiagnostic(ImportStack.back()->Kind); if (DiagnosticKind == 0) - Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName); + Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName, + (unsigned)FileChange); else if (DiagnosticKind == 1) - Error(diag::err_fe_module_file_modified, Filename, TopLevelPCHName); + Error(diag::err_fe_module_file_modified, Filename, TopLevelPCHName, + (unsigned)FileChange); else - Error(diag::err_fe_ast_file_modified, Filename, TopLevelPCHName); + Error(diag::err_fe_ast_file_modified, Filename, TopLevelPCHName, + (unsigned)FileChange); // Print the import stack. if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) { @@ -2820,9 +2886,8 @@ ASTReader::ReadControlBlock(ModuleFile &F, // Don't emit module relocation error if we have -fno-validate-pch if (!PP.getPreprocessorOpts().DisablePCHValidation && F.Kind != MK_ExplicitModule && F.Kind != MK_PrebuiltModule) { - const DirectoryEntry *BuildDir = - PP.getFileManager().getDirectory(Blob); - if (!BuildDir || BuildDir != M->Directory) { + auto BuildDir = PP.getFileManager().getDirectory(Blob); + if (!BuildDir || *BuildDir != M->Directory) { if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) Diag(diag::err_imported_module_relocated) << F.ModuleName << Blob << M->Directory->getName(); @@ -3814,7 +3879,6 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr; // Don't emit module relocation error if we have -fno-validate-pch if (!PP.getPreprocessorOpts().DisablePCHValidation && !ModMap) { - assert(ImportedBy && "top-level import should be verified"); if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) { if (auto *ASTFE = M ? M->getASTFile() : nullptr) { // This module was defined by an imported (explicit) module. @@ -3823,12 +3887,13 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, } else { // This module was built with a different module map. Diag(diag::err_imported_module_not_found) - << F.ModuleName << F.FileName << ImportedBy->FileName - << F.ModuleMapPath; + << F.ModuleName << F.FileName + << (ImportedBy ? ImportedBy->FileName : "") << F.ModuleMapPath + << !ImportedBy; // In case it was imported by a PCH, there's a chance the user is // just missing to include the search path to the directory containing // the modulemap. - if (ImportedBy->Kind == MK_PCH) + if (ImportedBy && ImportedBy->Kind == MK_PCH) Diag(diag::note_imported_by_pch_module_not_found) << llvm::sys::path::parent_path(F.ModuleMapPath); } @@ -3839,14 +3904,16 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, assert(M->Name == F.ModuleName && "found module with different name"); // Check the primary module map file. - const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath); - if (StoredModMap == nullptr || StoredModMap != ModMap) { + auto StoredModMap = FileMgr.getFile(F.ModuleMapPath); + if (!StoredModMap || *StoredModMap != ModMap) { assert(ModMap && "found module is missing module map file"); - assert(ImportedBy && "top-level import should be verified"); + assert((ImportedBy || F.Kind == MK_ImplicitModule) && + "top-level import should be verified"); + bool NotImported = F.Kind == MK_ImplicitModule && !ImportedBy; if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) Diag(diag::err_imported_module_modmap_changed) - << F.ModuleName << ImportedBy->FileName - << ModMap->getName() << F.ModuleMapPath; + << F.ModuleName << (NotImported ? F.FileName : ImportedBy->FileName) + << ModMap->getName() << F.ModuleMapPath << NotImported; return OutOfDate; } @@ -3854,14 +3921,13 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, for (unsigned I = 0, N = Record[Idx++]; I < N; ++I) { // FIXME: we should use input files rather than storing names. std::string Filename = ReadPath(F, Record, Idx); - const FileEntry *F = - FileMgr.getFile(Filename, false, false); - if (F == nullptr) { + auto F = FileMgr.getFile(Filename, false, false); + if (!F) { if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) Error("could not find file '" + Filename +"' referenced by AST file"); return OutOfDate; } - AdditionalStoredMaps.insert(F); + AdditionalStoredMaps.insert(*F); } // Check any additional module map files (e.g. module.private.modulemap) @@ -4035,7 +4101,7 @@ static void updateModuleTimestamp(ModuleFile &MF) { // Overwrite the timestamp file contents so that file's mtime changes. std::string TimestampFilename = MF.getTimestampFilename(); std::error_code EC; - llvm::raw_fd_ostream OS(TimestampFilename, EC, llvm::sys::fs::F_Text); + llvm::raw_fd_ostream OS(TimestampFilename, EC, llvm::sys::fs::OF_Text); if (EC) return; OS << "Timestamp file\n"; @@ -5187,6 +5253,8 @@ bool ASTReader::readASTFileControlBlock( consumeError(MaybeRecordType.takeError()); } switch ((InputFileRecordTypes)MaybeRecordType.get()) { + case INPUT_FILE_HASH: + break; case INPUT_FILE: bool Overridden = static_cast<bool>(Record[3]); std::string Filename = Blob; @@ -5459,10 +5527,10 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case SUBMODULE_UMBRELLA_HEADER: { std::string Filename = Blob; ResolveImportedPath(F, Filename); - if (auto *Umbrella = PP.getFileManager().getFile(Filename)) { + if (auto Umbrella = PP.getFileManager().getFile(Filename)) { if (!CurrentModule->getUmbrellaHeader()) - ModMap.setUmbrellaHeader(CurrentModule, Umbrella, Blob); - else if (CurrentModule->getUmbrellaHeader().Entry != Umbrella) { + ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob); + else if (CurrentModule->getUmbrellaHeader().Entry != *Umbrella) { if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) Error("mismatched umbrella headers in submodule"); return OutOfDate; @@ -5492,10 +5560,10 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case SUBMODULE_UMBRELLA_DIR: { std::string Dirname = Blob; ResolveImportedPath(F, Dirname); - if (auto *Umbrella = PP.getFileManager().getDirectory(Dirname)) { + if (auto Umbrella = PP.getFileManager().getDirectory(Dirname)) { if (!CurrentModule->getUmbrellaDir()) - ModMap.setUmbrellaDir(CurrentModule, Umbrella, Blob); - else if (CurrentModule->getUmbrellaDir().Entry != Umbrella) { + ModMap.setUmbrellaDir(CurrentModule, *Umbrella, Blob); + else if (CurrentModule->getUmbrellaDir().Entry != *Umbrella) { if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) Error("mismatched umbrella directories in submodule"); return OutOfDate; @@ -5890,7 +5958,8 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]); const FileEntry *File = nullptr; if (!FullFileName.empty()) - File = PP.getFileManager().getFile(FullFileName); + if (auto FE = PP.getFileManager().getFile(FullFileName)) + File = *FE; // FIXME: Stable encoding InclusionDirective::InclusionKind Kind @@ -6373,7 +6442,8 @@ QualType ASTReader::readTypeRecord(unsigned Index) { unsigned IndexTypeQuals = Record[2]; unsigned Idx = 3; llvm::APInt Size = ReadAPInt(Record, Idx); - return Context.getConstantArrayType(ElementType, Size, + Expr *SizeExpr = ReadExpr(*Loc.F); + return Context.getConstantArrayType(ElementType, Size, SizeExpr, ASM, IndexTypeQuals); } @@ -7413,6 +7483,11 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_OMP_ARRAY_SECTION: T = Context.OMPArraySectionTy; break; +#define SVE_TYPE(Name, Id, SingletonId) \ + case PREDEF_TYPE_##Id##_ID: \ + T = Context.SingletonId; \ + break; +#include "clang/Basic/AArch64SVEACLETypes.def" } assert(!T.isNull() && "Unknown predefined type"); @@ -8716,7 +8791,7 @@ void ASTReader::ReadLateParsedTemplates( /* In loop */) { FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++])); - auto LT = llvm::make_unique<LateParsedTemplate>(); + auto LT = std::make_unique<LateParsedTemplate>(); LT->D = GetDecl(LateParsedTemplates[Idx++]); ModuleFile *F = getOwningModuleFile(LT->D); @@ -9270,9 +9345,11 @@ ASTReader::ReadTemplateParameterList(ModuleFile &F, while (NumParams--) Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx)); - // TODO: Concepts + bool HasRequiresClause = Record[Idx++]; + Expr *RequiresClause = HasRequiresClause ? ReadExpr(F) : nullptr; + TemplateParameterList *TemplateParams = TemplateParameterList::Create( - getContext(), TemplateLoc, LAngleLoc, Params, RAngleLoc, nullptr); + getContext(), TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause); return TemplateParams; } @@ -9718,10 +9795,17 @@ void ASTReader::ReadComments() { } } NextCursor: - // De-serialized SourceLocations get negative FileIDs for other modules, - // potentially invalidating the original order. Sort it again. - llvm::sort(Comments, BeforeThanCompare<RawComment>(SourceMgr)); - Context.Comments.addDeserializedComments(Comments); + llvm::DenseMap<FileID, std::map<unsigned, RawComment *>> + FileToOffsetToComment; + for (RawComment *C : Comments) { + SourceLocation CommentLoc = C->getBeginLoc(); + if (CommentLoc.isValid()) { + std::pair<FileID, unsigned> Loc = + SourceMgr.getDecomposedLoc(CommentLoc); + if (Loc.first.isValid()) + Context.Comments.OrderedComments[Loc.first].emplace(Loc.second, C); + } + } } } @@ -12134,7 +12218,7 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache, StringRef isysroot, bool DisableValidation, bool AllowASTWithCompilerErrors, bool AllowConfigurationMismatch, bool ValidateSystemInputs, - bool UseGlobalIndex, + bool ValidateASTInputFilesContent, bool UseGlobalIndex, std::unique_ptr<llvm::Timer> ReadTimer) : Listener(DisableValidation ? cast<ASTReaderListener>(new SimpleASTReaderListener(PP)) @@ -12148,6 +12232,7 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache, AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), AllowConfigurationMismatch(AllowConfigurationMismatch), ValidateSystemInputs(ValidateSystemInputs), + ValidateASTInputFilesContent(ValidateASTInputFilesContent), UseGlobalIndex(UseGlobalIndex), CurrSwitchCaseStmts(&SwitchCaseStmts) { SourceMgr.setExternalSLocEntrySource(this); @@ -12184,7 +12269,7 @@ Expected<unsigned> ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor, ////===----------------------------------------------------------------------===// OMPClause *OMPClauseReader::readClause() { - OMPClause *C; + OMPClause *C = nullptr; switch (Record.readInt()) { case OMPC_if: C = new (Context) OMPIfClause(); @@ -12385,6 +12470,8 @@ OMPClause *OMPClauseReader::readClause() { C = OMPAllocateClause::CreateEmpty(Context, Record.readInt()); break; } + assert(C && "Unknown OMPClause type"); + Visit(C); C->setLocStart(Record.readSourceLocation()); C->setLocEnd(Record.readSourceLocation()); @@ -12412,6 +12499,7 @@ void OMPClauseReader::VisitOMPIfClause(OMPIfClause *C) { } void OMPClauseReader::VisitOMPFinalClause(OMPFinalClause *C) { + VisitOMPClauseWithPreInit(C); C->setCondition(Record.readSubExpr()); C->setLParenLoc(Record.readSourceLocation()); } @@ -12728,6 +12816,10 @@ void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) { C->setFinals(Vars); C->setStep(Record.readSubExpr()); C->setCalcStep(Record.readSubExpr()); + Vars.clear(); + for (unsigned I = 0; I != NumVars + 1; ++I) + Vars.push_back(Record.readSubExpr()); + C->setUsedExprs(Vars); } void OMPClauseReader::VisitOMPAlignedClause(OMPAlignedClause *C) { @@ -12904,16 +12996,19 @@ void OMPClauseReader::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) { } void OMPClauseReader::VisitOMPPriorityClause(OMPPriorityClause *C) { + VisitOMPClauseWithPreInit(C); C->setPriority(Record.readSubExpr()); C->setLParenLoc(Record.readSourceLocation()); } void OMPClauseReader::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { + VisitOMPClauseWithPreInit(C); C->setGrainsize(Record.readSubExpr()); C->setLParenLoc(Record.readSourceLocation()); } void OMPClauseReader::VisitOMPNumTasksClause(OMPNumTasksClause *C) { + VisitOMPClauseWithPreInit(C); C->setNumTasks(Record.readSubExpr()); C->setLParenLoc(Record.readSourceLocation()); } diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 3cac82ad421c0..9aa8c77c62319 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1390,10 +1390,11 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { if (uint64_t Val = Record.readInt()) { VD->setInit(Record.readExpr()); - if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3 + if (Val > 1) { EvaluatedStmt *Eval = VD->ensureEvaluatedStmt(); Eval->CheckedICE = true; - Eval->IsICE = Val == 3; + Eval->IsICE = (Val & 1) != 0; + Eval->HasConstantDestruction = (Val & 4) != 0; } } @@ -1655,55 +1656,11 @@ void ASTDeclReader::VisitUnresolvedUsingTypenameDecl( void ASTDeclReader::ReadCXXDefinitionData( struct CXXRecordDecl::DefinitionData &Data, const CXXRecordDecl *D) { + #define FIELD(Name, Width, Merge) \ + Data.Name = Record.readInt(); + #include "clang/AST/CXXRecordDeclDefinitionBits.def" + // Note: the caller has deserialized the IsLambda bit already. - Data.UserDeclaredConstructor = Record.readInt(); - Data.UserDeclaredSpecialMembers = Record.readInt(); - Data.Aggregate = Record.readInt(); - Data.PlainOldData = Record.readInt(); - Data.Empty = Record.readInt(); - Data.Polymorphic = Record.readInt(); - Data.Abstract = Record.readInt(); - Data.IsStandardLayout = Record.readInt(); - Data.IsCXX11StandardLayout = Record.readInt(); - Data.HasBasesWithFields = Record.readInt(); - Data.HasBasesWithNonStaticDataMembers = Record.readInt(); - Data.HasPrivateFields = Record.readInt(); - Data.HasProtectedFields = Record.readInt(); - Data.HasPublicFields = Record.readInt(); - Data.HasMutableFields = Record.readInt(); - Data.HasVariantMembers = Record.readInt(); - Data.HasOnlyCMembers = Record.readInt(); - Data.HasInClassInitializer = Record.readInt(); - Data.HasUninitializedReferenceMember = Record.readInt(); - Data.HasUninitializedFields = Record.readInt(); - Data.HasInheritedConstructor = Record.readInt(); - Data.HasInheritedAssignment = Record.readInt(); - Data.NeedOverloadResolutionForCopyConstructor = Record.readInt(); - Data.NeedOverloadResolutionForMoveConstructor = Record.readInt(); - Data.NeedOverloadResolutionForMoveAssignment = Record.readInt(); - Data.NeedOverloadResolutionForDestructor = Record.readInt(); - Data.DefaultedCopyConstructorIsDeleted = Record.readInt(); - Data.DefaultedMoveConstructorIsDeleted = Record.readInt(); - Data.DefaultedMoveAssignmentIsDeleted = Record.readInt(); - Data.DefaultedDestructorIsDeleted = Record.readInt(); - Data.HasTrivialSpecialMembers = Record.readInt(); - Data.HasTrivialSpecialMembersForCall = Record.readInt(); - Data.DeclaredNonTrivialSpecialMembers = Record.readInt(); - Data.DeclaredNonTrivialSpecialMembersForCall = Record.readInt(); - Data.HasIrrelevantDestructor = Record.readInt(); - Data.HasConstexprNonCopyMoveConstructor = Record.readInt(); - Data.HasDefaultedDefaultConstructor = Record.readInt(); - Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt(); - Data.HasConstexprDefaultConstructor = Record.readInt(); - Data.HasNonLiteralTypeFieldsOrBases = Record.readInt(); - Data.ComputedVisibleConversions = Record.readInt(); - Data.UserProvidedDefaultConstructor = Record.readInt(); - Data.DeclaredSpecialMembers = Record.readInt(); - Data.ImplicitCopyConstructorCanHaveConstParamForVBase = Record.readInt(); - Data.ImplicitCopyConstructorCanHaveConstParamForNonVBase = Record.readInt(); - Data.ImplicitCopyAssignmentHasConstParam = Record.readInt(); - Data.HasDeclaredCopyConstructorWithConstParam = Record.readInt(); - Data.HasDeclaredCopyAssignmentWithConstParam = Record.readInt(); Data.ODRHash = Record.readInt(); Data.HasODRHash = true; @@ -1718,7 +1675,9 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.VBases = ReadGlobalOffset(); Record.readUnresolvedSet(Data.Conversions); - Record.readUnresolvedSet(Data.VisibleConversions); + Data.ComputedVisibleConversions = Record.readInt(); + if (Data.ComputedVisibleConversions) + Record.readUnresolvedSet(Data.VisibleConversions); assert(Data.Definition && "Data.Definition should be already set!"); Data.FirstFriend = ReadDeclID(); @@ -1731,6 +1690,7 @@ void ASTDeclReader::ReadCXXDefinitionData( Lambda.CaptureDefault = Record.readInt(); Lambda.NumCaptures = Record.readInt(); Lambda.NumExplicitCaptures = Record.readInt(); + Lambda.HasKnownInternalLinkage = Record.readInt(); Lambda.ManglingNumber = Record.readInt(); Lambda.ContextDecl = ReadDeclID(); Lambda.Captures = (Capture *)Reader.getContext().Allocate( @@ -1791,63 +1751,17 @@ void ASTDeclReader::MergeDefinitionData( return; } - // FIXME: Move this out into a .def file? bool DetectedOdrViolation = false; -#define OR_FIELD(Field) DD.Field |= MergeDD.Field; -#define MATCH_FIELD(Field) \ + + #define FIELD(Name, Width, Merge) Merge(Name) + #define MERGE_OR(Field) DD.Field |= MergeDD.Field; + #define NO_MERGE(Field) \ DetectedOdrViolation |= DD.Field != MergeDD.Field; \ - OR_FIELD(Field) - MATCH_FIELD(UserDeclaredConstructor) - MATCH_FIELD(UserDeclaredSpecialMembers) - MATCH_FIELD(Aggregate) - MATCH_FIELD(PlainOldData) - MATCH_FIELD(Empty) - MATCH_FIELD(Polymorphic) - MATCH_FIELD(Abstract) - MATCH_FIELD(IsStandardLayout) - MATCH_FIELD(IsCXX11StandardLayout) - MATCH_FIELD(HasBasesWithFields) - MATCH_FIELD(HasBasesWithNonStaticDataMembers) - MATCH_FIELD(HasPrivateFields) - MATCH_FIELD(HasProtectedFields) - MATCH_FIELD(HasPublicFields) - MATCH_FIELD(HasMutableFields) - MATCH_FIELD(HasVariantMembers) - MATCH_FIELD(HasOnlyCMembers) - MATCH_FIELD(HasInClassInitializer) - MATCH_FIELD(HasUninitializedReferenceMember) - MATCH_FIELD(HasUninitializedFields) - MATCH_FIELD(HasInheritedConstructor) - MATCH_FIELD(HasInheritedAssignment) - MATCH_FIELD(NeedOverloadResolutionForCopyConstructor) - MATCH_FIELD(NeedOverloadResolutionForMoveConstructor) - MATCH_FIELD(NeedOverloadResolutionForMoveAssignment) - MATCH_FIELD(NeedOverloadResolutionForDestructor) - MATCH_FIELD(DefaultedCopyConstructorIsDeleted) - MATCH_FIELD(DefaultedMoveConstructorIsDeleted) - MATCH_FIELD(DefaultedMoveAssignmentIsDeleted) - MATCH_FIELD(DefaultedDestructorIsDeleted) - OR_FIELD(HasTrivialSpecialMembers) - OR_FIELD(HasTrivialSpecialMembersForCall) - OR_FIELD(DeclaredNonTrivialSpecialMembers) - OR_FIELD(DeclaredNonTrivialSpecialMembersForCall) - MATCH_FIELD(HasIrrelevantDestructor) - OR_FIELD(HasConstexprNonCopyMoveConstructor) - OR_FIELD(HasDefaultedDefaultConstructor) - MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr) - OR_FIELD(HasConstexprDefaultConstructor) - MATCH_FIELD(HasNonLiteralTypeFieldsOrBases) - // ComputedVisibleConversions is handled below. - MATCH_FIELD(UserProvidedDefaultConstructor) - OR_FIELD(DeclaredSpecialMembers) - MATCH_FIELD(ImplicitCopyConstructorCanHaveConstParamForVBase) - MATCH_FIELD(ImplicitCopyConstructorCanHaveConstParamForNonVBase) - MATCH_FIELD(ImplicitCopyAssignmentHasConstParam) - OR_FIELD(HasDeclaredCopyConstructorWithConstParam) - OR_FIELD(HasDeclaredCopyAssignmentWithConstParam) - MATCH_FIELD(IsLambda) -#undef OR_FIELD -#undef MATCH_FIELD + MERGE_OR(Field) + #include "clang/AST/CXXRecordDeclDefinitionBits.def" + NO_MERGE(IsLambda) + #undef NO_MERGE + #undef MERGE_OR if (DD.NumBases != MergeDD.NumBases || DD.NumVBases != MergeDD.NumVBases) DetectedOdrViolation = true; @@ -2087,7 +2001,6 @@ DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) { DeclID PatternID = ReadDeclID(); auto *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID)); TemplateParameterList *TemplateParams = Record.readTemplateParameterList(); - // FIXME handle associated constraints D->init(TemplatedDecl, TemplateParams); return PatternID; @@ -2253,7 +2166,8 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D) { RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D); - D->TemplateParams = Record.readTemplateParameterList(); + TemplateParameterList *Params = Record.readTemplateParameterList(); + D->TemplateParams = Params; D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); // These are read/set from/to the first declaration. @@ -2355,7 +2269,8 @@ void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl( VarTemplatePartialSpecializationDecl *D) { RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D); - D->TemplateParams = Record.readTemplateParameterList(); + TemplateParameterList *Params = Record.readTemplateParameterList(); + D->TemplateParams = Params; D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); // These are read/set from/to the first declaration. @@ -2371,6 +2286,7 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setDeclaredWithTypename(Record.readInt()); + // TODO: Concepts: Immediately introduced constraint if (Record.readInt()) D->setDefaultArgument(GetTypeSourceInfo()); } @@ -2748,6 +2664,10 @@ public: return Reader->ReadSourceRange(*F, Record, Idx); } + SourceLocation readSourceLocation() { + return Reader->ReadSourceLocation(*F, Record, Idx); + } + Expr *readExpr() { return Reader->ReadExpr(*F); } std::string readString() { @@ -2783,9 +2703,20 @@ Attr *ASTReader::ReadAttr(ModuleFile &M, const RecordData &Rec, // Kind is stored as a 1-based integer because 0 is used to indicate a null // Attr pointer. auto Kind = static_cast<attr::Kind>(V - 1); - SourceRange Range = Record.readSourceRange(); ASTContext &Context = getContext(); + IdentifierInfo *AttrName = Record.getIdentifierInfo(); + IdentifierInfo *ScopeName = Record.getIdentifierInfo(); + SourceRange AttrRange = Record.readSourceRange(); + SourceLocation ScopeLoc = Record.readSourceLocation(); + unsigned ParsedKind = Record.readInt(); + unsigned Syntax = Record.readInt(); + unsigned SpellingIndex = Record.readInt(); + + AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc, + AttributeCommonInfo::Kind(ParsedKind), + AttributeCommonInfo::Syntax(Syntax), SpellingIndex); + #include "clang/Serialization/AttrPCHRead.inc" assert(New && "Unable to decode attribute?"); @@ -4551,8 +4482,9 @@ void ASTDeclReader::UpdateDecl(Decl *D, break; case UPD_DECL_MARKED_OPENMP_THREADPRIVATE: - D->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(Reader.getContext(), - ReadSourceRange())); + D->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( + Reader.getContext(), ReadSourceRange(), + AttributeCommonInfo::AS_Pragma)); break; case UPD_DECL_MARKED_OPENMP_ALLOCATE: { @@ -4561,7 +4493,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, Expr *Allocator = Record.readExpr(); SourceRange SR = ReadSourceRange(); D->addAttr(OMPAllocateDeclAttr::CreateImplicit( - Reader.getContext(), AllocatorKind, Allocator, SR)); + Reader.getContext(), AllocatorKind, Allocator, SR, + AttributeCommonInfo::AS_Pragma)); break; } @@ -4574,12 +4507,16 @@ void ASTDeclReader::UpdateDecl(Decl *D, break; } - case UPD_DECL_MARKED_OPENMP_DECLARETARGET: + case UPD_DECL_MARKED_OPENMP_DECLARETARGET: { + OMPDeclareTargetDeclAttr::MapTypeTy MapType = + static_cast<OMPDeclareTargetDeclAttr::MapTypeTy>(Record.readInt()); + OMPDeclareTargetDeclAttr::DevTypeTy DevType = + static_cast<OMPDeclareTargetDeclAttr::DevTypeTy>(Record.readInt()); D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit( - Reader.getContext(), - static_cast<OMPDeclareTargetDeclAttr::MapTypeTy>(Record.readInt()), - ReadSourceRange())); + Reader.getContext(), MapType, DevType, ReadSourceRange(), + AttributeCommonInfo::AS_Pragma)); break; + } case UPD_ADDED_ATTR_TO_RECORD: AttrVec Attrs; diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index afaaa543bb27f..a275e0c305799 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -734,6 +734,24 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { E->setRParenLoc(ReadSourceLocation()); } +void ASTStmtReader::VisitConceptSpecializationExpr( + ConceptSpecializationExpr *E) { + VisitExpr(E); + unsigned NumTemplateArgs = Record.readInt(); + E->NestedNameSpec = Record.readNestedNameSpecifierLoc(); + E->TemplateKWLoc = Record.readSourceLocation(); + E->ConceptNameLoc = Record.readSourceLocation(); + E->FoundDecl = ReadDeclAs<NamedDecl>(); + E->NamedConcept.setPointer(ReadDeclAs<ConceptDecl>()); + const ASTTemplateArgumentListInfo *ArgsAsWritten = + Record.readASTTemplateArgumentListInfo(); + llvm::SmallVector<TemplateArgument, 4> Args; + for (unsigned I = 0; I < NumTemplateArgs; ++I) + Args.push_back(Record.readTemplateArgument()); + E->setTemplateArguments(ArgsAsWritten, Args); + E->NamedConcept.setInt(Record.readInt() == 1); +} + void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { VisitExpr(E); E->setLHS(Record.readSubExpr()); @@ -1422,6 +1440,13 @@ void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { E->Range = Record.readSourceRange(); } +void ASTStmtReader::VisitCXXRewrittenBinaryOperator( + CXXRewrittenBinaryOperator *E) { + VisitExpr(E); + E->CXXRewrittenBinaryOperatorBits.IsReversed = Record.readInt(); + E->SemanticForm = Record.readSubExpr(); +} + void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) { VisitExpr(E); @@ -2060,6 +2085,18 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) { for (unsigned i = 0; i < CollapsedNum; ++i) Sub.push_back(Record.readSubExpr()); D->setFinals(Sub); + Sub.clear(); + for (unsigned i = 0; i < CollapsedNum; ++i) + Sub.push_back(Record.readSubExpr()); + D->setDependentCounters(Sub); + Sub.clear(); + for (unsigned i = 0; i < CollapsedNum; ++i) + Sub.push_back(Record.readSubExpr()); + D->setDependentInits(Sub); + Sub.clear(); + for (unsigned i = 0; i < CollapsedNum; ++i) + Sub.push_back(Record.readSubExpr()); + D->setFinalsConditions(Sub); } void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) { @@ -2264,6 +2301,21 @@ void ASTStmtReader::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) { VisitOMPLoopDirective(D); } +void ASTStmtReader::VisitOMPMasterTaskLoopDirective( + OMPMasterTaskLoopDirective *D) { + VisitOMPLoopDirective(D); +} + +void ASTStmtReader::VisitOMPMasterTaskLoopSimdDirective( + OMPMasterTaskLoopSimdDirective *D) { + VisitOMPLoopDirective(D); +} + +void ASTStmtReader::VisitOMPParallelMasterTaskLoopDirective( + OMPParallelMasterTaskLoopDirective *D) { + VisitOMPLoopDirective(D); +} + void ASTStmtReader::VisitOMPDistributeDirective(OMPDistributeDirective *D) { VisitOMPLoopDirective(D); } @@ -3055,6 +3107,30 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; } + case STMT_OMP_MASTER_TASKLOOP_DIRECTIVE: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1]; + S = OMPMasterTaskLoopDirective::CreateEmpty(Context, NumClauses, + CollapsedNum, Empty); + break; + } + + case STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1]; + S = OMPMasterTaskLoopSimdDirective::CreateEmpty(Context, NumClauses, + CollapsedNum, Empty); + break; + } + + case STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1]; + S = OMPParallelMasterTaskLoopDirective::CreateEmpty(Context, NumClauses, + CollapsedNum, Empty); + break; + } + case STMT_OMP_DISTRIBUTE_DIRECTIVE: { unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1]; @@ -3183,6 +3259,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty); break; + case EXPR_CXX_REWRITTEN_BINARY_OPERATOR: + S = new (Context) CXXRewrittenBinaryOperator(Empty); + break; + case EXPR_CXX_CONSTRUCT: S = CXXConstructExpr::CreateEmpty( Context, @@ -3452,6 +3532,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_DEPENDENT_COAWAIT: S = new (Context) DependentCoawaitExpr(Empty); break; + + case EXPR_CONCEPT_SPECIALIZATION: + unsigned numTemplateArgs = Record[ASTStmtReader::NumExprFields]; + S = ConceptSpecializationExpr::Create(Context, Empty, numTemplateArgs); + break; + } // We hit a STMT_STOP, so we're done with this expression. diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 10946f9b0d985..28affedbbb30f 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -166,7 +166,7 @@ namespace clang { #define TYPE(Class, Base) \ case Type::Class: Visit##Class##Type(cast<Class##Type>(T)); break; #define ABSTRACT_TYPE(Class, Base) -#include "clang/AST/TypeNodes.def" +#include "clang/AST/TypeNodes.inc" } } } @@ -177,7 +177,7 @@ namespace clang { #define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T); #define ABSTRACT_TYPE(Class, Base) -#include "clang/AST/TypeNodes.def" +#include "clang/AST/TypeNodes.inc" }; } // namespace clang @@ -238,6 +238,7 @@ void ASTTypeWriter::VisitArrayType(const ArrayType *T) { void ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) { VisitArrayType(T); Record.AddAPInt(T->getSize()); + Record.AddStmt(const_cast<Expr*>(T->getSizeExpr())); Code = TYPE_CONSTANT_ARRAY; } @@ -1023,6 +1024,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(STMT_CXX_FOR_RANGE); RECORD(EXPR_CXX_OPERATOR_CALL); RECORD(EXPR_CXX_MEMBER_CALL); + RECORD(EXPR_CXX_REWRITTEN_BINARY_OPERATOR); RECORD(EXPR_CXX_CONSTRUCT); RECORD(EXPR_CXX_TEMPORARY_OBJECT); RECORD(EXPR_CXX_STATIC_CAST); @@ -1098,6 +1100,7 @@ void ASTWriter::WriteBlockInfoBlock() { BLOCK(INPUT_FILES_BLOCK); RECORD(INPUT_FILE); + RECORD(INPUT_FILE_HASH); // AST Top-Level Block. BLOCK(AST_BLOCK); @@ -1763,6 +1766,7 @@ struct InputFileEntry { bool IsTransient; bool BufferOverridden; bool IsTopLevelModuleMap; + uint32_t ContentHash[2]; }; } // namespace @@ -1786,6 +1790,13 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name unsigned IFAbbrevCode = Stream.EmitAbbrev(std::move(IFAbbrev)); + // Create input file hash abbreviation. + auto IFHAbbrev = std::make_shared<BitCodeAbbrev>(); + IFHAbbrev->Add(BitCodeAbbrevOp(INPUT_FILE_HASH)); + IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); + IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); + unsigned IFHAbbrevCode = Stream.EmitAbbrev(std::move(IFHAbbrev)); + // Get all ContentCache objects for files, sorted by whether the file is a // system one or not. System files go at the back, users files at the front. std::deque<InputFileEntry> SortedFiles; @@ -1804,12 +1815,31 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, InputFileEntry Entry; Entry.File = Cache->OrigEntry; - Entry.IsSystemFile = Cache->IsSystemFile; + Entry.IsSystemFile = isSystem(File.getFileCharacteristic()); Entry.IsTransient = Cache->IsTransient; Entry.BufferOverridden = Cache->BufferOverridden; Entry.IsTopLevelModuleMap = isModuleMap(File.getFileCharacteristic()) && File.getIncludeLoc().isInvalid(); - if (Cache->IsSystemFile) + + auto ContentHash = hash_code(-1); + if (PP->getHeaderSearchInfo() + .getHeaderSearchOpts() + .ValidateASTInputFilesContent) { + auto *MemBuff = Cache->getRawBuffer(); + if (MemBuff) + ContentHash = hash_value(MemBuff->getBuffer()); + else + // FIXME: The path should be taken from the FileEntryRef. + PP->Diag(SourceLocation(), diag::err_module_unable_to_hash_content) + << Entry.File->getName(); + } + auto CH = llvm::APInt(64, ContentHash); + Entry.ContentHash[0] = + static_cast<uint32_t>(CH.getLoBits(32).getZExtValue()); + Entry.ContentHash[1] = + static_cast<uint32_t>(CH.getHiBits(32).getZExtValue()); + + if (Entry.IsSystemFile) SortedFiles.push_back(Entry); else SortedFiles.push_front(Entry); @@ -1833,16 +1863,26 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, // Emit size/modification time for this file. // And whether this file was overridden. - RecordData::value_type Record[] = { - INPUT_FILE, - InputFileOffsets.size(), - (uint64_t)Entry.File->getSize(), - (uint64_t)getTimestampForOutput(Entry.File), - Entry.BufferOverridden, - Entry.IsTransient, - Entry.IsTopLevelModuleMap}; + { + RecordData::value_type Record[] = { + INPUT_FILE, + InputFileOffsets.size(), + (uint64_t)Entry.File->getSize(), + (uint64_t)getTimestampForOutput(Entry.File), + Entry.BufferOverridden, + Entry.IsTransient, + Entry.IsTopLevelModuleMap}; + + // FIXME: The path should be taken from the FileEntryRef. + EmitRecordWithPath(IFAbbrevCode, Record, Entry.File->getName()); + } - EmitRecordWithPath(IFAbbrevCode, Record, Entry.File->getName()); + // Emit content hash for this file. + { + RecordData::value_type Record[] = {INPUT_FILE_HASH, Entry.ContentHash[0], + Entry.ContentHash[1]}; + Stream.EmitRecordWithAbbrev(IFHAbbrevCode, Record); + } } Stream.ExitBlock(); @@ -2314,8 +2354,8 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // We add one to the size so that we capture the trailing NULL // that is required by llvm::MemoryBuffer::getMemBuffer (on // the reader side). - const llvm::MemoryBuffer *Buffer - = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); + const llvm::MemoryBuffer *Buffer = + Content->getBuffer(PP.getDiagnostics(), PP.getFileManager()); StringRef Name = Buffer->getBufferIdentifier(); Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record, StringRef(Name.data(), Name.size() + 1)); @@ -2329,7 +2369,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Include the implicit terminating null character in the on-disk buffer // if we're writing it uncompressed. const llvm::MemoryBuffer *Buffer = - Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); + Content->getBuffer(PP.getDiagnostics(), PP.getFileManager()); StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1); emitBlob(Stream, Blob, SLocBufferBlobCompressedAbbrv, SLocBufferBlobAbbrv); @@ -2506,7 +2546,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { MacroIdentifiers.push_back(Id.second); // Sort the set of macro definitions that need to be serialized by the // name of the macro, to provide a stable ordering. - llvm::sort(MacroIdentifiers, llvm::less_ptr<IdentifierInfo>()); + llvm::sort(MacroIdentifiers, llvm::deref<std::less<>>()); // Emit the macro directives as a list and associate the offset with the // identifier they belong to. @@ -3266,15 +3306,17 @@ void ASTWriter::WriteComments() { auto _ = llvm::make_scope_exit([this] { Stream.ExitBlock(); }); if (!PP->getPreprocessorOpts().WriteCommentListToPCH) return; - ArrayRef<RawComment *> RawComments = Context->Comments.getComments(); RecordData Record; - for (const auto *I : RawComments) { - Record.clear(); - AddSourceRange(I->getSourceRange(), Record); - Record.push_back(I->getKind()); - Record.push_back(I->isTrailingComment()); - Record.push_back(I->isAlmostTrailingComment()); - Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record); + for (const auto &FO : Context->Comments.OrderedComments) { + for (const auto &OC : FO.second) { + const RawComment *I = OC.second; + Record.clear(); + AddSourceRange(I->getSourceRange(), Record); + Record.push_back(I->getKind()); + Record.push_back(I->isTrailingComment()); + Record.push_back(I->isAlmostTrailingComment()); + Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record); + } } } @@ -3746,7 +3788,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP, IIs.push_back(ID.second); // Sort the identifiers lexicographically before getting them references so // that their order is stable. - llvm::sort(IIs, llvm::less_ptr<IdentifierInfo>()); + llvm::sort(IIs, llvm::deref<std::less<>>()); for (const IdentifierInfo *II : IIs) if (Trait.isInterestingNonMacroIdentifier(II)) getIdentifierRef(II); @@ -4519,7 +4561,14 @@ void ASTRecordWriter::AddAttr(const Attr *A) { if (!A) return Record.push_back(0); Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs + + Record.AddIdentifierRef(A->getAttrName()); + Record.AddIdentifierRef(A->getScopeName()); Record.AddSourceRange(A->getRange()); + Record.AddSourceLocation(A->getScopeLoc()); + Record.push_back(A->getParsedKind()); + Record.push_back(A->getSyntax()); + Record.push_back(A->getAttributeSpellingListIndexRaw()); #include "clang/Serialization/AttrPCHWrite.inc" } @@ -4922,7 +4971,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, IIs.push_back(II); } // Sort the identifiers to visit based on their name. - llvm::sort(IIs, llvm::less_ptr<IdentifierInfo>()); + llvm::sort(IIs, llvm::deref<std::less<>>()); for (const IdentifierInfo *II : IIs) { for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II), DEnd = SemaRef.IdResolver.end(); @@ -6022,10 +6071,16 @@ void ASTRecordWriter::AddTemplateParameterList( AddSourceLocation(TemplateParams->getTemplateLoc()); AddSourceLocation(TemplateParams->getLAngleLoc()); AddSourceLocation(TemplateParams->getRAngleLoc()); - // TODO: Concepts + Record->push_back(TemplateParams->size()); for (const auto &P : *TemplateParams) AddDeclRef(P); + if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) { + Record->push_back(true); + AddStmt(const_cast<Expr*>(RequiresClause)); + } else { + Record->push_back(false); + } } /// Emit a template argument list. @@ -6130,54 +6185,10 @@ void ASTRecordWriter::AddCXXCtorInitializers( void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { auto &Data = D->data(); Record->push_back(Data.IsLambda); - Record->push_back(Data.UserDeclaredConstructor); - Record->push_back(Data.UserDeclaredSpecialMembers); - Record->push_back(Data.Aggregate); - Record->push_back(Data.PlainOldData); - Record->push_back(Data.Empty); - Record->push_back(Data.Polymorphic); - Record->push_back(Data.Abstract); - Record->push_back(Data.IsStandardLayout); - Record->push_back(Data.IsCXX11StandardLayout); - Record->push_back(Data.HasBasesWithFields); - Record->push_back(Data.HasBasesWithNonStaticDataMembers); - Record->push_back(Data.HasPrivateFields); - Record->push_back(Data.HasProtectedFields); - Record->push_back(Data.HasPublicFields); - Record->push_back(Data.HasMutableFields); - Record->push_back(Data.HasVariantMembers); - Record->push_back(Data.HasOnlyCMembers); - Record->push_back(Data.HasInClassInitializer); - Record->push_back(Data.HasUninitializedReferenceMember); - Record->push_back(Data.HasUninitializedFields); - Record->push_back(Data.HasInheritedConstructor); - Record->push_back(Data.HasInheritedAssignment); - Record->push_back(Data.NeedOverloadResolutionForCopyConstructor); - Record->push_back(Data.NeedOverloadResolutionForMoveConstructor); - Record->push_back(Data.NeedOverloadResolutionForMoveAssignment); - Record->push_back(Data.NeedOverloadResolutionForDestructor); - Record->push_back(Data.DefaultedCopyConstructorIsDeleted); - Record->push_back(Data.DefaultedMoveConstructorIsDeleted); - Record->push_back(Data.DefaultedMoveAssignmentIsDeleted); - Record->push_back(Data.DefaultedDestructorIsDeleted); - Record->push_back(Data.HasTrivialSpecialMembers); - Record->push_back(Data.HasTrivialSpecialMembersForCall); - Record->push_back(Data.DeclaredNonTrivialSpecialMembers); - Record->push_back(Data.DeclaredNonTrivialSpecialMembersForCall); - Record->push_back(Data.HasIrrelevantDestructor); - Record->push_back(Data.HasConstexprNonCopyMoveConstructor); - Record->push_back(Data.HasDefaultedDefaultConstructor); - Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr); - Record->push_back(Data.HasConstexprDefaultConstructor); - Record->push_back(Data.HasNonLiteralTypeFieldsOrBases); - Record->push_back(Data.ComputedVisibleConversions); - Record->push_back(Data.UserProvidedDefaultConstructor); - Record->push_back(Data.DeclaredSpecialMembers); - Record->push_back(Data.ImplicitCopyConstructorCanHaveConstParamForVBase); - Record->push_back(Data.ImplicitCopyConstructorCanHaveConstParamForNonVBase); - Record->push_back(Data.ImplicitCopyAssignmentHasConstParam); - Record->push_back(Data.HasDeclaredCopyConstructorWithConstParam); - Record->push_back(Data.HasDeclaredCopyAssignmentWithConstParam); + + #define FIELD(Name, Width, Merge) \ + Record->push_back(Data.Name); + #include "clang/AST/CXXRecordDeclDefinitionBits.def" // getODRHash will compute the ODRHash if it has not been previously computed. Record->push_back(D->getODRHash()); @@ -6199,7 +6210,9 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { AddCXXBaseSpecifiers(Data.vbases()); AddUnresolvedSet(Data.Conversions.get(*Writer->Context)); - AddUnresolvedSet(Data.VisibleConversions.get(*Writer->Context)); + Record->push_back(Data.ComputedVisibleConversions); + if (Data.ComputedVisibleConversions) + AddUnresolvedSet(Data.VisibleConversions.get(*Writer->Context)); // Data.Definition is the owning decl, no need to write it. AddDeclRef(D->getFirstFriend()); @@ -6211,6 +6224,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Record->push_back(Lambda.CaptureDefault); Record->push_back(Lambda.NumCaptures); Record->push_back(Lambda.NumExplicitCaptures); + Record->push_back(Lambda.HasKnownInternalLinkage); Record->push_back(Lambda.ManglingNumber); AddDeclRef(D->getLambdaContextDecl()); AddTypeSourceInfo(Lambda.MethodTyInfo); @@ -6627,6 +6641,7 @@ void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) { } void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) { + VisitOMPClauseWithPreInit(C); Record.AddStmt(C->getCondition()); Record.AddSourceLocation(C->getLParenLoc()); } @@ -6846,6 +6861,8 @@ void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) { } Record.AddStmt(C->getStep()); Record.AddStmt(C->getCalcStep()); + for (auto *VE : C->used_expressions()) + Record.AddStmt(VE); } void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) { @@ -6962,16 +6979,19 @@ void OMPClauseWriter::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) { } void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) { + VisitOMPClauseWithPreInit(C); Record.AddStmt(C->getPriority()); Record.AddSourceLocation(C->getLParenLoc()); } void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { + VisitOMPClauseWithPreInit(C); Record.AddStmt(C->getGrainsize()); Record.AddSourceLocation(C->getLParenLoc()); } void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) { + VisitOMPClauseWithPreInit(C); Record.AddStmt(C->getNumTasks()); Record.AddSourceLocation(C->getLParenLoc()); } diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index b71315505de90..039b57f88e736 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -968,7 +968,14 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(D->getLinkageInternal()); if (D->getInit()) { - Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2)); + if (!D->isInitKnownICE()) + Record.push_back(1); + else { + Record.push_back( + 2 | + (D->isInitICE() ? 1 : 0) | + (D->ensureEvaluatedStmt()->HasConstantDestruction ? 4 : 0)); + } Record.AddStmt(D->getInit()); } else { Record.push_back(0); @@ -1601,7 +1608,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { VisitTypeDecl(D); Record.push_back(D->wasDeclaredWithTypename()); - + // TODO: Concepts - constrained parameters. bool OwnsDefaultArg = D->hasDefaultArgument() && !D->defaultArgumentWasInherited(); Record.push_back(OwnsDefaultArg); @@ -1631,6 +1638,7 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK; } else { + // TODO: Concepts - constrained parameters. // Rest of NonTypeTemplateParmDecl. Record.push_back(D->isParameterPack()); bool OwnsDefaultArg = D->hasDefaultArgument() && @@ -1660,6 +1668,7 @@ void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { Record.AddTemplateParameterList(D->getExpansionTemplateParameters(I)); Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK; } else { + // TODO: Concepts - constrained parameters. // Rest of TemplateTemplateParmDecl. Record.push_back(D->isParameterPack()); bool OwnsDefaultArg = D->hasDefaultArgument() && @@ -2140,7 +2149,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // ImplicitParamKind Abv->Add(BitCodeAbbrevOp(0)); // EscapingByref Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // IsInitICE (local) + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // IsInitICE (local) Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // VarKind (local enum) // Type Source Info Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 4fbcbaabe74bb..c39d4d39bcdf8 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -388,6 +388,24 @@ void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) { Code = serialization::EXPR_DEPENDENT_COAWAIT; } +void ASTStmtWriter::VisitConceptSpecializationExpr( + ConceptSpecializationExpr *E) { + VisitExpr(E); + ArrayRef<TemplateArgument> TemplateArgs = E->getTemplateArguments(); + Record.push_back(TemplateArgs.size()); + Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc()); + Record.AddSourceLocation(E->getTemplateKWLoc()); + Record.AddSourceLocation(E->getConceptNameLoc()); + Record.AddDeclRef(E->getFoundDecl()); + Record.AddDeclRef(E->getNamedConcept()); + Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten()); + for (const TemplateArgument &Arg : TemplateArgs) + Record.AddTemplateArgument(Arg); + Record.push_back(E->isSatisfied()); + Code = serialization::EXPR_CONCEPT_SPECIALIZATION; +} + + void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) { VisitStmt(S); // NumCaptures @@ -1357,6 +1375,14 @@ void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { Code = serialization::EXPR_CXX_MEMBER_CALL; } +void ASTStmtWriter::VisitCXXRewrittenBinaryOperator( + CXXRewrittenBinaryOperator *E) { + VisitExpr(E); + Record.push_back(E->isReversed()); + Record.AddStmt(E->getSemanticForm()); + Code = serialization::EXPR_CXX_REWRITTEN_BINARY_OPERATOR; +} + void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) { VisitExpr(E); @@ -1995,6 +2021,12 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) { for (auto I : D->finals()) { Record.AddStmt(I); } + for (Stmt *S : D->dependent_counters()) + Record.AddStmt(S); + for (Stmt *S : D->dependent_inits()) + Record.AddStmt(S); + for (Stmt *S : D->finals_conditions()) + Record.AddStmt(S); } void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) { @@ -2217,6 +2249,24 @@ void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) { Code = serialization::STMT_OMP_TASKLOOP_SIMD_DIRECTIVE; } +void ASTStmtWriter::VisitOMPMasterTaskLoopDirective( + OMPMasterTaskLoopDirective *D) { + VisitOMPLoopDirective(D); + Code = serialization::STMT_OMP_MASTER_TASKLOOP_DIRECTIVE; +} + +void ASTStmtWriter::VisitOMPMasterTaskLoopSimdDirective( + OMPMasterTaskLoopSimdDirective *D) { + VisitOMPLoopDirective(D); + Code = serialization::STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE; +} + +void ASTStmtWriter::VisitOMPParallelMasterTaskLoopDirective( + OMPParallelMasterTaskLoopDirective *D) { + VisitOMPLoopDirective(D); + Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPDistributeDirective(OMPDistributeDirective *D) { VisitOMPLoopDirective(D); Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE; diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp index 2db8f830c46de..54ab17681ee9e 100644 --- a/lib/Serialization/GlobalModuleIndex.cpp +++ b/lib/Serialization/GlobalModuleIndex.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// - #include "ASTReaderInternals.h" #include "clang/Basic/FileManager.h" #include "clang/Lex/HeaderSearch.h" @@ -21,10 +20,12 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Bitstream/BitstreamWriter.h" #include "llvm/Support/DJB.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" #include "llvm/Support/LockFileManager.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/OnDiskHashTable.h" @@ -657,7 +658,7 @@ llvm::Error GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { Idx += Length; // Find the imported module file. - const FileEntry *DependsOnFile + auto DependsOnFile = FileMgr.getFile(ImportedFile, /*OpenFile=*/false, /*CacheFailure=*/false); @@ -669,11 +670,11 @@ llvm::Error GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Save the information in ImportedModuleFileInfo so we can verify after // loading all pcms. ImportedModuleFiles.insert(std::make_pair( - DependsOnFile, ImportedModuleFileInfo(StoredSize, StoredModTime, - StoredSignature))); + *DependsOnFile, ImportedModuleFileInfo(StoredSize, StoredModTime, + StoredSignature))); // Record the dependency. - unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID; + unsigned DependsOnID = getModuleFileInfo(*DependsOnFile).ID; getModuleFileInfo(File).Dependencies.push_back(DependsOnID); } @@ -894,12 +895,12 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, } // If we can't find the module file, skip it. - const FileEntry *ModuleFile = FileMgr.getFile(D->path()); + auto ModuleFile = FileMgr.getFile(D->path()); if (!ModuleFile) continue; // Load this module file. - if (llvm::Error Err = Builder.loadModuleFile(ModuleFile)) + if (llvm::Error Err = Builder.loadModuleFile(*ModuleFile)) return Err; } @@ -912,37 +913,9 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, "failed writing index"); } - // Write the global index file to a temporary file. - llvm::SmallString<128> IndexTmpPath; - int TmpFD; - if (llvm::sys::fs::createUniqueFile(IndexPath + "-%%%%%%%%", TmpFD, - IndexTmpPath)) - return llvm::createStringError(std::errc::io_error, - "failed creating unique file"); - - // Open the temporary global index file for output. - llvm::raw_fd_ostream Out(TmpFD, true); - if (Out.has_error()) - return llvm::createStringError(Out.error(), "failed outputting to stream"); - - // Write the index. - Out.write(OutputBuffer.data(), OutputBuffer.size()); - Out.close(); - if (Out.has_error()) - return llvm::createStringError(Out.error(), "failed writing to stream"); - - // Remove the old index file. It isn't relevant any more. - llvm::sys::fs::remove(IndexPath); - - // Rename the newly-written index file to the proper name. - if (std::error_code Err = llvm::sys::fs::rename(IndexTmpPath, IndexPath)) { - // Remove the file on failure, don't check whether removal succeeded. - llvm::sys::fs::remove(IndexTmpPath); - return llvm::createStringError(Err, "failed renaming file \"%s\" to \"%s\"", - IndexTmpPath.c_str(), IndexPath.c_str()); - } - - return llvm::Error::success(); + return llvm::writeFileAtomically( + (IndexPath + "-%%%%%%%%").str(), IndexPath, + llvm::StringRef(OutputBuffer.data(), OutputBuffer.size())); } namespace { diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp index 6ae0c4f575519..4b9f20fca4f80 100644 --- a/lib/Serialization/ModuleManager.cpp +++ b/lib/Serialization/ModuleManager.cpp @@ -42,10 +42,10 @@ using namespace clang; using namespace serialization; ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const { - const FileEntry *Entry = FileMgr.getFile(Name, /*OpenFile=*/false, - /*CacheFailure=*/false); + auto Entry = FileMgr.getFile(Name, /*OpenFile=*/false, + /*CacheFailure=*/false); if (Entry) - return lookup(Entry); + return lookup(*Entry); return nullptr; } @@ -68,9 +68,11 @@ ModuleFile *ModuleManager::lookup(const FileEntry *File) const { std::unique_ptr<llvm::MemoryBuffer> ModuleManager::lookupBuffer(StringRef Name) { - const FileEntry *Entry = FileMgr.getFile(Name, /*OpenFile=*/false, - /*CacheFailure=*/false); - return std::move(InMemoryBuffers[Entry]); + auto Entry = FileMgr.getFile(Name, /*OpenFile=*/false, + /*CacheFailure=*/false); + if (!Entry) + return nullptr; + return std::move(InMemoryBuffers[*Entry]); } static bool checkSignature(ASTFileSignature Signature, @@ -142,7 +144,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, } // Allocate a new module. - auto NewModule = llvm::make_unique<ModuleFile>(Type, Generation); + auto NewModule = std::make_unique<ModuleFile>(Type, Generation); NewModule->Index = Chain.size(); NewModule->FileName = FileName.str(); NewModule->File = Entry; @@ -183,9 +185,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, Buf = llvm::MemoryBuffer::getSTDIN(); } else { // Get a buffer of the file and close the file descriptor when done. - Buf = FileMgr.getBufferForFile(NewModule->File, - /*isVolatile=*/false, - /*ShouldClose=*/true); + Buf = FileMgr.getBufferForFile(NewModule->File, /*isVolatile=*/false); } if (!Buf) { @@ -202,13 +202,8 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, // Read the signature eagerly now so that we can check it. Avoid calling // ReadSignature unless there's something to check though. if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data), - ExpectedSignature, ErrorStr)) { - // Try to remove the buffer. If it can't be removed, then it was already - // validated by this process. - if (!getModuleCache().tryToDropPCM(NewModule->FileName)) - FileMgr.invalidateCache(NewModule->File); + ExpectedSignature, ErrorStr)) return OutOfDate; - } // We're keeping this module. Store it everywhere. Module = Modules[Entry] = NewModule.get(); @@ -447,9 +442,13 @@ bool ModuleManager::lookupModuleFile(StringRef FileName, // Open the file immediately to ensure there is no race between stat'ing and // opening the file. - File = FileMgr.getFile(FileName, /*OpenFile=*/true, /*CacheFailure=*/false); - if (!File) + auto FileOrErr = FileMgr.getFile(FileName, /*OpenFile=*/true, + /*CacheFailure=*/false); + if (!FileOrErr) { + File = nullptr; return false; + } + File = *FileOrErr; if ((ExpectedSize && ExpectedSize != File->getSize()) || (ExpectedModTime && ExpectedModTime != File->getModificationTime())) diff --git a/lib/Serialization/PCHContainerOperations.cpp b/lib/Serialization/PCHContainerOperations.cpp index 00063d64f3f28..d4990fce2d99d 100644 --- a/lib/Serialization/PCHContainerOperations.cpp +++ b/lib/Serialization/PCHContainerOperations.cpp @@ -54,7 +54,7 @@ std::unique_ptr<ASTConsumer> RawPCHContainerWriter::CreatePCHContainerGenerator( CompilerInstance &CI, const std::string &MainFileName, const std::string &OutputFileName, std::unique_ptr<llvm::raw_pwrite_stream> OS, std::shared_ptr<PCHBuffer> Buffer) const { - return llvm::make_unique<RawPCHContainerGenerator>(std::move(OS), Buffer); + return std::make_unique<RawPCHContainerGenerator>(std::move(OS), Buffer); } StringRef @@ -63,6 +63,6 @@ RawPCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const { } PCHContainerOperations::PCHContainerOperations() { - registerWriter(llvm::make_unique<RawPCHContainerWriter>()); - registerReader(llvm::make_unique<RawPCHContainerReader>()); + registerWriter(std::make_unique<RawPCHContainerWriter>()); + registerReader(std::make_unique<RawPCHContainerReader>()); } |