This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG96d229c9abdf: [flang][driver] Add options for unparsing
(authored by awarzynski).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D96483/new/
https://reviews.llvm.org/D96483
Files:
clang/include/clang/Driver/Options.td
flang/include/flang/Frontend/FrontendActions.h
flang/include/flang/Frontend/FrontendOptions.h
flang/lib/Frontend/CMakeLists.txt
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Frontend/FrontendActions.cpp
flang/lib/Frontend/FrontendOptions.cpp
flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
flang/lib/Parser/CMakeLists.txt
flang/test/Flang-Driver/driver-help.f90
flang/test/Parser/continuation-in-if.f
flang/test/Parser/pp-dir-comments.f90
flang/test/Semantics/canondo01.f90
flang/test/Semantics/canondo02.f90
flang/test/Semantics/canondo03.f90
flang/test/Semantics/canondo04.f90
flang/test/Semantics/canondo05.f90
flang/test/Semantics/critical04.f90
flang/test/Semantics/defined-ops.f90
flang/test/Semantics/doconcurrent02.f90
flang/test/Semantics/doconcurrent03.f90
flang/test/Semantics/doconcurrent04.f90
flang/test/Semantics/doconcurrent07.f90
flang/test/Semantics/label02.f90
flang/test/Semantics/label03.f90
flang/test/Semantics/label04.f90
flang/test/Semantics/label05.f90
flang/test/Semantics/label06.f90
flang/test/Semantics/label07.f90
flang/test/Semantics/label08.f90
flang/test/Semantics/label09.f90
flang/test/Semantics/label10.f90
flang/test/Semantics/label12.f90
flang/test/Semantics/label13.f90
flang/test/Semantics/label15.f90
flang/test/lit.cfg.py
flang/tools/f18/f18.cpp
Index: flang/tools/f18/f18.cpp
===================================================================
--- flang/tools/f18/f18.cpp
+++ flang/tools/f18/f18.cpp
@@ -540,9 +540,10 @@
options.instrumentedParse = true;
} else if (arg == "-fdebug-no-semantics") {
driver.debugNoSemantics = true;
- } else if (arg == "-funparse") {
+ } else if (arg == "-funparse" || arg == "-fdebug-unparse") {
driver.dumpUnparse = true;
- } else if (arg == "-funparse-with-symbols") {
+ } 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;
Index: flang/test/lit.cfg.py
===================================================================
--- flang/test/lit.cfg.py
+++ flang/test/lit.cfg.py
@@ -74,10 +74,15 @@
if config.include_flang_new_driver_test:
tools.append(ToolSubst('%flang-new', command=FindTool('flang-new'), unresolved='fatal'))
tools.append(ToolSubst('%flang', command=FindTool('flang-new'), unresolved='fatal'))
+ tools.append(ToolSubst('%flang_fc1', command=FindTool('flang-new'),
+ extra_args=['-fc1'], unresolved='fatal'))
else:
tools.append(ToolSubst('%flang', command=FindTool('f18'),
extra_args=["-intrinsic-module-directory "+config.flang_intrinsic_modules_dir],
unresolved='fatal'))
+ tools.append(ToolSubst('%flang_fc1', command=FindTool('f18'),
+ extra_args=["-intrinsic-module-directory "+config.flang_intrinsic_modules_dir],
+ unresolved='fatal'))
if config.flang_standalone_build:
llvm_config.add_tool_substitutions(tools, [config.flang_llvm_tools_dir])
Index: flang/test/Semantics/label15.f90
===================================================================
--- flang/test/Semantics/label15.f90
+++ flang/test/Semantics/label15.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
!CHECK-NOT: error:
module mm
Index: flang/test/Semantics/label13.f90
===================================================================
--- flang/test/Semantics/label13.f90
+++ flang/test/Semantics/label13.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: branch into loop body from outside
! CHECK: the loop branched into
Index: flang/test/Semantics/label12.f90
===================================================================
--- flang/test/Semantics/label12.f90
+++ flang/test/Semantics/label12.f90
@@ -1,4 +1,4 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: expected end of statement
subroutine s
Index: flang/test/Semantics/label10.f90
===================================================================
--- flang/test/Semantics/label10.f90
+++ flang/test/Semantics/label10.f90
@@ -1,4 +1,4 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: '60' not a FORMAT
! CHECK: data transfer use of '60'
Index: flang/test/Semantics/label09.f90
===================================================================
--- flang/test/Semantics/label09.f90
+++ flang/test/Semantics/label09.f90
@@ -1,4 +1,4 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: Label '60' was not found
subroutine s(a)
Index: flang/test/Semantics/label08.f90
===================================================================
--- flang/test/Semantics/label08.f90
+++ flang/test/Semantics/label08.f90
@@ -1,5 +1,5 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: CYCLE construct-name is not in scope
! CHECK: IF construct name unexpected
! CHECK: unnamed IF statement
Index: flang/test/Semantics/label07.f90
===================================================================
--- flang/test/Semantics/label07.f90
+++ flang/test/Semantics/label07.f90
@@ -1,5 +1,5 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: Label '30' is not a branch target
! CHECK: Control flow use of '30'
! CHECK: Label '10' is not in scope
Index: flang/test/Semantics/label06.f90
===================================================================
--- flang/test/Semantics/label06.f90
+++ flang/test/Semantics/label06.f90
@@ -1,5 +1,5 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: Label '10' is not in scope
! CHECK: Label '20' was not found
! CHECK: Label '30' is not a branch target
Index: flang/test/Semantics/label05.f90
===================================================================
--- flang/test/Semantics/label05.f90
+++ flang/test/Semantics/label05.f90
@@ -1,5 +1,5 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: Label '50' was not found
! CHECK: Label '55' is not in scope
! CHECK: Label '70' is not a branch target
Index: flang/test/Semantics/label04.f90
===================================================================
--- flang/test/Semantics/label04.f90
+++ flang/test/Semantics/label04.f90
@@ -1,5 +1,5 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: branch into loop body from outside
! CHECK: do 10 i = 1, m
! CHECK: the loop branched into
Index: flang/test/Semantics/label03.f90
===================================================================
--- flang/test/Semantics/label03.f90
+++ flang/test/Semantics/label03.f90
@@ -1,5 +1,5 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: DO loop doesn't properly nest
! CHECK: DO loop conflicts
! CHECK: Label '30' cannot be found
Index: flang/test/Semantics/label02.f90
===================================================================
--- flang/test/Semantics/label02.f90
+++ flang/test/Semantics/label02.f90
@@ -1,5 +1,5 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: Label '0' is out of range
! CHECK: Label '100000' is out of range
! CHECK: Label '123456' is out of range
Index: flang/test/Semantics/doconcurrent07.f90
===================================================================
--- flang/test/Semantics/doconcurrent07.f90
+++ flang/test/Semantics/doconcurrent07.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK-NOT: exit from DO CONCURRENT construct
subroutine do_concurrent_test1(n)
Index: flang/test/Semantics/doconcurrent04.f90
===================================================================
--- flang/test/Semantics/doconcurrent04.f90
+++ flang/test/Semantics/doconcurrent04.f90
@@ -1,5 +1,5 @@
! C1122 The index-name shall be a named scalar variable of type integer.
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: Must have INTEGER type, but is REAL(4)
subroutine do_concurrent_test1(n)
Index: flang/test/Semantics/doconcurrent03.f90
===================================================================
--- flang/test/Semantics/doconcurrent03.f90
+++ flang/test/Semantics/doconcurrent03.f90
@@ -1,4 +1,4 @@
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: Control flow escapes from DO CONCURRENT
! CHECK: branch into loop body from outside
! CHECK: the loop branched into
Index: flang/test/Semantics/doconcurrent02.f90
===================================================================
--- flang/test/Semantics/doconcurrent02.f90
+++ flang/test/Semantics/doconcurrent02.f90
@@ -1,6 +1,6 @@
! when the loops are not DO CONCURRENT
-! RUN: not %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK-NOT: image control statement not allowed in DO CONCURRENT
! CHECK-NOT: RETURN not allowed in DO CONCURRENT
! CHECK-NOT: call to impure procedure in DO CONCURRENT not allowed
Index: flang/test/Semantics/defined-ops.f90
===================================================================
--- flang/test/Semantics/defined-ops.f90
+++ flang/test/Semantics/defined-ops.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
! Check the analyzed form of a defined operator or assignment.
Index: flang/test/Semantics/critical04.f90
===================================================================
--- flang/test/Semantics/critical04.f90
+++ flang/test/Semantics/critical04.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK-NOT: Control flow escapes from CRITICAL
subroutine test1(a, i)
Index: flang/test/Semantics/canondo05.f90
===================================================================
--- flang/test/Semantics/canondo05.f90
+++ flang/test/Semantics/canondo05.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! RUN: %f18 -fopenmp -funparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK-NOT: do *[1-9]
Index: flang/test/Semantics/canondo04.f90
===================================================================
--- flang/test/Semantics/canondo04.f90
+++ flang/test/Semantics/canondo04.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK-NOT: do [1-9]
! Figure out how to also execute this test.
Index: flang/test/Semantics/canondo03.f90
===================================================================
--- flang/test/Semantics/canondo03.f90
+++ flang/test/Semantics/canondo03.f90
@@ -1,5 +1,5 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: 10 continue
! CHECK: end do
Index: flang/test/Semantics/canondo02.f90
===================================================================
--- flang/test/Semantics/canondo02.f90
+++ flang/test/Semantics/canondo02.f90
@@ -1,5 +1,5 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: end do
SUBROUTINE sub00(a,b,n,m)
Index: flang/test/Semantics/canondo01.f90
===================================================================
--- flang/test/Semantics/canondo01.f90
+++ flang/test/Semantics/canondo01.f90
@@ -1,5 +1,5 @@
-! RUN: %f18 -funparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
! CHECK: end do
SUBROUTINE sub00(a,b,n,m)
Index: flang/test/Parser/pp-dir-comments.f90
===================================================================
--- flang/test/Parser/pp-dir-comments.f90
+++ flang/test/Parser/pp-dir-comments.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
#define pmk
#ifdef pmk // comment
Index: flang/test/Parser/continuation-in-if.f
===================================================================
--- flang/test/Parser/continuation-in-if.f
+++ flang/test/Parser/continuation-in-if.f
@@ -1,4 +1,4 @@
-! RUN: %f18 -funparse %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
! CHECK: CALL foo("N","N")
#ifdef transpose
call foo('T',
Index: flang/test/Flang-Driver/driver-help.f90
===================================================================
--- flang/test/Flang-Driver/driver-help.f90
+++ flang/test/Flang-Driver/driver-help.f90
@@ -46,6 +46,9 @@
! HELP-FC1-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
! HELP-FC1-NEXT: -emit-obj Emit native object files
! HELP-FC1-NEXT: -E Only run the preprocessor
+! HELP-FC1-NEXT: -fdebug-unparse-with-symbols
+! HELP-FC1-NEXT: Unparse and stop.
+! HELP-FC1-NEXT: -fdebug-unparse Unparse and stop.
! HELP-FC1-NEXT: -ffixed-form Process source files in fixed form
! HELP-FC1-NEXT: -ffixed-line-length=<value>
! HELP-FC1-NEXT: Use <value> as character line width in fixed mode
Index: flang/lib/Parser/CMakeLists.txt
===================================================================
--- flang/lib/Parser/CMakeLists.txt
+++ flang/lib/Parser/CMakeLists.txt
@@ -1,4 +1,3 @@
-
add_flang_library(FortranParser
Fortran-parsers.cpp
char-buffer.cpp
Index: flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -37,6 +37,12 @@
case EmitObj:
return std::make_unique<EmitObjAction>();
break;
+ case DebugUnparse:
+ return std::make_unique<DebugUnparseAction>();
+ break;
+ case DebugUnparseWithSymbols:
+ return std::make_unique<DebugUnparseWithSymbolsAction>();
+ break;
default:
break;
// TODO:
Index: flang/lib/Frontend/FrontendOptions.cpp
===================================================================
--- flang/lib/Frontend/FrontendOptions.cpp
+++ flang/lib/Frontend/FrontendOptions.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Frontend/FrontendOptions.h"
+#include "flang/Evaluate/expression.h"
using namespace Fortran::frontend;
@@ -25,6 +26,34 @@
suffix == "f08" || suffix == "F08" || suffix == "f18" || 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
@@ -9,10 +9,13 @@
#include "flang/Frontend/FrontendActions.h"
#include "flang/Common/default-kinds.h"
#include "flang/Frontend/CompilerInstance.h"
+#include "flang/Frontend/FrontendOptions.h"
#include "flang/Parser/parsing.h"
#include "flang/Parser/provenance.h"
#include "flang/Parser/source.h"
+#include "flang/Parser/unparse.h"
#include "flang/Semantics/semantics.h"
+#include "flang/Semantics/unparse-with-symbols.h"
using namespace Fortran::frontend;
@@ -49,6 +52,75 @@
return true;
}
+bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
+ CompilerInstance &ci = this->instance();
+
+ std::string currentInputPath{GetCurrentFileOrBufferName()};
+
+ Fortran::parser::Options parserOptions = ci.invocation().fortranOpts();
+
+ if (ci.invocation().frontendOpts().fortranForm_ == FortranForm::Unknown) {
+ // Switch between fixed and free form format based on the input file
+ // extension.
+ //
+ // Ideally we should have all Fortran options set before entering this
+ // method (i.e. before processing any specific input files). However, we
+ // can't decide between fixed and free form based on the file extension
+ // earlier than this.
+ parserOptions.isFixedForm = currentInput().IsFixedForm();
+ }
+
+ // Prescan. In case of failure, report and return.
+ ci.parsing().Prescan(currentInputPath, parserOptions);
+
+ if (ci.parsing().messages().AnyFatalError()) {
+ const unsigned diagID = ci.diagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "Could not scan %0");
+ ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
+ ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources());
+
+ return false;
+ }
+
+ // Parse. In case of failure, report and return.
+ ci.parsing().Parse(llvm::outs());
+
+ if (ci.parsing().messages().AnyFatalError()) {
+ unsigned diagID = ci.diagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "Could not parse %0");
+ ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
+
+ ci.parsing().messages().Emit(
+ llvm::errs(), this->instance().allCookedSources());
+ return false;
+ }
+
+ // Report the diagnostics from parsing
+ ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources());
+
+ auto &parseTree{*ci.parsing().parseTree()};
+
+ // Prepare semantics
+ Fortran::semantics::Semantics semantics{ci.invocation().semanticsContext(),
+ parseTree, ci.parsing().cooked().AsCharBlock()};
+
+ // Run semantic checks
+ semantics.Perform();
+
+ // Report the diagnostics from the semantic checks
+ semantics.EmitMessages(ci.semaOutputStream());
+
+ if (semantics.AnyFatalError()) {
+ unsigned DiagID = ci.diagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "Semantic errors in %0");
+ ci.diagnostics().Report(DiagID) << GetCurrentFileOrBufferName();
+
+ return false;
+ }
+
+ return true;
+}
+
void InputOutputTestAction::ExecuteAction() {
CompilerInstance &ci = instance();
@@ -111,42 +183,25 @@
}
}
-void ParseSyntaxOnlyAction::ExecuteAction() {
- CompilerInstance &ci = this->instance();
-
- // Parse. In case of failure, report and return.
- ci.parsing().Parse(llvm::outs());
-
- if (ci.parsing().messages().AnyFatalError()) {
- unsigned diagID = ci.diagnostics().getCustomDiagID(
- clang::DiagnosticsEngine::Error, "Could not parse %0");
- ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
-
- ci.parsing().messages().Emit(
- llvm::errs(), this->instance().allCookedSources());
- return;
- }
+void ParseSyntaxOnlyAction::ExecuteAction() {}
- // Report the diagnostics from parsing
- ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources());
-
- auto &parseTree{*ci.parsing().parseTree()};
+void DebugUnparseAction::ExecuteAction() {
+ auto &parseTree{instance().parsing().parseTree()};
+ Fortran::parser::AnalyzedObjectsAsFortran asFortran =
+ Fortran::frontend::getBasicAsFortran();
- // Prepare semantics
- Fortran::semantics::Semantics semantics{ci.invocation().semanticsContext(),
- parseTree, ci.parsing().cooked().AsCharBlock()};
-
- // Run semantic checks
- semantics.Perform();
+ // TODO: Options should come from CompilerInvocation
+ Unparse(llvm::outs(), *parseTree,
+ /*encoding=*/Fortran::parser::Encoding::UTF_8,
+ /*capitalizeKeywords=*/true, /*backslashEscapes=*/false,
+ /*preStatement=*/nullptr, &asFortran);
+}
- // Report the diagnostics from the semantic checks
- semantics.EmitMessages(ci.semaOutputStream());
+void DebugUnparseWithSymbolsAction::ExecuteAction() {
+ auto &parseTree{*instance().parsing().parseTree()};
- if (semantics.AnyFatalError()) {
- unsigned DiagID = ci.diagnostics().getCustomDiagID(
- clang::DiagnosticsEngine::Error, "Semantic errors in %0");
- ci.diagnostics().Report(DiagID) << GetCurrentFileOrBufferName();
- }
+ Fortran::semantics::UnparseWithSymbols(
+ llvm::outs(), parseTree, /*encoding=*/Fortran::parser::Encoding::UTF_8);
}
void EmitObjAction::ExecuteAction() {
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- flang/lib/Frontend/CompilerInvocation.cpp
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -110,6 +110,12 @@
case clang::driver::options::OPT_emit_obj:
opts.programAction_ = EmitObj;
break;
+ case clang::driver::options::OPT_fdebug_unparse:
+ opts.programAction_ = DebugUnparse;
+ break;
+ case clang::driver::options::OPT_fdebug_unparse_with_symbols:
+ opts.programAction_ = DebugUnparseWithSymbols;
+ break;
// TODO:
// case calng::driver::options::OPT_emit_llvm:
Index: flang/lib/Frontend/CMakeLists.txt
===================================================================
--- flang/lib/Frontend/CMakeLists.txt
+++ flang/lib/Frontend/CMakeLists.txt
@@ -14,6 +14,7 @@
LINK_LIBS
FortranParser
FortranSemantics
+ FortranEvaluate
FortranCommon
clangBasic
clangDriver
Index: flang/include/flang/Frontend/FrontendOptions.h
===================================================================
--- flang/include/flang/Frontend/FrontendOptions.h
+++ flang/include/flang/Frontend/FrontendOptions.h
@@ -9,6 +9,7 @@
#define LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
#include "flang/Common/Fortran-features.h"
+#include "flang/Parser/unparse.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -32,6 +33,13 @@
/// Emit a .o file.
EmitObj,
+ /// Parse, unparse the parse-tree and output a Fortran source file
+ DebugUnparse,
+
+ /// Parse, resolve the sybmols, unparse the parse-tree and then output a
+ /// Fortran source file
+ DebugUnparseWithSymbols,
+
/// TODO: RunPreprocessor, EmitLLVM, EmitLLVMOnly,
/// EmitCodeGenOnly, EmitAssembly, (...)
};
@@ -40,6 +48,10 @@
/// \return True if the file extension should be processed as fixed form
bool isFixedFormSuffix(llvm::StringRef suffix);
+// TODO: Find a more suitable location for this. Added for compability with
+// f18.cpp (this is equivalent to `asFortran` defined there).
+Fortran::parser::AnalyzedObjectsAsFortran getBasicAsFortran();
+
/// \param suffix The file extension
/// \return True if the file extension should be processed as free form
bool isFreeFormSuffix(llvm::StringRef suffix);
Index: flang/include/flang/Frontend/FrontendActions.h
===================================================================
--- flang/include/flang/Frontend/FrontendActions.h
+++ flang/include/flang/Frontend/FrontendActions.h
@@ -37,7 +37,23 @@
void ExecuteAction() override;
};
-class ParseSyntaxOnlyAction : public PrescanAction {
+//===----------------------------------------------------------------------===//
+// PrescanAndSema Actions
+//===----------------------------------------------------------------------===//
+class PrescanAndSemaAction : public FrontendAction {
+ void ExecuteAction() override = 0;
+ bool BeginSourceFileAction(CompilerInstance &ci) override;
+};
+
+class DebugUnparseWithSymbolsAction : public PrescanAndSemaAction {
+ void ExecuteAction() override;
+};
+
+class DebugUnparseAction : public PrescanAndSemaAction {
+ void ExecuteAction() override;
+};
+
+class ParseSyntaxOnlyAction : public PrescanAndSemaAction {
void ExecuteAction() override;
};
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4244,6 +4244,18 @@
}
+//===----------------------------------------------------------------------===//
+// FC1 Options
+//===----------------------------------------------------------------------===//
+let Flags = [FC1Option, FlangOnlyOption] in {
+
+def fdebug_unparse : Flag<["-"], "fdebug-unparse">, Group<Action_Group>,
+ HelpText<"Unparse and stop.">;
+def fdebug_unparse_with_symbols : Flag<["-"], "fdebug-unparse-with-symbols">, Group<Action_Group>,
+ HelpText<"Unparse and stop.">;
+
+}
+
//===----------------------------------------------------------------------===//
// CC1 Options
//===----------------------------------------------------------------------===//
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits