diff options
Diffstat (limited to 'flang')
-rw-r--r-- | flang/include/flang/Frontend/FrontendActions.h | 16 | ||||
-rw-r--r-- | flang/include/flang/Frontend/FrontendOptions.h | 7 | ||||
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 6 | ||||
-rw-r--r-- | flang/lib/Frontend/FrontendActions.cpp | 72 | ||||
-rw-r--r-- | flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp | 6 | ||||
-rw-r--r-- | flang/test/Driver/driver-help.f90 | 3 | ||||
-rw-r--r-- | flang/test/Driver/dump-parse-tree-no-sema.f90 | 22 | ||||
-rw-r--r-- | flang/test/Parser/omp-allocate-unparse.f90 | 2 | ||||
-rw-r--r-- | flang/test/Parser/omp-atomic-unparse.f90 | 2 | ||||
-rw-r--r-- | flang/tools/f18/f18.cpp | 7 |
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" || |