[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.
This commit is contained in:
Krzysztof Parzyszek 2026-07-31 13:19:30 -05:00
parent 6dfd733723
commit cf5e8828dc
7 changed files with 24 additions and 8 deletions

View file

@ -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 @@ public:
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,

View file

@ -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 @@ public:
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 @@ private:
std::set<CharBlock> oldStructureComponents_;
common::LanguageFeatureControl features_;
common::LangOptions langOptions_;
};
// Definitions of parser classes that manipulate the UserState.

View file

@ -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;

View file

@ -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

View file

@ -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.

View file

@ -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) {

View file

@ -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(),