[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