Skip to content

Commit 5024a6e

Browse files
authored
[flang][preprocessor] Support __TIMESTAMP__ (#98057)
Support the predefined macro __TIMESTAMP__ as interpreted by GCC. It expands to a character literal with the time of last modification of the top-level source file in asctime(3) format, e.g. "Tue Jul 4 10:18:05 1776".
1 parent 60c9033 commit 5024a6e

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

flang/include/flang/Parser/provenance.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ class AllSources {
176176
const std::string &message, const std::string &prefix,
177177
llvm::raw_ostream::Colors color, bool echoSourceLine = false) const;
178178
const SourceFile *GetSourceFile(
179-
Provenance, std::size_t *offset = nullptr) const;
179+
Provenance, std::size_t *offset = nullptr, bool topLevel = false) const;
180180
const char *GetSource(ProvenanceRange) const;
181181
std::optional<SourcePosition> GetSourcePosition(Provenance) const;
182182
std::optional<ProvenanceRange> GetFirstFileProvenance() const;
183-
std::string GetPath(Provenance) const; // __FILE__
183+
std::string GetPath(Provenance, bool topLevel = false) const; // __FILE__
184184
int GetLineNumber(Provenance) const; // __LINE__
185185
Provenance CompilerInsertionProvenance(char ch);
186186
ProvenanceRange IntersectionWithSourceFiles(ProvenanceRange) const;

flang/lib/Parser/preprocessor.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "flang/Common/idioms.h"
1313
#include "flang/Parser/characters.h"
1414
#include "flang/Parser/message.h"
15+
#include "llvm/Support/FileSystem.h"
1516
#include "llvm/Support/raw_ostream.h"
1617
#include <algorithm>
1718
#include <cinttypes>
@@ -289,6 +290,7 @@ void Preprocessor::DefineStandardMacros() {
289290
// The values of these predefined macros depend on their invocation sites.
290291
Define("__FILE__"s, "__FILE__"s);
291292
Define("__LINE__"s, "__LINE__"s);
293+
Define("__TIMESTAMP__"s, "__TIMESTAMP__"s);
292294
}
293295

294296
void Preprocessor::Define(const std::string &macro, const std::string &value) {
@@ -377,6 +379,19 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
377379
llvm::raw_string_ostream ss{buf};
378380
ss << allSources_.GetLineNumber(prescanner.GetCurrentProvenance());
379381
repl = ss.str();
382+
} else if (name == "__TIMESTAMP__") {
383+
auto path{allSources_.GetPath(
384+
prescanner.GetCurrentProvenance(), /*topLevel=*/true)};
385+
llvm::sys::fs::file_status status;
386+
repl = "??? ??? ?? ??:??:?? ????";
387+
if (!llvm::sys::fs::status(path, status)) {
388+
auto modTime{llvm::sys::toTimeT(status.getLastModificationTime())};
389+
if (std::string time{std::asctime(std::localtime(&modTime))};
390+
time.size() > 1 && time[time.size() - 1] == '\n') {
391+
time.erase(time.size() - 1); // clip terminal '\n'
392+
repl = "\""s + time + '"';
393+
}
394+
}
380395
}
381396
if (!repl.empty()) {
382397
ProvenanceRange insert{allSources_.AddCompilerInsertion(repl)};

flang/lib/Parser/provenance.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,19 @@ void AllSources::EmitMessage(llvm::raw_ostream &o,
321321
}
322322

323323
const SourceFile *AllSources::GetSourceFile(
324-
Provenance at, std::size_t *offset) const {
324+
Provenance at, std::size_t *offset, bool topLevel) const {
325325
const Origin &origin{MapToOrigin(at)};
326326
return common::visit(common::visitors{
327327
[&](const Inclusion &inc) {
328-
if (offset) {
329-
*offset = origin.covers.MemberOffset(at);
328+
if (topLevel && !origin.replaces.empty()) {
329+
return GetSourceFile(
330+
origin.replaces.start(), offset, topLevel);
331+
} else {
332+
if (offset) {
333+
*offset = origin.covers.MemberOffset(at);
334+
}
335+
return &inc.source;
330336
}
331-
return &inc.source;
332337
},
333338
[&](const Macro &) {
334339
return GetSourceFile(
@@ -380,9 +385,9 @@ std::optional<ProvenanceRange> AllSources::GetFirstFileProvenance() const {
380385
return std::nullopt;
381386
}
382387

383-
std::string AllSources::GetPath(Provenance at) const {
388+
std::string AllSources::GetPath(Provenance at, bool topLevel) const {
384389
std::size_t offset{0};
385-
const SourceFile *source{GetSourceFile(at, &offset)};
390+
const SourceFile *source{GetSourceFile(at, &offset, topLevel)};
386391
return source ? *source->GetSourcePosition(offset).path : ""s;
387392
}
388393

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
2+
!CHECK: INTEGER, PARAMETER :: tslen = 24_4
3+
!CHECK: LOGICAL, PARAMETER :: tsspaces = .true._4
4+
!CHECK: LOGICAL, PARAMETER :: tscolons = .true._4
5+
6+
integer, parameter :: tsLen = len(__TIMESTAMP__)
7+
character(tsLen), parameter :: ts = __TIMESTAMP__
8+
integer, parameter :: spaces(*) = [4, 8, 11, 20]
9+
integer, parameter :: colons(*) = [14, 17]
10+
logical, parameter :: tsSpaces = all([character(1)::(ts(spaces(j):spaces(j)),j=1,size(spaces))] == ' ')
11+
logical, parameter :: tsColons = all([character(1)::(ts(colons(j):colons(j)),j=1,size(colons))] == ':')
12+
end

0 commit comments

Comments
 (0)