[flang-commits] [flang] 5024a6e - [flang][preprocessor] Support __TIMESTAMP__ (#98057)
via flang-commits
flang-commits at lists.llvm.org
Thu Jul 11 12:53:46 PDT 2024
Author: Peter Klausler
Date: 2024-07-11T12:53:43-07:00
New Revision: 5024a6ec974536596b3d51895e73462f2f71dc0d
URL: https://github.com/llvm/llvm-project/commit/5024a6ec974536596b3d51895e73462f2f71dc0d
DIFF: https://github.com/llvm/llvm-project/commit/5024a6ec974536596b3d51895e73462f2f71dc0d.diff
LOG: [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".
Added:
flang/test/Preprocessing/timestamp.F90
Modified:
flang/include/flang/Parser/provenance.h
flang/lib/Parser/preprocessor.cpp
flang/lib/Parser/provenance.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/provenance.h b/flang/include/flang/Parser/provenance.h
index 42c5b3de2cbe2..3189e012cd495 100644
--- a/flang/include/flang/Parser/provenance.h
+++ b/flang/include/flang/Parser/provenance.h
@@ -176,11 +176,11 @@ class AllSources {
const std::string &message, const std::string &prefix,
llvm::raw_ostream::Colors color, bool echoSourceLine = false) const;
const SourceFile *GetSourceFile(
- Provenance, std::size_t *offset = nullptr) const;
+ Provenance, std::size_t *offset = nullptr, bool topLevel = false) const;
const char *GetSource(ProvenanceRange) const;
std::optional<SourcePosition> GetSourcePosition(Provenance) const;
std::optional<ProvenanceRange> GetFirstFileProvenance() const;
- std::string GetPath(Provenance) const; // __FILE__
+ std::string GetPath(Provenance, bool topLevel = false) const; // __FILE__
int GetLineNumber(Provenance) const; // __LINE__
Provenance CompilerInsertionProvenance(char ch);
ProvenanceRange IntersectionWithSourceFiles(ProvenanceRange) const;
diff --git a/flang/lib/Parser/preprocessor.cpp b/flang/lib/Parser/preprocessor.cpp
index 8896980bf4bbf..7d3130cd66ed9 100644
--- a/flang/lib/Parser/preprocessor.cpp
+++ b/flang/lib/Parser/preprocessor.cpp
@@ -12,6 +12,7 @@
#include "flang/Common/idioms.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/message.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cinttypes>
@@ -289,6 +290,7 @@ void Preprocessor::DefineStandardMacros() {
// The values of these predefined macros depend on their invocation sites.
Define("__FILE__"s, "__FILE__"s);
Define("__LINE__"s, "__LINE__"s);
+ Define("__TIMESTAMP__"s, "__TIMESTAMP__"s);
}
void Preprocessor::Define(const std::string ¯o, const std::string &value) {
@@ -377,6 +379,19 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
llvm::raw_string_ostream ss{buf};
ss << allSources_.GetLineNumber(prescanner.GetCurrentProvenance());
repl = ss.str();
+ } else if (name == "__TIMESTAMP__") {
+ auto path{allSources_.GetPath(
+ prescanner.GetCurrentProvenance(), /*topLevel=*/true)};
+ llvm::sys::fs::file_status status;
+ repl = "??? ??? ?? ??:??:?? ????";
+ if (!llvm::sys::fs::status(path, status)) {
+ auto modTime{llvm::sys::toTimeT(status.getLastModificationTime())};
+ if (std::string time{std::asctime(std::localtime(&modTime))};
+ time.size() > 1 && time[time.size() - 1] == '\n') {
+ time.erase(time.size() - 1); // clip terminal '\n'
+ repl = "\""s + time + '"';
+ }
+ }
}
if (!repl.empty()) {
ProvenanceRange insert{allSources_.AddCompilerInsertion(repl)};
diff --git a/flang/lib/Parser/provenance.cpp b/flang/lib/Parser/provenance.cpp
index 6e2e7326e2167..c67ddd22f0968 100644
--- a/flang/lib/Parser/provenance.cpp
+++ b/flang/lib/Parser/provenance.cpp
@@ -321,14 +321,19 @@ void AllSources::EmitMessage(llvm::raw_ostream &o,
}
const SourceFile *AllSources::GetSourceFile(
- Provenance at, std::size_t *offset) const {
+ Provenance at, std::size_t *offset, bool topLevel) const {
const Origin &origin{MapToOrigin(at)};
return common::visit(common::visitors{
[&](const Inclusion &inc) {
- if (offset) {
- *offset = origin.covers.MemberOffset(at);
+ if (topLevel && !origin.replaces.empty()) {
+ return GetSourceFile(
+ origin.replaces.start(), offset, topLevel);
+ } else {
+ if (offset) {
+ *offset = origin.covers.MemberOffset(at);
+ }
+ return &inc.source;
}
- return &inc.source;
},
[&](const Macro &) {
return GetSourceFile(
@@ -380,9 +385,9 @@ std::optional<ProvenanceRange> AllSources::GetFirstFileProvenance() const {
return std::nullopt;
}
-std::string AllSources::GetPath(Provenance at) const {
+std::string AllSources::GetPath(Provenance at, bool topLevel) const {
std::size_t offset{0};
- const SourceFile *source{GetSourceFile(at, &offset)};
+ const SourceFile *source{GetSourceFile(at, &offset, topLevel)};
return source ? *source->GetSourcePosition(offset).path : ""s;
}
diff --git a/flang/test/Preprocessing/timestamp.F90 b/flang/test/Preprocessing/timestamp.F90
new file mode 100644
index 0000000000000..b8f431c3022b8
--- /dev/null
+++ b/flang/test/Preprocessing/timestamp.F90
@@ -0,0 +1,12 @@
+!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
+!CHECK: INTEGER, PARAMETER :: tslen = 24_4
+!CHECK: LOGICAL, PARAMETER :: tsspaces = .true._4
+!CHECK: LOGICAL, PARAMETER :: tscolons = .true._4
+
+integer, parameter :: tsLen = len(__TIMESTAMP__)
+character(tsLen), parameter :: ts = __TIMESTAMP__
+integer, parameter :: spaces(*) = [4, 8, 11, 20]
+integer, parameter :: colons(*) = [14, 17]
+logical, parameter :: tsSpaces = all([character(1)::(ts(spaces(j):spaces(j)),j=1,size(spaces))] == ' ')
+logical, parameter :: tsColons = all([character(1)::(ts(colons(j):colons(j)),j=1,size(colons))] == ':')
+end
More information about the flang-commits
mailing list