[clang] Move getenv call for SOURCE_DATE_EPOCH out of frontend NFC
authorBen Langmuir <blangmuir@apple.com>
Tue, 25 Oct 2022 22:12:24 +0000 (15:12 -0700)
committerBen Langmuir <blangmuir@apple.com>
Wed, 26 Oct 2022 19:42:56 +0000 (12:42 -0700)
Move the check for SOURCE_DATE_EPOCH to the driver and use a cc1 option
to pass it to the frontend. This avoids hidden state in the cc1
invocation and makes this env variable behave more like other env
variables that clang handles in the driver.

Differential Revision: https://reviews.llvm.org/D136717

clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/test/Driver/SOURCE_DATE_EPOCH.c [new file with mode: 0644]
clang/test/Preprocessor/SOURCE_DATE_EPOCH.c

index 0f5b6d8..61cb418 100644 (file)
@@ -6303,6 +6303,9 @@ def setup_static_analyzer : Flag<["-"], "setup-static-analyzer">,
 def disable_pragma_debug_crash : Flag<["-"], "disable-pragma-debug-crash">,
   HelpText<"Disable any #pragma clang __debug that can lead to crashing behavior. This is meant for testing.">,
   MarshallingInfoFlag<PreprocessorOpts<"DisablePragmaDebugCrash">>;
+def source_date_epoch : Separate<["-"], "source-date-epoch">,
+  MetaVarName<"<time since Epoch in seconds>">,
+  HelpText<"Time to be used in __DATE__, __TIME__, and __TIMESTAMP__ macros">;
 
 } // let Flags = [CC1Option, NoDriverOption]
 
index d1e5ad3..1ebb37e 100644 (file)
@@ -1462,6 +1462,11 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
 
   Args.AddLastArg(CmdArgs, options::OPT_ffile_reproducible,
                   options::OPT_fno_file_reproducible);
+
+  if (const char *Epoch = std::getenv("SOURCE_DATE_EPOCH")) {
+    CmdArgs.push_back("-source-date-epoch");
+    CmdArgs.push_back(Args.MakeArgString(Epoch));
+  }
 }
 
 // FIXME: Move to target hook.
index bcd5359..9cd6d86 100644 (file)
@@ -4227,6 +4227,9 @@ static void GeneratePreprocessorArgs(PreprocessorOptions &Opts,
   for (const auto &RF : Opts.RemappedFiles)
     GenerateArg(Args, OPT_remap_file, RF.first + ";" + RF.second, SA);
 
+  if (Opts.SourceDateEpoch)
+    GenerateArg(Args, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch), SA);
+
   // Don't handle LexEditorPlaceholders. It is implied by the action that is
   // generated elsewhere.
 }
@@ -4309,14 +4312,15 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
     Opts.addRemappedFile(Split.first, Split.second);
   }
 
-  if (const char *Epoch = std::getenv("SOURCE_DATE_EPOCH")) {
+  if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
+    StringRef Epoch = A->getValue();
     // SOURCE_DATE_EPOCH, if specified, must be a non-negative decimal integer.
     // On time64 systems, pick 253402300799 (the UNIX timestamp of
     // 9999-12-31T23:59:59Z) as the upper bound.
     const uint64_t MaxTimestamp =
         std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
     uint64_t V;
-    if (StringRef(Epoch).getAsInteger(10, V) || V > MaxTimestamp) {
+    if (Epoch.getAsInteger(10, V) || V > MaxTimestamp) {
       Diags.Report(diag::err_fe_invalid_source_date_epoch)
           << Epoch << MaxTimestamp;
     } else {
diff --git a/clang/test/Driver/SOURCE_DATE_EPOCH.c b/clang/test/Driver/SOURCE_DATE_EPOCH.c
new file mode 100644 (file)
index 0000000..69c0e1e
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: %clang -E %s -### 2>&1 | FileCheck %s -check-prefix=NO_EPOCH
+// NO_EPOCH-NOT: "-source-date-epoch"
+
+// RUN: env SOURCE_DATE_EPOCH=123 %clang -E %s -### 2>&1 | FileCheck %s
+// CHECK: "-source-date-epoch" "123"
index 71de3c7..30aec44 100644 (file)
@@ -1,10 +1,10 @@
-// RUN: env SOURCE_DATE_EPOCH=0 %clang_cc1 -E %s | FileCheck %s --check-prefix=19700101
+// RUN: %clang_cc1 -source-date-epoch 0 -E %s | FileCheck %s --check-prefix=19700101
 
 // 19700101:      const char date[] = "Jan  1 1970";
 // 19700101-NEXT: const char time[] = "00:00:00";
 // 19700101-NEXT: const char timestamp[] = "Thu Jan  1 00:00:00 1970";
 
-// RUN: env SOURCE_DATE_EPOCH=2147483647 %clang_cc1 -E -Wdate-time %s 2>&1 | FileCheck %s --check-prefix=Y2038
+// RUN: %clang_cc1 -source-date-epoch 2147483647 -E -Wdate-time %s 2>&1 | FileCheck %s --check-prefix=Y2038
 
 // Y2038:      warning: expansion of date or time macro is not reproducible [-Wdate-time]
 // Y2038:      const char date[] = "Jan 19 2038";
 // Y2038-NEXT: const char timestamp[] = "Tue Jan 19 03:14:07 2038";
 
 /// Test a large timestamp if the system uses 64-bit time_t and known to support large timestamps.
-// RUN: %if !system-windows && clang-target-64-bits %{ env SOURCE_DATE_EPOCH=253402300799 %clang_cc1 -E -Wdate-time %s 2>&1 | FileCheck %s --check-prefix=99991231 %}
+// RUN: %if !system-windows && clang-target-64-bits %{ %clang_cc1 -source-date-epoch 253402300799 -E -Wdate-time %s 2>&1 | FileCheck %s --check-prefix=99991231 %}
 
 // 99991231:      warning: expansion of date or time macro is not reproducible [-Wdate-time]
 // 99991231:      const char date[] = "Dec 31 9999";
 // 99991231-NEXT: const char time[] = "23:59:59";
 // 99991231-NEXT: const char timestamp[] = "Fri Dec 31 23:59:59 9999";
 
-// RUN: env SOURCE_DATE_EPOCH=253402300800 not %clang_cc1 -E %s 2>&1 | FileCheck %s --check-prefix=TOOBIG
+// RUN: not %clang_cc1 -source-date-epoch 253402300800 -E %s 2>&1 | FileCheck %s --check-prefix=TOOBIG
 
 // TOOBIG: error: environment variable 'SOURCE_DATE_EPOCH' ('253402300800') must be a non-negative decimal integer <= {{(2147483647|253402300799)}}
 
-// RUN: env SOURCE_DATE_EPOCH=0x0 not %clang_cc1 -E %s 2>&1 | FileCheck %s --check-prefix=NOTDECIMAL
+// RUN: not %clang_cc1 -source-date-epoch 0x0 -E %s 2>&1 | FileCheck %s --check-prefix=NOTDECIMAL
 
 // NOTDECIMAL: error: environment variable 'SOURCE_DATE_EPOCH' ('0x0') must be a non-negative decimal integer <= {{(2147483647|253402300799)}}