[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