aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Frontend/FrontendActions.h16
-rw-r--r--flang/include/flang/Frontend/FrontendOptions.h7
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp6
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp72
-rw-r--r--flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp6
-rw-r--r--flang/test/Driver/driver-help.f903
-rw-r--r--flang/test/Driver/dump-parse-tree-no-sema.f9022
-rw-r--r--flang/test/Parser/omp-allocate-unparse.f902
-rw-r--r--flang/test/Parser/omp-atomic-unparse.f902
-rw-r--r--flang/tools/f18/f18.cpp7
10 files changed, 141 insertions, 2 deletions
diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h
index f49f9f4714b5..83e9652153ae 100644
--- a/flang/include/flang/Frontend/FrontendActions.h
+++ b/flang/include/flang/Frontend/FrontendActions.h
@@ -63,6 +63,22 @@ class DebugMeasureParseTreeAction : public PrescanAction {
};
//===----------------------------------------------------------------------===//
+// PrescanAndParse Actions
+//===----------------------------------------------------------------------===//
+class PrescanAndParseAction : public FrontendAction {
+ void ExecuteAction() override = 0;
+ bool BeginSourceFileAction(CompilerInstance &ci) override;
+};
+
+class DebugUnparseNoSemaAction : public PrescanAndParseAction {
+ void ExecuteAction() override;
+};
+
+class DebugDumpParseTreeNoSemaAction : public PrescanAndParseAction {
+ void ExecuteAction() override;
+};
+
+//===----------------------------------------------------------------------===//
// PrescanAndSema Actions
//===----------------------------------------------------------------------===//
class PrescanAndSemaAction : public FrontendAction {
diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h
index b58ca9ce8770..43b38f6db2a5 100644
--- a/flang/include/flang/Frontend/FrontendOptions.h
+++ b/flang/include/flang/Frontend/FrontendOptions.h
@@ -37,6 +37,10 @@ enum ActionKind {
/// Parse, unparse the parse-tree and output a Fortran source file
DebugUnparse,
+ /// Parse, unparse the parse-tree and output a Fortran source file, skip the
+ /// semantic checks
+ DebugUnparseNoSema,
+
/// Parse, resolve the sybmols, unparse the parse-tree and then output a
/// Fortran source file
DebugUnparseWithSymbols,
@@ -47,6 +51,9 @@ enum ActionKind {
/// Parse, run semantics and then output the parse tree
DebugDumpParseTree,
+ /// Parse and then output the parse tree, skip the semantic checks
+ DebugDumpParseTreeNoSema,
+
/// Dump provenance
DebugDumpProvenance,
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 43d9d41bd8d4..d1203c7912d0 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -127,6 +127,9 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts,
case clang::driver::options::OPT_fdebug_unparse:
opts.programAction_ = DebugUnparse;
break;
+ case clang::driver::options::OPT_fdebug_unparse_no_sema:
+ opts.programAction_ = DebugUnparseNoSema;
+ break;
case clang::driver::options::OPT_fdebug_unparse_with_symbols:
opts.programAction_ = DebugUnparseWithSymbols;
break;
@@ -136,6 +139,9 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts,
case clang::driver::options::OPT_fdebug_dump_parse_tree:
opts.programAction_ = DebugDumpParseTree;
break;
+ case clang::driver::options::OPT_fdebug_dump_parse_tree_no_sema:
+ opts.programAction_ = DebugDumpParseTreeNoSema;
+ break;
case clang::driver::options::OPT_fdebug_dump_provenance:
opts.programAction_ = DebugDumpProvenance;
break;
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 6aa7e2602ea6..00b46c90dfd1 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -67,6 +67,55 @@ bool PrescanAction::BeginSourceFileAction(CompilerInstance &c1) {
return true;
}
+bool PrescanAndParseAction::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());
+
+ return true;
+}
+
bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
CompilerInstance &ci = this->instance();
std::string currentInputPath{GetCurrentFileOrBufferName()};
@@ -117,6 +166,7 @@ bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
// Report the diagnostics from the semantic checks
semantics.EmitMessages(ci.semaOutputStream());
+
return true;
}
@@ -191,6 +241,19 @@ void ParseSyntaxOnlyAction::ExecuteAction() {
GetCurrentFileOrBufferName());
}
+void DebugUnparseNoSemaAction::ExecuteAction() {
+ 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);
+}
+
void DebugUnparseAction::ExecuteAction() {
auto &parseTree{instance().parsing().parseTree()};
Fortran::parser::AnalyzedObjectsAsFortran asFortran =
@@ -228,6 +291,15 @@ void DebugDumpSymbolsAction::ExecuteAction() {
semantics, this->instance().diagnostics(), GetCurrentFileOrBufferName());
}
+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);
+}
+
void DebugDumpParseTreeAction::ExecuteAction() {
auto &parseTree{instance().parsing().parseTree()};
Fortran::parser::AnalyzedObjectsAsFortran asFortran =
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 2a08e388a9d8..462de5241f3e 100644
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -40,6 +40,9 @@ static std::unique_ptr<FrontendAction> CreateFrontendBaseAction(
case DebugUnparse:
return std::make_unique<DebugUnparseAction>();
break;
+ case DebugUnparseNoSema:
+ return std::make_unique<DebugUnparseNoSemaAction>();
+ break;
case DebugUnparseWithSymbols:
return std::make_unique<DebugUnparseWithSymbolsAction>();
break;
@@ -49,6 +52,9 @@ static std::unique_ptr<FrontendAction> CreateFrontendBaseAction(
case DebugDumpParseTree:
return std::make_unique<DebugDumpParseTreeAction>();
break;
+ case DebugDumpParseTreeNoSema:
+ return std::make_unique<DebugDumpParseTreeNoSemaAction>();
+ break;
case DebugDumpProvenance:
return std::make_unique<DebugDumpProvenanceAction>();
break;
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index ed4648cfa48a..dd43990bb1ac 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -69,6 +69,8 @@
! HELP-FC1-NEXT: -falternative-parameter-statement
! HELP-FC1-NEXT: Enable the old style PARAMETER statement
! HELP-FC1-NEXT: -fbackslash Specify that backslash in string introduces an escape character
+! HELP-FC1-NEXT: -fdebug-dump-parse-tree-no-sema
+! HELP-FC1-NEXT: Dump the parse tree (skips the semantic checks)
! HELP-FC1-NEXT: -fdebug-dump-parse-tree Dump the parse tree
! HELP-FC1-NEXT: -fdebug-dump-parsing-log
! HELP-FC1-NEXT: Run instrumented parse and dump the parsing log
@@ -78,6 +80,7 @@
! HELP-FC1-NEXT: Measure the parse tree
! HELP-FC1-NEXT: -fdebug-module-writer Enable debug messages while writing module files
! HELP-FC1-NEXT: -fdebug-pre-fir-tree Dump the pre-FIR tree
+! HELP-FC1-NEXT: -fdebug-unparse-no-sema Unparse and stop (skips the semantic checks)
! HELP-FC1-NEXT: -fdebug-unparse-with-symbols
! HELP-FC1-NEXT: Unparse and stop.
! HELP-FC1-NEXT: -fdebug-unparse Unparse and stop.
diff --git a/flang/test/Driver/dump-parse-tree-no-sema.f90 b/flang/test/Driver/dump-parse-tree-no-sema.f90
new file mode 100644
index 000000000000..7179b1d4174e
--- /dev/null
+++ b/flang/test/Driver/dump-parse-tree-no-sema.f90
@@ -0,0 +1,22 @@
+!----------
+! RUN lines
+!----------
+! RUN: %flang_fc1 -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s --check-prefix=SEMA_ON
+! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix=SEMA_OFF
+
+!-----------------
+! EXPECTEED OUTPUT
+!-----------------
+! SEMA_ON: | | | NamedConstant -> Name = 'i'
+! SEMA_ON-NEXT: | | | Constant -> Expr = '1_4'
+! SEMA_ON-NEXT: | | | | LiteralConstant -> IntLiteralConstant = '1'
+
+! SEMA_OFF: | | | NamedConstant -> Name = 'i'
+! SEMA_OFF-NEXT: | | | Constant -> Expr -> LiteralConstant -> IntLiteralConstant = '1'
+
+!-------
+! INPUT
+!-------
+parameter(i=1)
+integer :: j
+end program
diff --git a/flang/test/Parser/omp-allocate-unparse.f90 b/flang/test/Parser/omp-allocate-unparse.f90
index 3f517c1e2d04..81b3677ad954 100644
--- a/flang/test/Parser/omp-allocate-unparse.f90
+++ b/flang/test/Parser/omp-allocate-unparse.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -fdebug-no-semantics -funparse -fopenmp %s | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck %s
! Check Unparsing of OpenMP Allocate directive
program allocate_unparse
diff --git a/flang/test/Parser/omp-atomic-unparse.f90 b/flang/test/Parser/omp-atomic-unparse.f90
index 10d1a61df07c..f9d8ec5d5c68 100644
--- a/flang/test/Parser/omp-atomic-unparse.f90
+++ b/flang/test/Parser/omp-atomic-unparse.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -fdebug-no-semantics -funparse -fopenmp %s | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck %s
program main
implicit none
diff --git a/flang/tools/f18/f18.cpp b/flang/tools/f18/f18.cpp
index 92d04ddd9b27..9a24183aa873 100644
--- a/flang/tools/f18/f18.cpp
+++ b/flang/tools/f18/f18.cpp
@@ -564,6 +564,13 @@ int main(int argc, char *const argv[]) {
options.instrumentedParse = true;
} else if (arg == "-fdebug-no-semantics") {
driver.debugNoSemantics = true;
+ } else if (arg == "-fdebug-unparse-no-sema") {
+ driver.debugNoSemantics = true;
+ driver.dumpUnparse = true;
+ } else if (arg == "-fdebug-dump-parse-tree-no-sema") {
+ driver.debugNoSemantics = true;
+ driver.dumpParseTree = true;
+ driver.syntaxOnly = true;
} else if (arg == "-funparse" || arg == "-fdebug-unparse") {
driver.dumpUnparse = true;
} else if (arg == "-funparse-with-symbols" ||