[flang-commits] [flang] [flang] Pass LangOptions to parser via UserState (PR #213472)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Mon Aug 3 07:02:01 PDT 2026


https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/213472

>From 35554cf19e680239ae053a8e49d1d80990a35ceb Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 31 Jul 2026 13:19:30 -0500
Subject: [PATCH 1/5] [flang] Pass LangOptions to parser via UserState

This will help deal with syntax changes across different versions of
OpenMP. There are certain cases where being able to generate different
AST for the same source code depending on the version of the OpenMP
spec makes semantic analysis easier.
---
 flang/include/flang/Parser/parsing.h    | 4 +++-
 flang/include/flang/Parser/user-state.h | 8 ++++++++
 flang/lib/Frontend/FrontendAction.cpp   | 4 +++-
 flang/lib/Frontend/ParserActions.cpp    | 6 ++++--
 flang/lib/Parser/parsing.cpp            | 6 ++++--
 flang/lib/Semantics/mod-file.cpp        | 2 +-
 flang/tools/bbc/bbc.cpp                 | 2 +-
 7 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/flang/include/flang/Parser/parsing.h b/flang/include/flang/Parser/parsing.h
index 3365628dc4e0c..604703b5f8fc1 100644
--- a/flang/include/flang/Parser/parsing.h
+++ b/flang/include/flang/Parser/parsing.h
@@ -15,6 +15,7 @@
 #include "parse-tree.h"
 #include "provenance.h"
 #include "flang/Parser/preprocessor.h"
+#include "flang/Support/LangOptions.h"
 #include "llvm/Support/raw_ostream.h"
 #include <optional>
 #include <string>
@@ -42,7 +43,8 @@ class Parsing {
   void DumpCookedChars(llvm::raw_ostream &) const;
   void DumpProvenance(llvm::raw_ostream &) const;
   void DumpParsingLog(llvm::raw_ostream &) const;
-  void Parse(llvm::raw_ostream &debugOutput);
+  void Parse(
+      llvm::raw_ostream &debugOutput, const common::LangOptions &langOptions);
   void ClearLog();
 
   void EmitMessage(llvm::raw_ostream &o, const char *at,
diff --git a/flang/include/flang/Parser/user-state.h b/flang/include/flang/Parser/user-state.h
index f3dcae2158916..5ad67735f8ccf 100644
--- a/flang/include/flang/Parser/user-state.h
+++ b/flang/include/flang/Parser/user-state.h
@@ -17,6 +17,7 @@
 #include "flang/Parser/char-block.h"
 #include "flang/Parser/parse-tree.h"
 #include "flang/Support/Fortran-features.h"
+#include "flang/Support/LangOptions.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cinttypes>
 #include <optional>
@@ -88,6 +89,12 @@ class UserState {
     return oldStructureComponents_.find(name) != oldStructureComponents_.end();
   }
 
+  const common::LangOptions langOptions() const { return langOptions_; }
+  UserState &set_langOptions(const common::LangOptions &langOptions) {
+    langOptions_ = langOptions;
+    return *this;
+  }
+
 private:
   const AllCookedSources &allCooked_;
 
@@ -102,6 +109,7 @@ class UserState {
   std::set<CharBlock> oldStructureComponents_;
 
   common::LanguageFeatureControl features_;
+  common::LangOptions langOptions_;
 };
 
 // Definitions of parser classes that manipulate the UserState.
diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp
index e17f7ac42b5e6..8744d03d1c612 100644
--- a/flang/lib/Frontend/FrontendAction.cpp
+++ b/flang/lib/Frontend/FrontendAction.cpp
@@ -162,7 +162,9 @@ bool FrontendAction::runParse(bool emitMessages) {
   CompilerInstance &ci = this->getInstance();
 
   // Parse. In case of failure, report and return.
-  ci.getParsing().Parse(llvm::outs());
+  const common::LangOptions &langOpts =
+      getInstance().getInvocation().getLangOpts();
+  ci.getParsing().Parse(llvm::outs(), langOpts);
 
   if (reportFatalParsingErrors()) {
     return false;
diff --git a/flang/lib/Frontend/ParserActions.cpp b/flang/lib/Frontend/ParserActions.cpp
index 1722c7a9cf9d0..95f3ec7d5b983 100644
--- a/flang/lib/Frontend/ParserActions.cpp
+++ b/flang/lib/Frontend/ParserActions.cpp
@@ -91,7 +91,8 @@ struct MeasurementVisitor {
 
 void debugMeasureParseTree(CompilerInstance &ci, llvm::StringRef filename) {
   // Parse. In case of failure, report and return.
-  ci.getParsing().Parse(llvm::outs());
+  const common::LangOptions &langOptions = ci.getInvocation().getLangOpts();
+  ci.getParsing().Parse(llvm::outs(), langOptions);
 
   if ((ci.getParsing().parseTree().has_value() &&
        !ci.getParsing().consumedWholeFile()) ||
@@ -146,7 +147,8 @@ void debugUnparseWithModules(CompilerInstance &ci) {
 }
 
 void debugDumpParsingLog(CompilerInstance &ci) {
-  ci.getParsing().Parse(llvm::errs());
+  const common::LangOptions &langOptions = ci.getInvocation().getLangOpts();
+  ci.getParsing().Parse(llvm::errs(), langOptions);
   ci.getParsing().DumpParsingLog(llvm::outs());
 }
 } // namespace Fortran::frontend
diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp
index 667d8d9297ecb..38d03b8e6985f 100644
--- a/flang/lib/Parser/parsing.cpp
+++ b/flang/lib/Parser/parsing.cpp
@@ -279,11 +279,13 @@ void Parsing::DumpParsingLog(llvm::raw_ostream &out) const {
   log_.Dump(out, allCooked_);
 }
 
-void Parsing::Parse(llvm::raw_ostream &out) {
+void Parsing::Parse(
+    llvm::raw_ostream &out, const common::LangOptions &langOptions) {
   UserState userState{allCooked_, options_.features};
   userState.set_debugOutput(out)
       .set_instrumentedParse(options_.instrumentedParse)
-      .set_log(&log_);
+      .set_log(&log_)
+      .set_langOptions(langOptions);
   ParseState parseState{cooked()};
   parseState.set_inFixedForm(options_.isFixedForm).set_userState(&userState);
   // Don't bother managing message buffers when parsing module files.
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 177082d6af081..ed9ccc9ce1a7b 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -1720,7 +1720,7 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic,
     return nullptr;
   }
   llvm::raw_null_ostream NullStream;
-  parsing.Parse(NullStream);
+  parsing.Parse(NullStream, context_.langOptions());
   std::optional<parser::Program> &parsedProgram{parsing.parseTree()};
   if (!parsing.messages().empty() || !parsing.consumedWholeFile() ||
       !parsedProgram) {
diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp
index e1017a0005b50..e76808394becd 100644
--- a/flang/tools/bbc/bbc.cpp
+++ b/flang/tools/bbc/bbc.cpp
@@ -413,7 +413,7 @@ static llvm::LogicalResult convertFortranSourceToMLIR(
   }
 
   // parse the input Fortran
-  parsing.Parse(llvm::outs());
+  parsing.Parse(llvm::outs(), semanticsContext.langOptions());
   if (!parsing.consumedWholeFile()) {
     parsing.messages().Emit(llvm::errs(), parsing.allCooked());
     parsing.EmitMessage(llvm::errs(), parsing.finalRestingPlace(),

>From dd7afb766523ea1400f9dd738c6d9e2bb495d98d Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 3 Aug 2026 08:40:24 -0500
Subject: [PATCH 2/5] Fix call to Parse in f18-parse-demo

---
 flang/tools/f18-parse-demo/f18-parse-demo.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/tools/f18-parse-demo/f18-parse-demo.cpp b/flang/tools/f18-parse-demo/f18-parse-demo.cpp
index e25785bd784d4..07280da15d7d9 100644
--- a/flang/tools/f18-parse-demo/f18-parse-demo.cpp
+++ b/flang/tools/f18-parse-demo/f18-parse-demo.cpp
@@ -189,7 +189,7 @@ std::string CompileFortran(
     }
     return {};
   }
-  parsing.Parse(llvm::outs());
+  parsing.Parse(llvm::outs(), driver.langOpts);
   auto stop{CPUseconds()};
   if (driver.timeParse) {
     if (canTime) {

>From 04fa67251428b1907538a3df1f6836f6e9fe96f7 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 3 Aug 2026 08:45:04 -0500
Subject: [PATCH 3/5] Update flang/lib/Frontend/FrontendAction.cpp

Co-authored-by: Michael Kruse <llvm-project at meinersbur.de>
---
 flang/lib/Frontend/FrontendAction.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp
index 8744d03d1c612..40f6e35d826fb 100644
--- a/flang/lib/Frontend/FrontendAction.cpp
+++ b/flang/lib/Frontend/FrontendAction.cpp
@@ -163,7 +163,7 @@ bool FrontendAction::runParse(bool emitMessages) {
 
   // Parse. In case of failure, report and return.
   const common::LangOptions &langOpts =
-      getInstance().getInvocation().getLangOpts();
+      getInvocation().getLangOpts();
   ci.getParsing().Parse(llvm::outs(), langOpts);
 
   if (reportFatalParsingErrors()) {

>From 0fc19f8b24a2103c040b86a2ecf8f0851d220aa5 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 3 Aug 2026 08:45:13 -0500
Subject: [PATCH 4/5] Update flang/include/flang/Parser/user-state.h

Co-authored-by: Michael Kruse <llvm-project at meinersbur.de>
---
 flang/include/flang/Parser/user-state.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/include/flang/Parser/user-state.h b/flang/include/flang/Parser/user-state.h
index 5ad67735f8ccf..867c737717a44 100644
--- a/flang/include/flang/Parser/user-state.h
+++ b/flang/include/flang/Parser/user-state.h
@@ -89,7 +89,7 @@ class UserState {
     return oldStructureComponents_.find(name) != oldStructureComponents_.end();
   }
 
-  const common::LangOptions langOptions() const { return langOptions_; }
+  const common::LangOptions &langOptions() const { return langOptions_; }
   UserState &set_langOptions(const common::LangOptions &langOptions) {
     langOptions_ = langOptions;
     return *this;

>From 824f56524b8bdeaa6cc35bf751d7d1a51d4e4a63 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 3 Aug 2026 09:00:57 -0500
Subject: [PATCH 5/5] Add ci

---
 flang/lib/Frontend/FrontendAction.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp
index 40f6e35d826fb..bb93f3ba9e4a0 100644
--- a/flang/lib/Frontend/FrontendAction.cpp
+++ b/flang/lib/Frontend/FrontendAction.cpp
@@ -163,7 +163,7 @@ bool FrontendAction::runParse(bool emitMessages) {
 
   // Parse. In case of failure, report and return.
   const common::LangOptions &langOpts =
-      getInvocation().getLangOpts();
+      ci.getInvocation().getLangOpts();
   ci.getParsing().Parse(llvm::outs(), langOpts);
 
   if (reportFatalParsingErrors()) {



More information about the flang-commits mailing list