[flang-commits] [flang] f3991e1 - [flang] Allow macro replacement in numeric kind suffix (#132120)
via flang-commits
flang-commits at lists.llvm.org
Wed Mar 26 12:08:30 PDT 2025
Author: Peter Klausler
Date: 2025-03-26T12:08:26-07:00
New Revision: f3991e10bb0aa8cd6a72e9ebd8112b2030c67f13
URL: https://github.com/llvm/llvm-project/commit/f3991e10bb0aa8cd6a72e9ebd8112b2030c67f13
DIFF: https://github.com/llvm/llvm-project/commit/f3991e10bb0aa8cd6a72e9ebd8112b2030c67f13.diff
LOG: [flang] Allow macro replacement in numeric kind suffix (#132120)
When a numeric value has a kind suffix containing an identifier, allow
macro replacement for that identifier by treating it as its own token.
Fixes https://github.com/llvm/llvm-project/issues/131548.
Added:
flang/test/Preprocessing/kind-suffix.F90
Modified:
flang/lib/Parser/prescan.cpp
flang/lib/Parser/prescan.h
Removed:
################################################################################
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index b4ac82839b73f..0df1e3e291923 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -720,8 +720,8 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
} else if (*at_ == '.') {
while (IsDecimalDigit(EmitCharAndAdvance(tokens, *at_))) {
}
- ExponentAndKind(tokens);
- } else if (ExponentAndKind(tokens)) {
+ HandleExponentAndOrKindSuffix(tokens);
+ } else if (HandleExponentAndOrKindSuffix(tokens)) {
} else if (digits == 1 && n == 0 && (*at_ == 'x' || *at_ == 'X') &&
inPreprocessorDirective_) {
do {
@@ -743,7 +743,7 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
if (!inPreprocessorDirective_ && IsDecimalDigit(nch)) {
while (IsDecimalDigit(EmitCharAndAdvance(tokens, *at_))) {
}
- ExponentAndKind(tokens);
+ HandleExponentAndOrKindSuffix(tokens);
} else if (nch == '.' && EmitCharAndAdvance(tokens, '.') == '.') {
EmitCharAndAdvance(tokens, '.'); // variadic macro definition ellipsis
}
@@ -839,40 +839,53 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
return true;
}
-bool Prescanner::ExponentAndKind(TokenSequence &tokens) {
- char ed{ToLowerCaseLetter(*at_)};
- if (ed != 'e' && ed != 'd') {
- return false;
- }
- // Do some look-ahead to ensure that this 'e'/'d' is an exponent,
- // not the start of an identifier that could be a macro.
- const char *p{at_};
- if (int n{IsSpace(++p)}) {
- p += n;
- }
- if (*p == '+' || *p == '-') {
- if (int n{IsSpace(++p)}) {
- p += n;
+bool Prescanner::HandleExponent(TokenSequence &tokens) {
+ if (char ed{ToLowerCaseLetter(*at_)}; ed == 'e' || ed == 'd') {
+ // Do some look-ahead to ensure that this 'e'/'d' is an exponent,
+ // not the start of an identifier that could be a macro.
+ const char *p{SkipWhiteSpace(at_ + 1)};
+ if (*p == '+' || *p == '-') {
+ p = SkipWhiteSpace(p + 1);
+ }
+ if (IsDecimalDigit(*p)) { // it's an exponent
+ EmitCharAndAdvance(tokens, ed);
+ if (*at_ == '+' || *at_ == '-') {
+ EmitCharAndAdvance(tokens, *at_);
+ }
+ while (IsDecimalDigit(*at_)) {
+ EmitCharAndAdvance(tokens, *at_);
+ }
+ return true;
}
}
- if (IsDecimalDigit(*p)) { // it's an exponent
- EmitCharAndAdvance(tokens, ed);
- if (*at_ == '+' || *at_ == '-') {
- EmitCharAndAdvance(tokens, *at_);
+ return false;
+}
+
+bool Prescanner::HandleKindSuffix(TokenSequence &tokens) {
+ if (*at_ == '_' && IsLegalInIdentifier(*SkipWhiteSpace(at_ + 1))) {
+ EmitCharAndAdvance(tokens, *at_);
+ if (IsLegalIdentifierStart(*at_)) {
+ // The kind specifier might be a macro, so put it into its own token.
+ tokens.CloseToken();
}
- while (IsDecimalDigit(*at_)) {
+ while (IsLegalInIdentifier(*at_)) {
EmitCharAndAdvance(tokens, *at_);
}
- if (*at_ == '_') {
- while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_))) {
- }
- }
return true;
} else {
return false;
}
}
+bool Prescanner::HandleExponentAndOrKindSuffix(TokenSequence &tokens) {
+ bool hadExponent{HandleExponent(tokens)};
+ if (HandleKindSuffix(tokens)) {
+ return true;
+ } else {
+ return hadExponent;
+ }
+}
+
void Prescanner::QuotedCharacterLiteral(
TokenSequence &tokens, const char *start) {
char quote{*at_};
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index 9cf1b389f5b19..53361ba14f378 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -186,7 +186,9 @@ class Prescanner {
const char *SkipWhiteSpaceAndCComments(const char *) const;
const char *SkipCComment(const char *) const;
bool NextToken(TokenSequence &);
- bool ExponentAndKind(TokenSequence &);
+ bool HandleExponent(TokenSequence &);
+ bool HandleKindSuffix(TokenSequence &);
+ bool HandleExponentAndOrKindSuffix(TokenSequence &);
void QuotedCharacterLiteral(TokenSequence &, const char *start);
void Hollerith(TokenSequence &, int count, const char *start);
bool PadOutCharacterLiteral(TokenSequence &);
diff --git a/flang/test/Preprocessing/kind-suffix.F90 b/flang/test/Preprocessing/kind-suffix.F90
new file mode 100644
index 0000000000000..36aa323630c6c
--- /dev/null
+++ b/flang/test/Preprocessing/kind-suffix.F90
@@ -0,0 +1,6 @@
+! RUN: %flang -E %s 2>&1 | FileCheck %s
+#define n k
+parameter(n=4)
+!CHECK: print *,1_k
+print *,1_n
+end
More information about the flang-commits
mailing list