[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 06:40:58 PDT 2026
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/213472
>From cf5e8828dce4cd7c748132530bd415bde3021b59 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/2] [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 39701d0c5d2b69c41cabc7047005b265b8d17b0d 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/2] 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) {
More information about the flang-commits
mailing list