awarzynski created this revision. Herald added a reviewer: sscalpone. Herald added a subscriber: dang. awarzynski requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This patch adds new option for the new Flang driver: `-fno-unparse-typed-exprs`. The semantics are similar to `-funparse-typed-exprs-to-f18-fc` from `f18`. For consistency, the latter is replaced with `-fno-unparse-typed-exprs`. The new option controls the behaviour of the unparser (i.e. the action corresponding to `-fdebug-unparse`). The default behaviour is to always unparse typed expressions. The new flag can be used to turn this off. Note that the semantics in `f18` had to be updated so that the behaviour is consistent across all calls to `Unparse`. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D103612 Files: clang/include/clang/Driver/Options.td flang/include/flang/Frontend/CompilerInvocation.h flang/lib/Frontend/CompilerInvocation.cpp flang/lib/Frontend/FrontendActions.cpp flang/lib/Frontend/FrontendOptions.cpp flang/test/Driver/unparse-typed-exprs.f95 flang/tools/f18/f18.cpp flang/tools/f18/flang
Index: flang/tools/f18/flang =================================================================== --- flang/tools/f18/flang +++ flang/tools/f18/flang @@ -8,7 +8,7 @@ #===------------------------------------------------------------------------===# wd=$(cd $(dirname "$0")/.. && pwd) -opts="-module-suffix .f18.mod " +opts="-fno-unparse-typed-exprs -module-suffix .f18.mod " if ! $wd/bin/f18 $opts "$@" then status=$? echo flang: in $PWD, f18 failed with exit status $status: $wd/bin/f18 $opts "$@" >&2 Index: flang/tools/f18/f18.cpp =================================================================== --- flang/tools/f18/f18.cpp +++ flang/tools/f18/f18.cpp @@ -105,7 +105,7 @@ bool debugModuleWriter{false}; bool defaultReal8{false}; bool measureTree{false}; - bool unparseTypedExprsToF18_FC{false}; + bool unparseTypedExprs{true}; std::vector<std::string> F18_FCArgs; const char *prefix{nullptr}; bool getDefinition{false}; @@ -322,7 +322,8 @@ Unparse(llvm::outs(), parseTree, driver.encoding, true /*capitalize*/, options.features.IsEnabled( Fortran::common::LanguageFeature::BackslashEscapes), - nullptr /* action before each statement */, &asFortran); + nullptr /* action before each statement */, + driver.unparseTypedExprs ? &asFortran : nullptr); return {}; } if (driver.dumpPreFirTree) { @@ -353,11 +354,11 @@ options.features.IsEnabled( Fortran::common::LanguageFeature::BackslashEscapes), nullptr /* action before each statement */, - driver.unparseTypedExprsToF18_FC ? &asFortran : nullptr); + driver.unparseTypedExprs ? &asFortran : nullptr); } RunOtherCompiler(driver, tmpSourcePath.data(), relo.data()); - filesToDelete.emplace_back(tmpSourcePath); + // filesToDelete.emplace_back(tmpSourcePath); if (!driver.compileOnly && driver.outputPath.empty()) { filesToDelete.push_back(relo); } @@ -578,8 +579,8 @@ } else if (arg == "-funparse-with-symbols" || arg == "-fdebug-unparse-with-symbols") { driver.dumpUnparseWithSymbols = true; - } else if (arg == "-funparse-typed-exprs-to-f18-fc") { - driver.unparseTypedExprsToF18_FC = true; + } else if (arg == "-fno-unparse-typed-exprs") { + driver.unparseTypedExprs = false; } else if (arg == "-fparse-only" || arg == "-fsyntax-only") { driver.syntaxOnly = true; } else if (arg == "-c") { Index: flang/test/Driver/unparse-typed-exprs.f95 =================================================================== --- /dev/null +++ flang/test/Driver/unparse-typed-exprs.f95 @@ -0,0 +1,34 @@ +! Tests `-fno-unparse-typed-exprs-to-f18-fc` frontend option + +!-------------------------- +! RUN lines +!-------------------------- +! RUN: %flang_fc1 -fdebug-unparse %s | FileCheck %s --check-prefix=UNPARSED_TYPED_EXPR +! RUN: %flang_fc1 -fdebug-unparse -fno-unparse-typed-exprs %s | FileCheck %s --check-prefix=AS_FORTRAN + +!-------------------------- +! EXPECTED OUTPUT: default +!-------------------------- +! UNPARSED_TYPED_EXPR: PROGRAM test_allocated +! UNPARSED_TYPED_EXPR-NEXT: INTEGER :: i = 4_4 +! UNPARSED_TYPED_EXPR-NEXT: REAL(KIND=4_4), ALLOCATABLE :: x(:) +! UNPARSED_TYPED_EXPR-NEXT: IF (.NOT.allocated(x)) ALLOCATE(x(i)) +! UNPARSED_TYPED_EXPR-NEXT: END PROGRAM test_allocated + +!------------------------------------- +! EXPECTED OUTPUT: unparsed as Fortran +!-------------------------------------- +! AS_FORTRAN: PROGRAM test_allocated +! AS_FORTRAN-NEXT: INTEGER :: i = 4 +! AS_FORTRAN-NEXT: REAL(KIND=4), ALLOCATABLE :: x(:) +! AS_FORTRAN-NEXT: IF (.NOT.allocated(x)) ALLOCATE(x(i)) +! AS_FORTRAN-NEXT: END PROGRAM test_allocated + +!-------------------------- +! INPUT +!-------------------------- +program test_allocated + integer :: i = 4 + real(4), allocatable :: x(:) + if (.not. allocated(x)) allocate(x(i)) +end program test_allocated Index: flang/lib/Frontend/FrontendOptions.cpp =================================================================== --- flang/lib/Frontend/FrontendOptions.cpp +++ flang/lib/Frontend/FrontendOptions.cpp @@ -32,34 +32,6 @@ suffix == "F03" || suffix == "F08" || suffix == "F18"; } -// TODO: This is a copy of `asFortran` from f18.cpp and is added here for -// compatiblity. It doesn't really belong here, but I couldn't find a better -// place. We should decide whether to add it to the Evaluate or Parse/Unparse -// APIs or some dedicated utility library in the driver. -Fortran::parser::AnalyzedObjectsAsFortran -Fortran::frontend::getBasicAsFortran() { - return Fortran::parser::AnalyzedObjectsAsFortran{ - [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) { - if (x.v) { - x.v->AsFortran(o); - } else { - o << "(bad expression)"; - } - }, - [](llvm::raw_ostream &o, - const Fortran::evaluate::GenericAssignmentWrapper &x) { - if (x.v) { - x.v->AsFortran(o); - } else { - o << "(bad assignment)"; - } - }, - [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) { - x.AsFortran(o << "CALL "); - }, - }; -} - InputKind FrontendOptions::GetInputKindForExtension(llvm::StringRef extension) { if (isFixedFormSuffix(extension) || isFreeFormSuffix(extension)) { return Language::Fortran; Index: flang/lib/Frontend/FrontendActions.cpp =================================================================== --- flang/lib/Frontend/FrontendActions.cpp +++ flang/lib/Frontend/FrontendActions.cpp @@ -242,28 +242,27 @@ } void DebugUnparseNoSemaAction::ExecuteAction() { + auto &invoc = this->instance().invocation(); auto &parseTree{instance().parsing().parseTree()}; - Fortran::parser::AnalyzedObjectsAsFortran asFortran = - Fortran::frontend::getBasicAsFortran(); - // TODO: Options should come from CompilerInvocation Unparse(llvm::outs(), *parseTree, /*encoding=*/Fortran::parser::Encoding::UTF_8, /*capitalizeKeywords=*/true, /*backslashEscapes=*/false, - /*preStatement=*/nullptr, &asFortran); + /*preStatement=*/nullptr, + invoc.unparseTypedExprs() ? &invoc.asFortran() : nullptr); } void DebugUnparseAction::ExecuteAction() { + auto &invoc = this->instance().invocation(); auto &parseTree{instance().parsing().parseTree()}; - Fortran::parser::AnalyzedObjectsAsFortran asFortran = - Fortran::frontend::getBasicAsFortran(); // TODO: Options should come from CompilerInvocation Unparse(llvm::outs(), *parseTree, /*encoding=*/Fortran::parser::Encoding::UTF_8, /*capitalizeKeywords=*/true, /*backslashEscapes=*/false, - /*preStatement=*/nullptr, &asFortran); + /*preStatement=*/nullptr, + invoc.unparseTypedExprs() ? &invoc.asFortran() : nullptr); // Report fatal semantic errors reportFatalSemanticErrors(semantics(), this->instance().diagnostics(), @@ -307,20 +306,19 @@ void DebugDumpParseTreeNoSemaAction::ExecuteAction() { auto &parseTree{instance().parsing().parseTree()}; - Fortran::parser::AnalyzedObjectsAsFortran asFortran = - Fortran::frontend::getBasicAsFortran(); // Dump parse tree - Fortran::parser::DumpTree(llvm::outs(), parseTree, &asFortran); + Fortran::parser::DumpTree( + llvm::outs(), parseTree, &this->instance().invocation().asFortran()); } void DebugDumpParseTreeAction::ExecuteAction() { auto &parseTree{instance().parsing().parseTree()}; - Fortran::parser::AnalyzedObjectsAsFortran asFortran = - Fortran::frontend::getBasicAsFortran(); // Dump parse tree - Fortran::parser::DumpTree(llvm::outs(), parseTree, &asFortran); + Fortran::parser::DumpTree( + llvm::outs(), parseTree, &this->instance().invocation().asFortran()); + // Report fatal semantic errors reportFatalSemanticErrors(semantics(), this->instance().diagnostics(), GetCurrentFileOrBufferName()); Index: flang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- flang/lib/Frontend/CompilerInvocation.cpp +++ flang/lib/Frontend/CompilerInvocation.cpp @@ -392,6 +392,11 @@ res.SetDebugModuleDir(true); } + // -fno-unparse-typed-exprs + if (args.hasArg(clang::driver::options::OPT_fno_unparse_typed_exprs)) { + res.SetUnparseTypedExprs(false); + } + return diags.getNumErrors() == numErrorsBefore; } Index: flang/include/flang/Frontend/CompilerInvocation.h =================================================================== --- flang/include/flang/Frontend/CompilerInvocation.h +++ flang/include/flang/Frontend/CompilerInvocation.h @@ -73,11 +73,34 @@ bool warnAsErr_ = false; + bool unparseTypedExprs_ = true; + // Fortran Dialect options Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_; bool EnableConformanceChecks_ = false; + Fortran::parser::AnalyzedObjectsAsFortran AsFortran_{ + [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) { + if (x.v) { + x.v->AsFortran(o); + } else { + o << "(bad expression)"; + } + }, + [](llvm::raw_ostream &o, + const Fortran::evaluate::GenericAssignmentWrapper &x) { + if (x.v) { + x.v->AsFortran(o); + } else { + o << "(bad assignment)"; + } + }, + [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) { + x.AsFortran(o << "CALL "); + }, + }; + public: CompilerInvocation() = default; @@ -103,11 +126,19 @@ bool &warnAsErr() { return warnAsErr_; } const bool &warnAsErr() const { return warnAsErr_; } + bool &unparseTypedExprs() { return unparseTypedExprs_; } + const bool &unaprseTypedExprsAsFortran() const { return unparseTypedExprs_; } + bool &enableConformanceChecks() { return EnableConformanceChecks_; } const bool &enableConformanceChecks() const { return EnableConformanceChecks_; } + Fortran::parser::AnalyzedObjectsAsFortran &asFortran() { return AsFortran_; } + const Fortran::parser::AnalyzedObjectsAsFortran &asFortran() const { + return AsFortran_; + } + Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() { return defaultKinds_; } @@ -133,6 +164,8 @@ void SetWarnAsErr(bool flag) { warnAsErr_ = flag; } + void SetUnparseTypedExprs(bool flag) { unparseTypedExprs_ = flag; } + /// Set the Fortran options to predifined defaults. These defaults are /// consistend with f18/f18.cpp. // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -4521,6 +4521,10 @@ def fget_symbols_sources : Flag<["-"], "fget-symbols-sources">, Group<Action_Group>, HelpText<"Dump symbols and their source code locations">; +def fno_unparse_typed_exprs : Flag<["-"], + "fno-unparse-typed-exprs">, Group<f_Group>, + HelpText<"Don't unparse typed expressions">; + } //===----------------------------------------------------------------------===//
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits