Author: rsmith Date: Mon Aug 17 02:13:32 2015 New Revision: 245199 URL: http://llvm.org/viewvc/llvm-project?rev=245199&view=rev Log: [modules] When explicitly building a module file, don't include timestamps in the produced pcm file for stable file creation across distributed build systems.
Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h cfe/trunk/include/clang/Serialization/ASTWriter.h cfe/trunk/include/clang/Serialization/Module.h cfe/trunk/lib/Frontend/CompilerInstance.cpp cfe/trunk/lib/Frontend/FrontendActions.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/lib/Serialization/ASTReaderInternals.h cfe/trunk/lib/Serialization/ASTWriter.cpp cfe/trunk/lib/Serialization/GeneratePCH.cpp cfe/trunk/test/Modules/explicit-build-missing-files.cpp cfe/trunk/test/Modules/module-map-path-hash.cpp Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original) +++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Mon Aug 17 02:13:32 2015 @@ -147,6 +147,8 @@ public: ///< dumps in AST dumps. unsigned ASTDumpLookups : 1; ///< Whether we include lookup table ///< dumps in AST dumps. + unsigned BuildingImplicitModule : 1; ///< Whether we are performing an + ///< implicit module build. CodeCompleteOptions CodeCompleteOpts; @@ -263,6 +265,7 @@ public: FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false), SkipFunctionBodies(false), UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), ASTDumpDecls(false), ASTDumpLookups(false), + BuildingImplicitModule(false), ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None), ProgramAction(frontend::ParseSyntaxOnly) {} Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original) +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Mon Aug 17 02:13:32 2015 @@ -119,6 +119,12 @@ private: /// \brief The base directory for any relative paths we emit. std::string BaseDirectory; + /// \brief Indicates whether timestamps should be written to the produced + /// module file. This is the case for files implicitly written to the + /// module cache, where we need the timestamps to determine if the module + /// file is up to date, but not otherwise. + bool IncludeTimestamps; + /// \brief Indicates when the AST writing is actively performing /// serialization, rather than just queueing updates. bool WritingAST; @@ -569,11 +575,16 @@ private: public: /// \brief Create a new precompiled header writer that outputs to /// the given bitstream. - ASTWriter(llvm::BitstreamWriter &Stream); + ASTWriter(llvm::BitstreamWriter &Stream, bool IncludeTimestamps = true); ~ASTWriter() override; const LangOptions &getLangOpts() const; + /// \brief Get a timestamp for output into the AST file. The actual timestamp + /// of the specified file may be ignored if we have been instructed to not + /// include timestamps in the output file. + time_t getTimestampForOutput(const FileEntry *E) const; + /// \brief Write a precompiled header for the given semantic analysis. /// /// \param SemaRef a reference to the semantic analysis object that processed @@ -892,7 +903,8 @@ public: PCHGenerator(const Preprocessor &PP, StringRef OutputFile, clang::Module *Module, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer, - bool AllowASTWithErrors = false); + bool AllowASTWithErrors = false, + bool IncludeTimestamps = true); ~PCHGenerator() override; void InitializeSema(Sema &S) override { SemaPtr = &S; } void HandleTranslationUnit(ASTContext &Ctx) override; Modified: cfe/trunk/include/clang/Serialization/Module.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/Module.h (original) +++ cfe/trunk/include/clang/Serialization/Module.h Mon Aug 17 02:13:32 2015 @@ -152,6 +152,9 @@ public: /// \brief Whether this precompiled header is a relocatable PCH file. bool RelocatablePCH; + /// \brief Whether timestamps are included in this module file. + bool HasTimestamps; + /// \brief The file entry for the module file. const FileEntry *File; Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Mon Aug 17 02:13:32 2015 @@ -913,6 +913,7 @@ static bool compileModuleImpl(CompilerIn FrontendOpts.OutputFile = ModuleFileName.str(); FrontendOpts.DisableFree = false; FrontendOpts.GenerateGlobalModuleIndex = false; + FrontendOpts.BuildingImplicitModule = true; FrontendOpts.Inputs.clear(); InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/FrontendActions.cpp (original) +++ cfe/trunk/lib/Frontend/FrontendActions.cpp Mon Aug 17 02:13:32 2015 @@ -137,7 +137,9 @@ GenerateModuleAction::CreateASTConsumer( auto Buffer = std::make_shared<PCHBuffer>(); std::vector<std::unique_ptr<ASTConsumer>> Consumers; Consumers.push_back(llvm::make_unique<PCHGenerator>( - CI.getPreprocessor(), OutputFile, Module, Sysroot, Buffer)); + CI.getPreprocessor(), OutputFile, Module, Sysroot, Buffer, + /*AllowASTWithErrors*/false, + /*IncludeTimestamps*/+CI.getFrontendOpts().BuildingImplicitModule)); Consumers.push_back( CI.getPCHContainerWriter().CreatePCHContainerGenerator( CI.getDiagnostics(), CI.getHeaderSearchOpts(), Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Aug 17 02:13:32 2015 @@ -1500,13 +1500,14 @@ unsigned HeaderFileInfoTrait::ComputeHas HeaderFileInfoTrait::internal_key_type HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) { - internal_key_type ikey = { FE->getSize(), FE->getModificationTime(), - FE->getName(), /*Imported*/false }; + internal_key_type ikey = {FE->getSize(), + M.HasTimestamps ? FE->getModificationTime() : 0, + FE->getName(), /*Imported*/ false}; return ikey; } bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { - if (a.Size != b.Size || a.ModTime != b.ModTime) + if (a.Size != b.Size || (a.ModTime && b.ModTime && a.ModTime != b.ModTime)) return false; if (llvm::sys::path::is_absolute(a.Filename) && @@ -1976,14 +1977,9 @@ InputFile ASTReader::getInputFile(Module // have inconsistent modification times that sometimes // erroneously trigger this error-handling path. // - // This also happens in networked file systems, so disable this - // check if validation is disabled or if we have an explicitly - // built PCM file. - // - // FIXME: Should we also do this for PCH files? They could also - // reasonably get shared across a network during a distributed build. - (StoredTime != File->getModificationTime() && !DisableValidation && - F.Kind != MK_ExplicitModule) + // FIXME: This probably also breaks HeaderFileInfo lookups on Windows. + (StoredTime && StoredTime != File->getModificationTime() && + !DisableValidation) #endif )) { if (Complain) { @@ -2164,7 +2160,7 @@ ASTReader::ReadControlBlock(ModuleFile & return VersionMismatch; } - bool hasErrors = Record[5]; + bool hasErrors = Record[6]; if (hasErrors && !DisableValidation && !AllowASTWithCompilerErrors) { Diag(diag::err_pch_with_compiler_errors); return HadErrors; @@ -2175,6 +2171,8 @@ ASTReader::ReadControlBlock(ModuleFile & if (F.RelocatablePCH) F.BaseDirectory = isysroot.empty() ? "/" : isysroot; + F.HasTimestamps = Record[5]; + const std::string &CurBranch = getClangFullRepositoryVersion(); StringRef ASTBranch = Blob; if (StringRef(CurBranch) != ASTBranch && !DisableValidation) { Modified: cfe/trunk/lib/Serialization/ASTReaderInternals.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderInternals.h?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderInternals.h (original) +++ cfe/trunk/lib/Serialization/ASTReaderInternals.h Mon Aug 17 02:13:32 2015 @@ -226,7 +226,7 @@ public: : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) { } static hash_value_type ComputeHash(internal_key_ref ikey); - static internal_key_type GetInternalKey(const FileEntry *FE); + internal_key_type GetInternalKey(const FileEntry *FE); bool EqualKey(internal_key_ref a, internal_key_ref b); static std::pair<unsigned, unsigned> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Aug 17 02:13:32 2015 @@ -1148,6 +1148,7 @@ void ASTWriter::WriteControlBlock(Prepro MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang maj. MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang min. MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable + MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Timestamps MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Errors MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag unsigned MetadataAbbrevCode = Stream.EmitAbbrev(MetadataAbbrev); @@ -1159,6 +1160,7 @@ void ASTWriter::WriteControlBlock(Prepro assert((!WritingModule || isysroot.empty()) && "writing module as a relocatable PCH?"); Record.push_back(!isysroot.empty()); + Record.push_back(IncludeTimestamps); Record.push_back(ASTHasCompilerErrors); Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record, getClangFullRepositoryVersion()); @@ -1248,7 +1250,7 @@ void ASTWriter::WriteControlBlock(Prepro Record.push_back((unsigned)M->Kind); // FIXME: Stable encoding AddSourceLocation(M->ImportLoc, Record); Record.push_back(M->File->getSize()); - Record.push_back(M->File->getModificationTime()); + Record.push_back(getTimestampForOutput(M->File)); Record.push_back(M->Signature); AddPath(M->FileName, Record); } @@ -1512,7 +1514,7 @@ void ASTWriter::WriteInputFiles(SourceMa // Emit size/modification time for this file. Record.push_back(Entry.File->getSize()); - Record.push_back(Entry.File->getModificationTime()); + Record.push_back(getTimestampForOutput(Entry.File)); // Whether this file was overridden. Record.push_back(Entry.BufferOverridden); @@ -1624,15 +1626,12 @@ namespace { typedef unsigned hash_value_type; typedef unsigned offset_type; - static hash_value_type ComputeHash(key_type_ref key) { + hash_value_type ComputeHash(key_type_ref key) { // The hash is based only on size/time of the file, so that the reader can // match even when symlinking or excess path elements ("foo/../", "../") // change the form of the name. However, complete path is still the key. - // - // FIXME: Using the mtime here will cause problems for explicit module - // imports. return llvm::hash_combine(key.FE->getSize(), - key.FE->getModificationTime()); + Writer.getTimestampForOutput(key.FE)); } std::pair<unsigned,unsigned> @@ -1653,7 +1652,7 @@ namespace { endian::Writer<little> LE(Out); LE.write<uint64_t>(key.FE->getSize()); KeyLen -= 8; - LE.write<uint64_t>(key.FE->getModificationTime()); + LE.write<uint64_t>(Writer.getTimestampForOutput(key.FE)); KeyLen -= 8; Out.write(key.Filename, KeyLen); } @@ -4058,22 +4057,21 @@ void ASTWriter::SetSelectorOffset(Select SelectorOffsets[ID - FirstSelectorID] = Offset; } -ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) +ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream, bool IncludeTimestamps) : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr), - WritingModule(nullptr), WritingAST(false), - DoneWritingDeclsAndTypes(false), ASTHasCompilerErrors(false), - FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID), - FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), - FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID), - FirstMacroID(NUM_PREDEF_MACRO_IDS), NextMacroID(FirstMacroID), - FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS), + WritingModule(nullptr), IncludeTimestamps(IncludeTimestamps), + WritingAST(false), DoneWritingDeclsAndTypes(false), + ASTHasCompilerErrors(false), FirstDeclID(NUM_PREDEF_DECL_IDS), + NextDeclID(FirstDeclID), FirstTypeID(NUM_PREDEF_TYPE_IDS), + NextTypeID(FirstTypeID), FirstIdentID(NUM_PREDEF_IDENT_IDS), + NextIdentID(FirstIdentID), FirstMacroID(NUM_PREDEF_MACRO_IDS), + NextMacroID(FirstMacroID), FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS), NextSubmoduleID(FirstSubmoduleID), FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID), CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), NumVisibleDeclContexts(0), NextCXXBaseSpecifiersID(1), NextCXXCtorInitializersID(1), - TypeExtQualAbbrev(0), - TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0), + TypeExtQualAbbrev(0), TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0), DeclVarAbbrev(0), DeclFieldAbbrev(0), DeclEnumAbbrev(0), @@ -4090,6 +4088,10 @@ const LangOptions &ASTWriter::getLangOpt return Context->getLangOpts(); } +time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const { + return IncludeTimestamps ? E->getModificationTime() : 0; +} + void ASTWriter::WriteAST(Sema &SemaRef, const std::string &OutputFile, Module *WritingModule, StringRef isysroot, Modified: cfe/trunk/lib/Serialization/GeneratePCH.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/GeneratePCH.cpp?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/GeneratePCH.cpp (original) +++ cfe/trunk/lib/Serialization/GeneratePCH.cpp Mon Aug 17 02:13:32 2015 @@ -26,9 +26,10 @@ using namespace clang; PCHGenerator::PCHGenerator(const Preprocessor &PP, StringRef OutputFile, clang::Module *Module, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer, - bool AllowASTWithErrors) + bool AllowASTWithErrors, bool IncludeTimestamps) : PP(PP), OutputFile(OutputFile), Module(Module), isysroot(isysroot.str()), - SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data), Writer(Stream), + SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data), + Writer(Stream, IncludeTimestamps), AllowASTWithErrors(AllowASTWithErrors) { Buffer->IsComplete = false; } Modified: cfe/trunk/test/Modules/explicit-build-missing-files.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/explicit-build-missing-files.cpp?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/test/Modules/explicit-build-missing-files.cpp (original) +++ cfe/trunk/test/Modules/explicit-build-missing-files.cpp Mon Aug 17 02:13:32 2015 @@ -21,6 +21,10 @@ // RUN: rm %t/other.modulemap // RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s // RUN: not %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s -DERRORS 2>&1 | FileCheck %s +// RUN: sleep 1 +// RUN: touch %t/a.h +// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s +// RUN: not %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s -DERRORS 2>&1 | FileCheck %s // RUN: rm %t/b.h // RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s // RUN: not %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s -DERRORS 2>&1 | FileCheck %s --check-prefix=MISSING-B Modified: cfe/trunk/test/Modules/module-map-path-hash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/module-map-path-hash.cpp?rev=245199&r1=245198&r2=245199&view=diff ============================================================================== --- cfe/trunk/test/Modules/module-map-path-hash.cpp (original) +++ cfe/trunk/test/Modules/module-map-path-hash.cpp Mon Aug 17 02:13:32 2015 @@ -1,4 +1,4 @@ -// rm -rf %t +// RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs/module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs//module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs/./module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits