[flang-commits] [flang] 13cee14 - [flang] Parse global compiler directives
peter klausler via flang-commits
flang-commits at lists.llvm.org
Tue Aug 25 11:41:33 PDT 2020
Author: peter klausler
Date: 2020-08-25T11:41:11-07:00
New Revision: 13cee14bb1612ccdc3a7e7e770373fa2d2a94254
URL: https://github.com/llvm/llvm-project/commit/13cee14bb1612ccdc3a7e7e770373fa2d2a94254
DIFF: https://github.com/llvm/llvm-project/commit/13cee14bb1612ccdc3a7e7e770373fa2d2a94254.diff
LOG: [flang] Parse global compiler directives
Accept and represent "global" compiler directives that appear
before and between program units in a source file.
Differential Revision: https://reviews.llvm.org/D86555
Added:
Modified:
flang/include/flang/Parser/parse-tree.h
flang/lib/Parser/program-parsers.cpp
flang/lib/Semantics/program-tree.cpp
flang/lib/Semantics/program-tree.h
flang/lib/Semantics/resolve-names.cpp
flang/test/Parser/compiler-directives.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index cbff63700775..317d772889ee 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -547,7 +547,8 @@ struct ProgramUnit {
std::variant<common::Indirection<MainProgram>,
common::Indirection<FunctionSubprogram>,
common::Indirection<SubroutineSubprogram>, common::Indirection<Module>,
- common::Indirection<Submodule>, common::Indirection<BlockData>>
+ common::Indirection<Submodule>, common::Indirection<BlockData>,
+ common::Indirection<CompilerDirective>>
u;
};
diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp
index 278cc6fdb51a..dee359e240cf 100644
--- a/flang/lib/Parser/program-parsers.cpp
+++ b/flang/lib/Parser/program-parsers.cpp
@@ -20,20 +20,6 @@
namespace Fortran::parser {
-// R501 program -> program-unit [program-unit]...
-// This is the top-level production for the Fortran language.
-// F'2018 6.3.1 defines a program unit as a sequence of one or more lines,
-// implying that a line can't be part of two distinct program units.
-// Consequently, a program unit END statement should be the last statement
-// on its line. We parse those END statements via unterminatedStatement()
-// and then skip over the end of the line here.
-TYPE_PARSER(construct<Program>(
- extension<LanguageFeature::EmptySourceFile>(skipStuffBeforeStatement >>
- !nextCh >> pure<std::list<ProgramUnit>>()) ||
- some(StartNewSubprogram{} >> Parser<ProgramUnit>{} / skipMany(";"_tok) /
- space / recovery(endOfLine, SkipPast<'\n'>{})) /
- skipStuffBeforeStatement))
-
// R502 program-unit ->
// main-program | external-subprogram | module | submodule | block-data
// R503 external-subprogram -> function-subprogram | subroutine-subprogram
@@ -49,12 +35,30 @@ TYPE_PARSER(construct<Program>(
// variant parsers for several productions; giving the "module" production
// priority here is a cleaner solution, though regrettably subtle. Enforcing
// C1547 is done in semantics.
-TYPE_PARSER(construct<ProgramUnit>(indirect(Parser<Module>{})) ||
+static constexpr auto programUnit{
+ construct<ProgramUnit>(indirect(Parser<Module>{})) ||
construct<ProgramUnit>(indirect(functionSubprogram)) ||
construct<ProgramUnit>(indirect(subroutineSubprogram)) ||
construct<ProgramUnit>(indirect(Parser<Submodule>{})) ||
construct<ProgramUnit>(indirect(Parser<BlockData>{})) ||
- construct<ProgramUnit>(indirect(Parser<MainProgram>{})))
+ construct<ProgramUnit>(indirect(Parser<MainProgram>{}))};
+static constexpr auto normalProgramUnit{StartNewSubprogram{} >> programUnit /
+ skipMany(";"_tok) / space / recovery(endOfLine, SkipPast<'\n'>{})};
+static constexpr auto globalCompilerDirective{
+ construct<ProgramUnit>(indirect(compilerDirective))};
+
+// R501 program -> program-unit [program-unit]...
+// This is the top-level production for the Fortran language.
+// F'2018 6.3.1 defines a program unit as a sequence of one or more lines,
+// implying that a line can't be part of two distinct program units.
+// Consequently, a program unit END statement should be the last statement
+// on its line. We parse those END statements via unterminatedStatement()
+// and then skip over the end of the line here.
+TYPE_PARSER(construct<Program>(
+ extension<LanguageFeature::EmptySourceFile>(skipStuffBeforeStatement >>
+ !nextCh >> pure<std::list<ProgramUnit>>()) ||
+ some(globalCompilerDirective || normalProgramUnit) /
+ skipStuffBeforeStatement))
// R504 specification-part ->
// [use-stmt]... [import-stmt]... [implicit-part]
diff --git a/flang/lib/Semantics/program-tree.cpp b/flang/lib/Semantics/program-tree.cpp
index e6dfd9b2f51c..9466a748567e 100644
--- a/flang/lib/Semantics/program-tree.cpp
+++ b/flang/lib/Semantics/program-tree.cpp
@@ -112,6 +112,10 @@ ProgramTree ProgramTree::Build(const parser::BlockData &x) {
return result.set_stmt(stmt).set_endStmt(end);
}
+ProgramTree ProgramTree::Build(const parser::CompilerDirective &) {
+ DIE("ProgramTree::Build() called for CompilerDirective");
+}
+
const parser::ParentIdentifier &ProgramTree::GetParentId() const {
const auto *stmt{
std::get<const parser::Statement<parser::SubmoduleStmt> *>(stmt_)};
diff --git a/flang/lib/Semantics/program-tree.h b/flang/lib/Semantics/program-tree.h
index 69c133bfbde7..6b0745228201 100644
--- a/flang/lib/Semantics/program-tree.h
+++ b/flang/lib/Semantics/program-tree.h
@@ -38,6 +38,7 @@ class ProgramTree {
static ProgramTree Build(const parser::Module &);
static ProgramTree Build(const parser::Submodule &);
static ProgramTree Build(const parser::BlockData &);
+ static ProgramTree Build(const parser::CompilerDirective &);
ENUM_CLASS(Kind, // kind of node
Program, Function, Subroutine, MpSubprogram, Module, Submodule, BlockData)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 60376a1b8469..36c38c1cd99c 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6226,6 +6226,11 @@ void ResolveNamesVisitor::Post(const parser::AssignedGotoStmt &x) {
}
bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) {
+ if (std::holds_alternative<common::Indirection<parser::CompilerDirective>>(
+ x.u)) {
+ // TODO: global directives
+ return true;
+ }
auto root{ProgramTree::Build(x)};
SetScope(context().globalScope());
ResolveSpecificationParts(root);
diff --git a/flang/test/Parser/compiler-directives.f90 b/flang/test/Parser/compiler-directives.f90
index 5545d0486e56..c916b16b5327 100644
--- a/flang/test/Parser/compiler-directives.f90
+++ b/flang/test/Parser/compiler-directives.f90
@@ -2,6 +2,7 @@
! Test that compiler directives can appear in various places.
+!dir$ integer
module m
!dir$ integer
use iso_fortran_env
More information about the flang-commits
mailing list