Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -507,6 +507,8 @@ HelpText<"When building a pch, try to find the input file in include " "directories, as if it had been included by the argument passed " "to this flag.">; +def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">, + HelpText<"Disable inclusion of timestamp in precompiled headers">; //===----------------------------------------------------------------------===// // Language Options Index: include/clang/Frontend/FrontendOptions.h =================================================================== --- include/clang/Frontend/FrontendOptions.h +++ include/clang/Frontend/FrontendOptions.h @@ -153,6 +153,8 @@ ///< implicit module build. unsigned ModulesEmbedAllFiles : 1; ///< Whether we should embed all used ///< files into the PCM file. + unsigned IncludeTimestamps : 1; ///< Whether timestamps should be + ///< written to the produced PCH file. CodeCompleteOptions CodeCompleteOpts; @@ -277,8 +279,8 @@ SkipFunctionBodies(false), UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), ASTDumpDecls(false), ASTDumpLookups(false), BuildingImplicitModule(false), ModulesEmbedAllFiles(false), - ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None), - ProgramAction(frontend::ParseSyntaxOnly) + IncludeTimestamps(true), ARCMTAction(ARCMT_None), + ObjCMTAction(ObjCMT_None), ProgramAction(frontend::ParseSyntaxOnly) {} /// getInputKindForExtension - Return the appropriate input kind for a file Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1144,6 +1144,7 @@ Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file); Opts.ModulesEmbedFiles = Args.getAllArgValues(OPT_fmodules_embed_file_EQ); Opts.ModulesEmbedAllFiles = Args.hasArg(OPT_fmodules_embed_all_files); + Opts.IncludeTimestamps = !Args.hasArg(OPT_fno_pch_timestamp); Opts.CodeCompleteOpts.IncludeMacros = Args.hasArg(OPT_code_completion_macros); Index: lib/Frontend/FrontendActions.cpp =================================================================== --- lib/Frontend/FrontendActions.cpp +++ lib/Frontend/FrontendActions.cpp @@ -92,7 +92,10 @@ std::vector> Consumers; Consumers.push_back(llvm::make_unique( CI.getPreprocessor(), OutputFile, nullptr, Sysroot, - Buffer, CI.getFrontendOpts().ModuleFileExtensions)); + Buffer, CI.getFrontendOpts().ModuleFileExtensions, + /*AllowASTWithErrors*/false, + /*IncludeTimestamps*/ + +CI.getFrontendOpts().IncludeTimestamps)); Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( CI, InFile, OutputFile, OS, Buffer)); Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -2010,17 +2010,8 @@ // For an overridden file, there is nothing to validate. if (!Overridden && // (StoredSize != File->getSize() || -#if defined(LLVM_ON_WIN32) - false -#else - // In our regression testing, the Windows file system seems to - // have inconsistent modification times that sometimes - // erroneously trigger this error-handling path. - // - // FIXME: This probably also breaks HeaderFileInfo lookups on Windows. (StoredTime && StoredTime != File->getModificationTime() && !DisableValidation) -#endif )) { if (Complain) { // Build a list of the PCH imports that got us here (in reverse). Index: test/PCH/Inputs/pragma-once2-pch.h =================================================================== --- /dev/null +++ test/PCH/Inputs/pragma-once2-pch.h @@ -0,0 +1 @@ +#include "pragma-once2.h" Index: test/PCH/Inputs/pragma-once2.h =================================================================== --- /dev/null +++ test/PCH/Inputs/pragma-once2.h @@ -0,0 +1,3 @@ +#pragma once + +inline void f() {} Index: test/PCH/include-timestamp.cpp =================================================================== --- /dev/null +++ test/PCH/include-timestamp.cpp @@ -0,0 +1,29 @@ +// Test that the timestamp is not included in the produced pch file with +// -fno-pch-timestamp. + +// Check timestamp is included by default. +// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/Inputs/pragma-once2-pch.h +// RUN: touch %S/Inputs/pragma-once2.h +// RUN: sleep 1 +// RUN: not %clang_cc1 -include-pch %t %s 2>&1 | FileCheck -check-prefix=CHECK-TIMESTAMP %s + +// Check bitcode output as well. +// RUN: llvm-bcanalyzer -dump %t | FileCheck -check-prefix=CHECK-BITCODE-TIMESTAMP-ON %s + +// Check timestamp inclusion is disabled by -fno-pch-timestamp. +// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/Inputs/pragma-once2-pch.h -fno-pch-timestamp +// RUN: touch %S/Inputs/pragma-once2.h +// RUN: sleep 1 +// RUN: %clang_cc1 -include-pch %t %s 2>&1 + +// Check bitcode output as well. +// RUN: llvm-bcanalyzer -dump %t | FileCheck -check-prefix=CHECK-BITCODE-TIMESTAMP-OFF %s + +#include "Inputs/pragma-once2.h" + +void g() { f(); } + +// CHECK-BITCODE-TIMESTAMP-ON: