From 5c3bf36c996e0e8e1b6fcdd2fc116d3e5305df13 Mon Sep 17 00:00:00 2001 From: Yussur Mustafa Oraji Date: Fri, 30 May 2025 14:33:53 +0200 Subject: [PATCH] [flang] Add __COUNTER__ preprocessor macro (#136827) This commit adds support for the `__COUNTER__` preprocessor macro, which works the same as the one found in clang. It is useful to generate unique names at compile-time. --- flang/docs/Extensions.md | 2 ++ flang/docs/Preprocessing.md | 12 ++++++++++++ flang/include/flang/Parser/preprocessor.h | 2 ++ flang/lib/Parser/preprocessor.cpp | 4 ++++ flang/test/Preprocessing/counter.F90 | 9 +++++++++ 5 files changed, 29 insertions(+) create mode 100644 flang/test/Preprocessing/counter.F90 diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md index 51969de5ac7f..7d5e35a3991d 100644 --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -521,6 +521,8 @@ end * We respect Fortran comments in macro actual arguments (like GNU, Intel, NAG; unlike PGI and XLF) on the principle that macro calls should be treated like function references. Fortran's line continuation methods also work. +* We implement the `__COUNTER__` preprocessing extension, + see [Non-standard Extensions](Preprocessing.md#non-standard-extensions) ## Standard features not silently accepted diff --git a/flang/docs/Preprocessing.md b/flang/docs/Preprocessing.md index 0b70d857833c..db815b9244ed 100644 --- a/flang/docs/Preprocessing.md +++ b/flang/docs/Preprocessing.md @@ -138,6 +138,18 @@ text. OpenMP-style directives that look like comments are not addressed by this scheme but are obvious extensions. +## Currently implemented built-ins + +* `__DATE__`: Date, given as e.g. "Jun 16 1904" +* `__TIME__`: Time in 24-hour format including seconds, e.g. "09:24:13" +* `__TIMESTAMP__`: Date, time and year of last modification, given as e.g. "Fri May 9 09:16:17 2025" +* `__FILE__`: Current file +* `__LINE__`: Current line + +### Non-standard Extensions + +* `__COUNTER__`: Replaced by sequential integers on each expansion, starting from 0. + ## Appendix `N` in the table below means "not supported"; this doesn't mean a bug, it just means that a particular behavior was diff --git a/flang/include/flang/Parser/preprocessor.h b/flang/include/flang/Parser/preprocessor.h index 15810a34ee6a..bb13b4463fa8 100644 --- a/flang/include/flang/Parser/preprocessor.h +++ b/flang/include/flang/Parser/preprocessor.h @@ -122,6 +122,8 @@ private: std::list names_; std::unordered_map definitions_; std::stack ifStack_; + + unsigned int counterVal_{0}; }; } // namespace Fortran::parser #endif // FORTRAN_PARSER_PREPROCESSOR_H_ diff --git a/flang/lib/Parser/preprocessor.cpp b/flang/lib/Parser/preprocessor.cpp index a5de14d86476..ef24c704db88 100644 --- a/flang/lib/Parser/preprocessor.cpp +++ b/flang/lib/Parser/preprocessor.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -299,6 +300,7 @@ void Preprocessor::DefineStandardMacros() { Define("__FILE__"s, "__FILE__"s); Define("__LINE__"s, "__LINE__"s); Define("__TIMESTAMP__"s, "__TIMESTAMP__"s); + Define("__COUNTER__"s, "__COUNTER__"s); } static const std::string idChars{ @@ -495,6 +497,8 @@ std::optional Preprocessor::MacroReplacement( repl = "\""s + time + '"'; } } + } else if (name == "__COUNTER__") { + repl = std::to_string(counterVal_++); } if (!repl.empty()) { ProvenanceRange insert{allSources_.AddCompilerInsertion(repl)}; diff --git a/flang/test/Preprocessing/counter.F90 b/flang/test/Preprocessing/counter.F90 new file mode 100644 index 000000000000..9761c8fb7f35 --- /dev/null +++ b/flang/test/Preprocessing/counter.F90 @@ -0,0 +1,9 @@ +! RUN: %flang -E %s | FileCheck %s +! CHECK: print *, 0 +! CHECK: print *, 1 +! CHECK: print *, 2 +! Check incremental counter macro +#define foo bar +print *, __COUNTER__ +print *, __COUNTER__ +print *, __COUNTER__