diff --git a/flang/include/flang/Semantics/semantics.h b/flang/include/flang/Semantics/semantics.h --- a/flang/include/flang/Semantics/semantics.h +++ b/flang/include/flang/Semantics/semantics.h @@ -195,6 +195,10 @@ void UseFortranBuiltinsModule(); const Scope *GetBuiltinsScope() const { return builtinsScope_; } + // Saves a module file's parse tree so that it remains available + // during semantics. + parser::Program &SaveParseTree(parser::Program &&); + private: void CheckIndexVarRedefine( const parser::CharBlock &, const Symbol &, parser::MessageFixedText &&); @@ -226,6 +230,7 @@ UnorderedSymbolSet errorSymbols_; std::set tempNames_; const Scope *builtinsScope_{nullptr}; // module __Fortran_builtins + std::list modFileParseTrees_; }; class Semantics { diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -970,13 +970,14 @@ } llvm::raw_null_ostream NullStream; parsing.Parse(NullStream); - auto &parseTree{parsing.parseTree()}; + std::optional &parsedProgram{parsing.parseTree()}; if (!parsing.messages().empty() || !parsing.consumedWholeFile() || - !parseTree) { + !parsedProgram) { Say(name, ancestorName, "Module file is corrupt: %s"_err_en_US, sourceFile->path()); return nullptr; } + parser::Program &parseTree{context_.SaveParseTree(std::move(*parsedProgram))}; Scope *parentScope; // the scope this module/submodule goes into if (!isIntrinsic.has_value()) { for (const auto &dir : context_.intrinsicModuleDirectories()) { @@ -991,7 +992,7 @@ : context_.globalScope()}; if (!ancestor) { parentScope = &topScope; - } else if (std::optional parent{GetSubmoduleParent(*parseTree)}) { + } else if (std::optional parent{GetSubmoduleParent(parseTree)}) { parentScope = Read(*parent, false /*not intrinsic*/, ancestor, silent); } else { parentScope = ancestor; @@ -1002,7 +1003,7 @@ } Symbol &modSymbol{*pair.first->second}; modSymbol.set(Symbol::Flag::ModFile); - ResolveNames(context_, *parseTree, topScope); + ResolveNames(context_, parseTree, topScope); CHECK(modSymbol.has()); CHECK(modSymbol.test(Symbol::Flag::ModFile)); if (isIntrinsic.value_or(false)) { diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp --- a/flang/lib/Semantics/semantics.cpp +++ b/flang/lib/Semantics/semantics.cpp @@ -355,6 +355,10 @@ } } +parser::Program &SemanticsContext::SaveParseTree(parser::Program &&tree) { + return modFileParseTrees_.emplace_back(std::move(tree)); +} + bool Semantics::Perform() { // Implicitly USE the __Fortran_builtins module so that special types // (e.g., __builtin_team_type) are available to semantics, esp. for