Skip to content

[flang][preprocessor] Expand some keyword macros in quoted character … #96987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 28, 2024

Conversation

klausler
Copy link
Contributor

…literals

To help port codes from compilers using pre-ANSI C preprocessors, which didn't care much about context when replacing macros, support the replacement of keyword macros in quoted character literals when (and only when) the name of the keyword macro constitutes the entire significant portion of a free form continuation line. See the new test case for a motivating example.

Fixes #96781.

…literals

To help port codes from compilers using pre-ANSI C preprocessors, which
didn't care much about context when replacing macros, support the replacement
of keyword macros in quoted character literals when (and only when) the
name of the keyword macro constitutes the entire significant portion of
a free form continuation line.  See the new test case for a motivating
example.

Fixes llvm#96781.
@klausler klausler requested a review from psteinfeld June 27, 2024 23:53
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:parser labels Jun 27, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 27, 2024

@llvm/pr-subscribers-flang-parser

Author: Peter Klausler (klausler)

Changes

…literals

To help port codes from compilers using pre-ANSI C preprocessors, which didn't care much about context when replacing macros, support the replacement of keyword macros in quoted character literals when (and only when) the name of the keyword macro constitutes the entire significant portion of a free form continuation line. See the new test case for a motivating example.

Fixes #96781.


Full diff: https://github.com/llvm/llvm-project/pull/96987.diff

2 Files Affected:

  • (modified) flang/lib/Parser/prescan.cpp (+35)
  • (added) flang/test/Preprocessing/kw-in-char.F90 (+14)
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 42aa829e0ed5b..668429a882291 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -820,6 +820,41 @@ void Prescanner::QuotedCharacterLiteral(
       }
       break;
     }
+    // Here's a weird edge case.  When there's a two or more following
+    // continuation lines at this point, and the entire significant part of
+    // the next continuation line is the name of a keyword macro, replace
+    // it in the character literal with its definition.  Example:
+    //   #define FOO foo
+    //   subroutine subr() bind(c, name="my_&
+    //     &FOO&
+    //     &_bar") ...
+    // produces a binding name of "my_foo_bar".
+    while (at_[1] == '&' && nextLine_ < limit_ && !InFixedFormSource()) {
+      const char *idStart{nextLine_};
+      if (const char *amper{SkipWhiteSpace(nextLine_)}; *amper == '&') {
+        idStart = amper + 1;
+      }
+      if (IsLegalIdentifierStart(*idStart)) {
+        std::size_t idLen{1};
+        for (; IsLegalInIdentifier(idStart[idLen]); ++idLen) {
+        }
+        if (idStart[idLen] == '&') {
+          CharBlock id{idStart, idLen};
+          if (preprocessor_.IsNameDefined(id)) {
+            TokenSequence ppTokens;
+            ppTokens.Put(id, GetProvenance(idStart));
+            if (auto replaced{
+                    preprocessor_.MacroReplacement(ppTokens, *this)}) {
+              tokens.Put(*replaced);
+              at_ = &idStart[idLen - 1];
+              NextLine();
+              continue; // try again on the next line
+            }
+          }
+        }
+      }
+      break;
+    }
     end = at_ + 1;
     NextChar();
     if (*at_ == quote && !isEscaped) {
diff --git a/flang/test/Preprocessing/kw-in-char.F90 b/flang/test/Preprocessing/kw-in-char.F90
new file mode 100644
index 0000000000000..e8f3a33b8a749
--- /dev/null
+++ b/flang/test/Preprocessing/kw-in-char.F90
@@ -0,0 +1,14 @@
+! RUN: %flang -E %s 2>&1 | FileCheck %s
+! CHECK: subroutine test_b_wrapper_c() bind(C, name="test_b_c_f")
+#define TEMP_LETTER b
+#define VAL c
+subroutine test_&
+TEMP_LETTER&
+_wrapper_&
+VAL&
+ () bind(C, name="test_&
+    &TEMP_LETTER&
+    &_&
+    &VAL&
+    &_f")
+end

Copy link
Contributor

@psteinfeld psteinfeld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All builds and tests correctly and looks good.

@klausler klausler merged commit cddbcd1 into llvm:main Jun 28, 2024
10 checks passed
@klausler klausler deleted the bug96781 branch June 28, 2024 19:14
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
llvm#96987)

…literals

To help port codes from compilers using pre-ANSI C preprocessors, which
didn't care much about context when replacing macros, support the
replacement of keyword macros in quoted character literals when (and
only when) the name of the keyword macro constitutes the entire
significant portion of a free form continuation line. See the new test
case for a motivating example.

Fixes llvm#96781.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:parser flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[flang] Preprocessor substitution in bind(C) names
3 participants