[flang] add more clauses, declarative directives, standalone directives, and directiv...
authorHongyon Suauthai <hsuauthai@nvidia.com>
Thu, 31 May 2018 14:38:15 +0000 (07:38 -0700)
committerHongyon Suauthai <hsuauthai@nvidia.com>
Thu, 31 May 2018 14:38:15 +0000 (07:38 -0700)
Original-commit: flang-compiler/f18@483a54b0c890a550165e985f1ae10c4ab9c5ac79
Reviewed-on: https://github.com/flang-compiler/f18/pull/96
Tree-same-pre-rewrite: false

flang/documentation/OpenMP-4.5-grammar.txt
flang/lib/parser/grammar.h
flang/lib/parser/openmp-grammar.h [new file with mode: 0644]
flang/lib/parser/parse-tree-visitor.h
flang/lib/parser/parse-tree.h
flang/lib/parser/parsing.cc
flang/lib/parser/type-parsers.h
flang/lib/parser/unparse.cc
flang/lib/parser/user-state.cc
flang/lib/semantics/dump-parse-tree.h

index 9117a7e..5118c2f 100644 (file)
@@ -80,8 +80,8 @@
 2.8.2 notinbranch -> NOTINBRANCH
 2.13.9 depend -> DEPEND (((IN | OUT | INOUT) : variable-name-list) |
                           SOURCE |
-                          SINK : arrayvec)
-         arrayvec -> ident[scalar-int-expr:scalar-int-expr],...,ident[...]
+                          SINK : vec)
+         vec -> iterator [ +/- scalar-int-expr:scalar-int-expr],..., iterator[...]
 2.9.2 num_tasks -> NUM_TASKS (scalar-int-expr)
 2.9.2 grainsize -> GRAINSIZE (scalar-int-expr)
 2.9.2 nogroup -> NOGROUP
index 53af938..926c031 100644 (file)
@@ -84,7 +84,7 @@ TYPE_CONTEXT_PARSER("specification construct"_en_US,
         construct<SpecificationConstruct>(
             statement(indirect(typeDeclarationStmt))),
         construct<SpecificationConstruct>(indirect(Parser<StructureDef>{})),
-        construct<SpecificationConstruct>(indirect(ompDirective)),
+        construct<SpecificationConstruct>(indirect(openmpConstruct)),
         construct<SpecificationConstruct>(indirect(compilerDirective))))
 
 // R513 other-specification-stmt ->
@@ -223,6 +223,9 @@ constexpr auto scalarDefaultCharConstantExpr =
 constexpr auto intConstantExpr = integer(constantExpr);
 constexpr auto scalarIntConstantExpr = scalar(intConstantExpr);
 
+
+
+
 // R501 program -> program-unit [program-unit]...
 // This is the top-level production for the Fortran language.
 constexpr StartNewSubprogram startNewSubprogram;
@@ -359,7 +362,7 @@ constexpr auto executableConstruct =
         construct<ExecutableConstruct>(indirect(Parser<SelectTypeConstruct>{})),
         construct<ExecutableConstruct>(indirect(whereConstruct)),
         construct<ExecutableConstruct>(indirect(forallConstruct)),
-        construct<ExecutableConstruct>(indirect(ompDirective)),
+        construct<ExecutableConstruct>(indirect(openmpConstruct)),
         construct<ExecutableConstruct>(indirect(compilerDirective)));
 
 // R510 execution-part-construct ->
@@ -3243,7 +3246,7 @@ TYPE_CONTEXT_PARSER("statement function definition"_en_US,
 // Directives, extensions, and deprecated statements
 // !DIR$ IVDEP
 // !DIR$ IGNORE_TKR [ [(tkr...)] name ]...
-constexpr auto beginDirective = skipEmptyLines >> space >> "!"_ch;
+constexpr auto beginDirective = skipEmptyLines >> space >> "!"_tok;
 constexpr auto endDirective = space >> endOfLine;
 constexpr auto ivdep = construct<CompilerDirective::IVDEP>("DIR$ IVDEP"_tok);
 constexpr auto ignore_tkr = "DIR$ IGNORE_TKR" >>
@@ -3320,36 +3323,5 @@ TYPE_CONTEXT_PARSER("PAUSE statement"_en_US,
 //     is used only via scalar-int-variable
 //   R1030 default-char-constant-expr -> default-char-expr
 //     is only used via scalar-default-char-constant-expr
-
-// OpenMP Directives and Clauses
-
-// OpenMP Clauses
-TYPE_PARSER(construct<OmpClause>(construct<OmpClause::Private>(
-                "PRIVATE" >> parenthesized(nonemptyList(name)))) ||
-    construct<OmpClause>(construct<OmpClause::Firstprivate>(
-        "FIRSTPRIVATE" >> parenthesized(nonemptyList(name)))))
-
-// !$OMP PARALLEL [DO | SECTIONS | WORKSHARE | DO SIMD]
-constexpr auto parallel =
-    construct<OmpExeDir::Parallel>("PARALLEL" >> many(Parser<OmpClause>{}));
-constexpr auto parallelDo = construct<OmpExeDir::ParallelDo>(
-    "PARALLEL DO" >> many(Parser<OmpClause>{}));
-constexpr auto parallelDoSimd = construct<OmpExeDir::ParallelDoSimd>(
-    "PARALLEL DO SIMD" >> many(Parser<OmpClause>{}));
-constexpr auto parallelSections = construct<OmpExeDir::ParallelSections>(
-    "PARALLEL SECTIONS" >> many(Parser<OmpClause>{}));
-constexpr auto parallelWorkshare = construct<OmpExeDir::ParallelWorkshare>(
-    "PARALLEL WORKSHARE" >> many(Parser<OmpClause>{}));
-
-TYPE_PARSER(construct<OmpExeDir>(parallelDoSimd) ||
-    construct<OmpExeDir>(parallelDo) ||
-    construct<OmpExeDir>(parallelSections) ||
-    construct<OmpExeDir>(parallelWorkshare) || construct<OmpExeDir>(parallel))
-
-constexpr auto beginOmpDirective = skipEmptyLines >> space >> "!$OMP "_sptok;
-constexpr auto endOmpDirective = space >> endOfLine;
-TYPE_PARSER(beginOmpDirective >>
-    construct<OmpDirective>(indirect(Parser<OmpExeDir>{})) / endOmpDirective)
-
 }  // namespace Fortran::parser
 #endif  // FORTRAN_PARSER_GRAMMAR_H_
diff --git a/flang/lib/parser/openmp-grammar.h b/flang/lib/parser/openmp-grammar.h
new file mode 100644 (file)
index 0000000..9d7c1fa
--- /dev/null
@@ -0,0 +1,336 @@
+// Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef OPENMP_PARSER_GRAMMAR_H_
+#define OPENMP_PARSER_GRAMMAR_H_
+
+// Top-level grammar specification for Fortran.  These parsers drive
+// the tokenization parsers in cooked-tokens.h to consume characters,
+// recognize the productions of Fortran, and to construct a parse tree.
+// See ParserCombinators.md for documentation on the parser combinator
+// library used here to implement an LL recursive descent recognizer.
+
+#include "basic-parsers.h"
+#include "characters.h"
+#include "debug-parser.h"
+#include "grammar.h"
+#include "parse-tree.h"
+#include "stmt-parser.h"
+#include "token-parsers.h"
+#include "type-parsers.h"
+#include "user-state.h"
+#include <cinttypes>
+#include <cstdio>
+#include <functional>
+#include <list>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <utility>
+
+// OpenMP Directives and Clauses
+namespace Fortran::parser {
+
+constexpr auto beginOmpDirective = skipEmptyLines >> space >> "!$OMP "_sptok;
+
+// OpenMP Clauses
+
+// DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE )
+TYPE_PARSER(construct<OmpDefaultClause>(
+    "PRIVATE" >> pure(OmpDefaultClause::Type::Private) ||
+    "FIRSTPRIVATE" >> pure(OmpDefaultClause::Type::Firstprivate) ||
+    "SHARED" >> pure(OmpDefaultClause::Type::Shared) ||
+    "NONE" >> pure(OmpDefaultClause::Type::None)))
+
+// PROC_BIND(CLOSE | MASTER | SPREAD)
+TYPE_PARSER(construct<OmpProcBindClause>(
+    "CLOSE" >> pure(OmpProcBindClause::Type::Close) ||
+    "MASTER" >> pure(OmpProcBindClause::Type::Master) ||
+    "SPREAD" >> pure(OmpProcBindClause::Type::Spread)))
+
+// MAP ([ [map-type-modifier[,]] map-type : ] list)
+// map-type-modifier -> ALWAYS
+// map-type -> TO | FROM | TOFROM | ALLOC | RELEASE | DELETE
+TYPE_PARSER(construct<OmpMapClause>(
+    maybe(maybe("ALWAYS"_tok >> maybe(","_ch)) >>
+        ("TO" >> pure(OmpMapClause::Type::To) / ":"_ch ||
+            "FROM" >> pure(OmpMapClause::Type::From) / ":"_ch ||
+            "TOFROM" >> pure(OmpMapClause::Type::Tofrom) / ":"_ch ||
+            "ALLOC" >> pure(OmpMapClause::Type::Alloc) / ":"_ch ||
+            "RELEASE" >> pure(OmpMapClause::Type::Release) / ":"_ch ||
+            "DELETE" >> pure(OmpMapClause::Type::Delete) / ":"_ch)),
+    nonemptyList(name)))
+
+// SCHEDULE ([modifier [, modifier]:]kind[, chunk_size])
+// Modifier ->  MONITONIC | NONMONOTONIC | SIMD
+// kind -> STATIC | DYNAMIC | GUIDED | AUTO | RUNTIME
+// chunk_size -> ScalarIntExpr
+TYPE_PARSER(construct<OmpScheduleModifierType>(
+    "MONOTONIC" >> pure(OmpScheduleModifierType::ModType::Monotonic) ||
+    "NONMONOTONIC" >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) ||
+    "SIMD" >> pure(OmpScheduleModifierType::ModType::Simd)))
+
+TYPE_PARSER(construct<OmpScheduleClause>(
+    optionalList(Parser<OmpScheduleModifierType>{}),
+    "STATIC" >> pure(OmpScheduleClause::ScheduleType::Static) ||
+        "DYNAMIC" >> pure(OmpScheduleClause::ScheduleType::Dynamic) ||
+        "GUIDED" >> pure(OmpScheduleClause::ScheduleType::Guided) ||
+        "AUTO" >> pure(OmpScheduleClause::ScheduleType::Auto) ||
+        "RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime),
+    maybe(","_ch) >> scalarIntExpr))
+
+// IF(directive-name-modifier: scalar-logical-expr)
+TYPE_PARSER(construct<OmpIfClause>(
+    ("PARALLEL"_tok >> pure(OmpIfClause::DirectiveNameModifier::Parallel) ||
+        "TARGET ENTER DATA"_tok >>
+            pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) ||
+        "TARGET EXIT DATA"_tok >>
+            pure(OmpIfClause::DirectiveNameModifier::TargetExitData) ||
+        "TARGET DATA"_tok >>
+            pure(OmpIfClause::DirectiveNameModifier::TargetData) ||
+        "TARGET UPDATE"_tok >>
+            pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) ||
+        "TARGET"_tok >> pure(OmpIfClause::DirectiveNameModifier::Target) ||
+        "TASKLOOP"_tok >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) ||
+        "TASK"_tok >> pure(OmpIfClause::DirectiveNameModifier::Task)) /
+        maybe(":"_ch),
+    scalarLogicalExpr))
+
+// REDUCTION(reduction-identifier: list)
+constexpr auto reductionBinaryOperator = "+" >>
+        pure(OmpReductionOperator::BinaryOperator::Add) ||
+    "-" >> pure(OmpReductionOperator::BinaryOperator::Subtract) ||
+    "*" >> pure(OmpReductionOperator::BinaryOperator::Multiply) ||
+    ".AND." >> pure(OmpReductionOperator::BinaryOperator::AND) ||
+    ".OR." >> pure(OmpReductionOperator::BinaryOperator::OR) ||
+    ".EQV." >> pure(OmpReductionOperator::BinaryOperator::EQV) ||
+    ".NEQV." >> pure(OmpReductionOperator::BinaryOperator::NEQV);
+
+constexpr auto reductionProcedureOperator = "MIN" >>
+        pure(OmpReductionOperator::ProcedureOperator::MIN) ||
+    "MAX" >> pure(OmpReductionOperator::ProcedureOperator::MAX) ||
+    "IAND" >> pure(OmpReductionOperator::ProcedureOperator::IAND) ||
+    "IOR" >> pure(OmpReductionOperator::ProcedureOperator::IOR) ||
+    "IEOR" >> pure(OmpReductionOperator::ProcedureOperator::IEOR);
+
+TYPE_PARSER(construct<OmpReductionOperator>(reductionBinaryOperator) ||
+    construct<OmpReductionOperator>(reductionProcedureOperator))
+
+TYPE_PARSER(construct<OmpReductionClause>(
+    Parser<OmpReductionOperator>{}, nonemptyList(designator)))
+
+// DEPEND(SOURCE | SINK : vec | (IN | OUT | INOUT) : list
+TYPE_PARSER(construct<OmpDependSinkVecLength>(
+    Parser<DefinedOperator>{}, scalarIntConstantExpr))
+
+TYPE_PARSER(
+    construct<OmpDependSinkVec>(name, maybe(Parser<OmpDependSinkVecLength>{})))
+
+TYPE_PARSER(construct<OmpDependenceType>(
+    "IN"_tok >> pure(OmpDependenceType::Type::In) ||
+    "OUT"_tok >> pure(OmpDependenceType::Type::Out) ||
+    "INOUT"_tok >> pure(OmpDependenceType::Type::Inout)))
+
+TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
+    construct<OmpDependClause>(construct<OmpDependClause::Sink>(
+        "SINK"_tok >> ":"_ch >> nonemptyList(Parser<OmpDependSinkVec>{}))) ||
+        construct<OmpDependClause>(
+            construct<OmpDependClause::Source>("SOURCE"_tok)) ||
+        construct<OmpDependClause>(construct<OmpDependClause::InOut>(
+            Parser<OmpDependenceType>{}, ":"_ch >> nonemptyList(designator))))
+
+// LINEAR(list: linear-step)
+TYPE_PARSER(construct<OmpLinearModifier>(
+    "REF"_tok >> pure(OmpLinearModifier::Type::Ref) ||
+    "VAL"_tok >> pure(OmpLinearModifier::Type::Val) ||
+    "UVAL"_tok >> pure(OmpLinearModifier::Type::Uval)))
+
+TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US,
+    construct<OmpLinearClause>(
+        construct<OmpLinearClause>(construct<OmpLinearClause::WithModifier>(
+            Parser<OmpLinearModifier>{},
+            parenthesized(nonemptyList(name)),
+            maybe(":"_ch >> scalarIntConstantExpr))) ||
+        construct<OmpLinearClause>(construct<OmpLinearClause::WithoutModifier>(
+            nonemptyList(name), maybe(":"_ch >> scalarIntConstantExpr)))))
+
+// ALIGNED(list: alignment)
+TYPE_PARSER(construct<OmpAlignedClause>(
+    nonemptyList(name), maybe(":"_ch) >> scalarIntConstantExpr))
+
+TYPE_PARSER(construct<OmpNameList>(pure(OmpNameList::Kind::Object), name) ||
+    construct<OmpNameList>("/" >> pure(OmpNameList::Kind::Common), name / "/"))
+
+TYPE_CONTEXT_PARSER("Omp Clause"_en_US,
+construct<OmpClause>(construct<OmpClause::Defaultmap>("DEFAULTMAP"_tok >> parenthesized("TOFROM"_tok >> ":"_ch >> "SCALAR"_tok))) ||
+construct<OmpClause>(construct<OmpClause::Inbranch>("INBRANCH"_tok)) ||
+construct<OmpClause>(construct<OmpClause::Mergeable>("MERGEABLE"_tok)) ||
+construct<OmpClause>(construct<OmpClause::Nogroup>("NOGROUP"_tok)) ||
+construct<OmpClause>(construct<OmpClause::Notinbranch>("NOTINBRANCH"_tok)) ||
+construct<OmpClause>(construct<OmpClause::Nowait>("NOWAIT"_tok)) ||
+construct<OmpClause>(construct<OmpClause::Untied>("UNTIED"_tok)) ||
+construct<OmpClause>(construct<OmpClause::Collapse>("COLLAPSE"_tok >> parenthesized(scalarIntConstantExpr))) ||
+construct<OmpClause>(construct<OmpClause::Copyin>("COPYIN"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
+construct<OmpClause>(construct<OmpClause::Copyprivate>("COPYPRIVATE"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
+construct<OmpClause>(construct<OmpClause::Device>("DEVICE"_tok >> parenthesized(scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::DistSchedule>("DIST_SCHEDULE"_tok >> parenthesized("STATIC"_tok >> ","_ch >> scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::Final>("FINAL"_tok >> parenthesized(scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::Firstprivate>("FIRSTPRIVATE"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
+construct<OmpClause>(construct<OmpClause::From>("FROM"_tok >> parenthesized(nonemptyList(designator)))) ||
+construct<OmpClause>(construct<OmpClause::Grainsize>("GRAINSIZE"_tok >> parenthesized(scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::Lastprivate>("LASTPRIVATE"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
+construct<OmpClause>(construct<OmpClause::Link>("LINK"_tok >> parenthesized(nonemptyList(name)))) ||
+construct<OmpClause>(construct<OmpClause::NumTasks>("NUM_TASKS"_tok >> parenthesized(scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::NumTeams>( "NUM_TEAMS"_tok >> parenthesized(scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::NumThreads>("NUM_THREADS"_tok >> parenthesized(scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::Ordered>("ORDERED"_tok >> maybe(parenthesized(scalarIntConstantExpr)))) ||
+construct<OmpClause>(construct<OmpClause::Priority>("PRIORITY"_tok >> parenthesized(scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::Private>("PRIVATE"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
+construct<OmpClause>(construct<OmpClause::Safelen>("SAFELEN"_tok >> parenthesized(scalarIntConstantExpr))) ||
+construct<OmpClause>(construct<OmpClause::Shared>("SHARED"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
+construct<OmpClause>(construct<OmpClause::Simdlen>("SIMDLEN"_tok >> parenthesized(scalarIntConstantExpr))) ||
+construct<OmpClause>(construct<OmpClause::ThreadLimit>("THREAD_LIMIT"_tok >> parenthesized(scalarIntExpr))) ||
+construct<OmpClause>(construct<OmpClause::To>("TO"_tok >> parenthesized(nonemptyList(designator)))) ||
+construct<OmpClause>(construct<OmpClause::Uniform>("UNIFORM"_tok >> parenthesized(nonemptyList(name)))) ||
+construct<OmpClause>(construct<OmpClause::UseDevicePtr>("USE_DEVICE_PTR"_tok >> parenthesized(nonemptyList(name)))) ||
+construct<OmpClause>("ALIGNED"_tok >> parenthesized(Parser<OmpAlignedClause>{})) ||
+construct<OmpClause>("DEFAULT"_tok >> parenthesized(Parser<OmpDefaultClause>{})) ||
+construct<OmpClause>("DEPEND"_tok >> parenthesized(Parser<OmpDependClause>{})) ||
+construct<OmpClause>("IF"_tok >> parenthesized(Parser<OmpIfClause>{})) ||
+construct<OmpClause>("LINEAR"_tok >> parenthesized(Parser<OmpLinearClause>{})) ||
+construct<OmpClause>("MAP"_tok >> parenthesized(Parser<OmpMapClause>{})) ||
+construct<OmpClause>("PROC_BIND"_tok >> parenthesized(Parser<OmpProcBindClause>{})) ||
+construct<OmpClause>("REDUCTION"_tok >> parenthesized(Parser<OmpReductionClause>{})) ||
+construct<OmpClause>("SCHEDULE"_tok >> parenthesized(Parser<OmpScheduleClause>{}))
+)
+
+TYPE_PARSER(skipEmptyLines >> space >> "!$OMP END"_sptok >>
+    (construct<OmpEndDirective>(Parser<OmpLoopDirective>{})))
+
+// Omp directives enclosing do loop
+TYPE_PARSER(
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::DistributeParallelDoSimd>(
+            "DISTRIBUTE PARALLEL DO SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::DistributeParallelDo>(
+            "DISTRIBUTE PARALLEL DO"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::DistributeSimd>(
+        "DISTRIBUTE SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::Distribute>(
+        "DISTRIBUTE"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::DoSimd>(
+        "DO SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::Do>(
+        "DO"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::ParallelDoSimd>(
+        "PARALLEL DO SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::ParallelDo>(
+        "PARALLEL DO"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::Simd>(
+        "SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::TargetParallelDoSimd>(
+            "TARGET PARALLEL DO SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::TargetParallelDo>(
+        "TARGET PARALLEL DO"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::TargetSimd>(
+        "TARGET SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::TargetTeamsDistributeParallelDoSimd>(
+            "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD"_tok >>
+            many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::TargetTeamsDistributeParallelDo>(
+            "TARGET TEAMS DISTRIBUTE PARALLEL DO"_tok >>
+            many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::TargetTeamsDistributeSimd>(
+            "TARGET TEAMS DISTRIBUTE SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::TargetTeamsDistribute>(
+            "TARGET TEAMS DISTRIBUTE"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::TaskloopSimd>(
+        "TASKLOOP SIMD" >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::Taskloop>(
+        "TASKLOOP" >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::TeamsDistributeParallelDoSimd>(
+            "TEAMS DISTRIBUTE PARALLEL DO SIMD"_tok >>
+            many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::TeamsDistributeParallelDo>(
+            "TEAMS DISTRIBUTE PARALLEL DO"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(
+        construct<OmpLoopDirective::TeamsDistributeSimd>(
+            "TEAMS DISTRIBUTE SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpLoopDirective>(construct<OmpLoopDirective::TeamsDistribute>(
+        "TEAMS DISTRIBUTE"_tok >> many(Parser<OmpClause>{}))))
+
+TYPE_PARSER(construct<OmpDeclDirective>(construct<OmpDeclDirective::DeclareReduction>(
+        "DECLARE REDUCTION"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpDeclDirective>(construct<OmpDeclDirective::DeclareSimd>(
+        "DECLARE SIMD"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpDeclDirective>(construct<OmpDeclDirective::DeclareTarget>(
+        "DECLARE TARGET"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpDeclDirective>(construct<OmpDeclDirective::Threadprivate>(
+        "THREADPRIVATE"_tok >> many(Parser<OmpClause>{}))))
+
+TYPE_PARSER(construct<OmpStandaloneDirective>(
+                construct<OmpStandaloneDirective::Barrier>(
+                    "BARRIER"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpStandaloneDirective>(
+        construct<OmpStandaloneDirective::CancellationPoint>(
+            "CANCELLATION POINT"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpStandaloneDirective>(construct<OmpStandaloneDirective::Cancel>(
+        "CANCEL"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpStandaloneDirective>(construct<OmpStandaloneDirective::Flush>(
+        "FLUSH"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpStandaloneDirective>(
+        construct<OmpStandaloneDirective::TargetEnterData>(
+            "TARGET ENTER DATA"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpStandaloneDirective>(
+        construct<OmpStandaloneDirective::TargetExitData>(
+            "TARGET EXIT DATA"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpStandaloneDirective>(
+        construct<OmpStandaloneDirective::TargetUpdate>(
+            "TARGET UPDATE"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpStandaloneDirective>(
+        construct<OmpStandaloneDirective::Taskwait>(
+            "TASKWAIT"_tok >> many(Parser<OmpClause>{}))) ||
+    construct<OmpStandaloneDirective>(
+        construct<OmpStandaloneDirective::Taskyield>(
+            "TASKYIELD"_tok >> many(Parser<OmpClause>{}))))
+
+TYPE_PARSER(
+    construct<OpenMPLoopConstruct>(statement(Parser<OmpLoopDirective>{}),
+        Parser<DoConstruct>{}, maybe(Parser<OmpEndDirective>{})))
+
+TYPE_PARSER(construct<OpenMPStandaloneConstruct>(
+    statement(Parser<OmpStandaloneDirective>{})))
+
+TYPE_PARSER(
+    construct<OpenMPDeclConstruct>(statement(Parser<OmpDeclDirective>{})))
+
+TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
+    beginOmpDirective >>
+        (construct<OpenMPConstruct>(
+             indirect(Parser<OpenMPStandaloneConstruct>{})) ||
+            construct<OpenMPConstruct>(
+                indirect(Parser<OpenMPLoopConstruct>{})) ||
+            construct<OpenMPConstruct>(
+                indirect(Parser<OpenMPDeclConstruct>{}))))
+
+}  // namespace Fortran::parser
+#endif  // OPENMP_PARSER_GRAMMAR_H_
index fcb4624..ed6161a 100644 (file)
@@ -674,5 +674,42 @@ void Walk(format::IntrinsicTypeDataEditDesc &x, M &mutator) {
   }
 }
 
+
+template<typename V>
+void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
+  if (visitor.Pre(x)) {
+    Walk(x.modifier, visitor);
+    Walk(x.names, visitor);
+    Walk(x.step, visitor);
+    visitor.Post(x);
+  }
+}
+template<typename M>
+void Walk(OmpLinearClause::WithModifier &x, M &mutator) {
+  if (mutator.Pre(x)) {
+    Walk(x.modifier, mutator);
+    Walk(x.names, mutator);
+    Walk(x.step, mutator);
+    mutator.Post(x);
+  }
+}
+template<typename V>
+void Walk(const OmpLinearClause::WithoutModifier &x, V &visitor) {
+  if (visitor.Pre(x)) {
+    Walk(x.names, visitor);
+    Walk(x.step, visitor);
+    visitor.Post(x);
+  }
+}
+template<typename M>
+void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) {
+  if (mutator.Pre(x)) {
+    Walk(x.names, mutator);
+    Walk(x.step, mutator);
+    mutator.Post(x);
+  }
+}
+
+
 }  // namespace Fortran::parser
 #endif  // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
index bf0ed09..afe9579 100644 (file)
@@ -248,8 +248,12 @@ struct ArithmeticIfStmt;
 struct AssignStmt;
 struct AssignedGotoStmt;
 struct PauseStmt;
-struct OmpDirective;
+struct OpenMPConstruct;
 struct OmpClause;
+struct OmpDeclDirective;
+struct OmpStandaloneDirective;
+struct OmpLoopDirective;
+struct OmpEndDirective;
 
 // Cooked character stream locations
 using Location = const char *;
@@ -359,7 +363,7 @@ struct SpecificationConstruct {
       Statement<Indirection<ProcedureDeclarationStmt>>,
       Statement<OtherSpecificationStmt>,
       Statement<Indirection<TypeDeclarationStmt>>, Indirection<StructureDef>,
-      Indirection<CompilerDirective>, Indirection<OmpDirective>>
+      Indirection<OpenMPConstruct>, Indirection<CompilerDirective>>
       u;
 };
 
@@ -469,7 +473,7 @@ struct ExecutableConstruct {
       Indirection<DoConstruct>, Indirection<IfConstruct>,
       Indirection<SelectRankConstruct>, Indirection<SelectTypeConstruct>,
       Indirection<WhereConstruct>, Indirection<ForallConstruct>,
-      Indirection<CompilerDirective>, Indirection<OmpDirective>>
+      Indirection<CompilerDirective>, Indirection<OpenMPConstruct>>
       u;
 };
 
@@ -3191,29 +3195,258 @@ struct AssignedGotoStmt {
 
 WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
 
-// OpenMP Directives and Clauses
-struct OmpClause {
-  UNION_CLASS_BOILERPLATE(OmpClause);
-  WRAPPER_CLASS(Firstprivate, std::list<Name>);
-  WRAPPER_CLASS(Private, std::list<Name>);
-  std::variant<Firstprivate, Private> u;
+// PROC_BIND(CLOSE | MASTER | SPREAD)
+struct OmpProcBindClause {
+  ENUM_CLASS(Type, Close, Master, Spread)
+  WRAPPER_CLASS_BOILERPLATE(OmpProcBindClause, Type);
+};
+
+// DEFAULT(PRIVATE | FIRSTPRIVATE | SHARED | NOND)
+struct OmpDefaultClause {
+  ENUM_CLASS(Type, Private, Firstprivate, Shared, None)
+  WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, Type);
+};
+
+// List -> variable-name | / common-block /
+struct OmpNameList {
+  TUPLE_CLASS_BOILERPLATE(OmpNameList);
+  ENUM_CLASS(Kind, Object, Common)
+  std::tuple<Kind, Name> t;
+};
+
+// MAP((TO | FROM | TOFROM | ALLOC | RELEASE | DELETE) : list)
+struct OmpMapClause {
+  TUPLE_CLASS_BOILERPLATE(OmpMapClause);
+  ENUM_CLASS(Type, To, From, Tofrom, Alloc, Release, Delete)
+  std::tuple<std::optional<Type>, std::list<Name>> t;
+};
+
+// schedule-modifier -> MONOTONIC | NONMONOTONIC | SIMD
+struct OmpScheduleModifierType {
+  ENUM_CLASS(ModType, Monotonic, Nonmonotonic, Simd)
+  WRAPPER_CLASS_BOILERPLATE(OmpScheduleModifierType, ModType);
+};
+
+// SCHEDULE([schedule-modifier [,schedule-modifier]] kind [,  Chunksize])
+struct OmpScheduleClause {
+  TUPLE_CLASS_BOILERPLATE(OmpScheduleClause);
+  ENUM_CLASS(ScheduleType, Static, Dynamic, Guided, Auto, Runtime)
+  WRAPPER_CLASS(Chunksize, ScalarIntExpr);
+  std::tuple<std::list<OmpScheduleModifierType>, std::optional<ScheduleType>,
+      Chunksize>
+      t;
+};
+
+// IF(DirectiveNameModifier: scalar-logical-expr)
+struct OmpIfClause {
+  TUPLE_CLASS_BOILERPLATE(OmpIfClause);
+  ENUM_CLASS(DirectiveNameModifier, Parallel, Target, TargetEnterData,
+      TargetExitData, TargetData, TargetUpdate, Taskloop, Task)
+  std::tuple<std::optional<DirectiveNameModifier>, ScalarLogicalExpr> t;
+};
+
+// ALIGNED(list, scalar-int-constant-expr)
+struct OmpAlignedClause {
+  TUPLE_CLASS_BOILERPLATE(OmpAlignedClause);
+  std::tuple<std::list<Name>, std::optional<ScalarIntConstantExpr>> t;
+};
+
+// linear-modifier -> REF | VAL | UVAL
+struct OmpLinearModifier {
+  ENUM_CLASS(Type, Ref, Val, Uval)
+  WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Type);
+};
+
+// LINEAR((modifier(list) | (list)) [: linear-step])
+struct OmpLinearClause {
+  UNION_CLASS_BOILERPLATE(OmpLinearClause);
+  struct WithModifier {
+    BOILERPLATE(WithModifier);
+    WithModifier(OmpLinearModifier &&m, std::list<Name> &&n,
+        std::optional<ScalarIntConstantExpr> &&s)
+      : modifier(std::move(m)), names(std::move(n)), step(std::move(s)) {}
+    OmpLinearModifier modifier;
+    std::list<Name> names;
+    std::optional<ScalarIntConstantExpr> step;
+  };
+  struct WithoutModifier {
+    BOILERPLATE(WithoutModifier);
+    WithoutModifier(
+        std::list<Name> &&n, std::optional<ScalarIntConstantExpr> &&s)
+      : names(std::move(n)), step(std::move(s)) {}
+    std::list<Name> names;
+    std::optional<ScalarIntConstantExpr> step;
+  };
+  std::variant<WithModifier, WithoutModifier> u;
 };
 
-struct OmpExeDir {
-  UNION_CLASS_BOILERPLATE(OmpExeDir);
+// reduction-identifier -> Add, Subtract, Multiply, .and., .or., .eqv., .neqg., min, max, iand, ior, ieor
+struct OmpReductionOperator {
+  UNION_CLASS_BOILERPLATE(OmpReductionOperator);
+  ENUM_CLASS(ProcedureOperator, MIN, MAX, IAND, IOR, IEOR)
+  ENUM_CLASS(BinaryOperator, Add, Subtract, Multiply, AND, OR, EQV, NEQV)
+  std::variant<ProcedureOperator, BinaryOperator> u;
+};
+
+// REDUCTION(reduction-identifier: list)
+struct OmpReductionClause {
+  TUPLE_CLASS_BOILERPLATE(OmpReductionClause);
+  std::tuple<OmpReductionOperator, std::list<Designator>> t;
+};
+
+// DEPEND(SOURCE | SINK: vec | DEPEND((IN | OUT | INOUT) : list)
+//  vec -> iterator_variable [ +/- d1], x2 [ +/- d2], ...
+//  d1 -> non-negative-constant
+//  list -> names | array-sections
+
+struct OmpDependSinkVecLength {
+  TUPLE_CLASS_BOILERPLATE(OmpDependSinkVecLength);
+  std::tuple<Indirection<DefinedOperator>, ScalarIntConstantExpr> t;
+};
+
+struct OmpDependSinkVec {
+  TUPLE_CLASS_BOILERPLATE(OmpDependSinkVec);
+  std::tuple<Name, std::optional<OmpDependSinkVecLength>> t;
+};
+
+struct OmpDependenceType {
+  ENUM_CLASS(Type, In, Out, Inout, Source, Sink)
+  WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type);
+};
+
+struct OmpDependClause {
+  UNION_CLASS_BOILERPLATE(OmpDependClause);
+  EMPTY_CLASS(Source);
+  WRAPPER_CLASS(Sink, std::list<OmpDependSinkVec>);
+  struct InOut {
+    TUPLE_CLASS_BOILERPLATE(InOut);
+    std::tuple<OmpDependenceType, std::list<Designator>> t;
+  };
+  std::variant<Source, Sink, InOut> u;
+};
+
+// OpenMP Clauses
+struct OmpClause {
+  UNION_CLASS_BOILERPLATE(OmpClause);
+  EMPTY_CLASS(Defaultmap);
+  EMPTY_CLASS(Inbranch);
+  EMPTY_CLASS(Mergeable);
+  EMPTY_CLASS(Nogroup);
+  EMPTY_CLASS(Notinbranch);
+  EMPTY_CLASS(Nowait);
+  EMPTY_CLASS(Untied);
+  WRAPPER_CLASS(Collapse, ScalarIntConstantExpr);
+  WRAPPER_CLASS(Copyin, std::list<OmpNameList>);
+  WRAPPER_CLASS(Copyprivate, std::list<OmpNameList>);
+  WRAPPER_CLASS(Device, ScalarIntExpr);
+  WRAPPER_CLASS(DistSchedule, ScalarIntExpr);
+  WRAPPER_CLASS(Final, ScalarIntExpr);
+  WRAPPER_CLASS(Firstprivate, std::list<OmpNameList>);
+  WRAPPER_CLASS(From, std::list<Designator>);
+  WRAPPER_CLASS(Grainsize, ScalarIntExpr);
+  WRAPPER_CLASS(Lastprivate, std::list<OmpNameList>);
+  WRAPPER_CLASS(Link, std::list<Name>);
+  WRAPPER_CLASS(NumTasks, ScalarIntExpr);
+  WRAPPER_CLASS(NumTeams, ScalarIntExpr);
+  WRAPPER_CLASS(NumThreads, ScalarIntExpr);
+  WRAPPER_CLASS(Ordered, std::optional<ScalarIntConstantExpr>);
+  WRAPPER_CLASS(Priority, ScalarIntExpr);
+  WRAPPER_CLASS(Private, std::list<OmpNameList>);
+  WRAPPER_CLASS(Safelen, ScalarIntConstantExpr);
+  WRAPPER_CLASS(Shared, std::list<OmpNameList>);
+  WRAPPER_CLASS(Simdlen, ScalarIntConstantExpr);
+  WRAPPER_CLASS(ThreadLimit, ScalarIntExpr);
+  WRAPPER_CLASS(To, std::list<Designator>);
+  WRAPPER_CLASS(Uniform, std::list<Name>);
+  WRAPPER_CLASS(UseDevicePtr, std::list<Name>);
+  std::variant<Defaultmap, Inbranch, Mergeable, Nogroup, Notinbranch, Nowait,
+  Untied, Collapse, Copyin, Copyprivate, Device, DistSchedule,
+  Final, Firstprivate, From, Grainsize, Lastprivate, Link,
+  NumTasks, NumTeams, NumThreads, Ordered, Priority, Private, Safelen,
+  Shared, Simdlen, ThreadLimit, To, Uniform, UseDevicePtr,
+  OmpAlignedClause, OmpDefaultClause, OmpDependClause, OmpIfClause, 
+  OmpLinearClause, OmpMapClause, OmpProcBindClause, OmpReductionClause, 
+  OmpScheduleClause> u;
+};
+
+struct OmpDeclDirective {
+  UNION_CLASS_BOILERPLATE(OmpDeclDirective);
+  WRAPPER_CLASS(DeclareReduction, std::list<OmpClause>);
+  WRAPPER_CLASS(DeclareSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(DeclareTarget, std::list<OmpClause>);
+  WRAPPER_CLASS(Threadprivate, std::list<OmpClause>);
+  std::variant<DeclareReduction, DeclareSimd, DeclareTarget, Threadprivate> u;
+};
+
+struct OmpLoopDirective {
+  UNION_CLASS_BOILERPLATE(OmpLoopDirective);
+  WRAPPER_CLASS(DistributeParallelDoSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(DistributeParallelDo, std::list<OmpClause>);
+  WRAPPER_CLASS(DistributeSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(Distribute, std::list<OmpClause>);
+  WRAPPER_CLASS(DoSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(Do, std::list<OmpClause>);
   WRAPPER_CLASS(ParallelDoSimd, std::list<OmpClause>);
   WRAPPER_CLASS(ParallelDo, std::list<OmpClause>);
-  WRAPPER_CLASS(ParallelSections, std::list<OmpClause>);
-  WRAPPER_CLASS(ParallelWorkshare, std::list<OmpClause>);
-  WRAPPER_CLASS(Parallel, std::list<OmpClause>);
-  std::variant<ParallelDoSimd, ParallelDo, ParallelSections, ParallelWorkshare,
-      Parallel>
+  WRAPPER_CLASS(Simd, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetParallelDoSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetParallelDo, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetTeamsDistributeParallelDoSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetTeamsDistributeParallelDo, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetTeamsDistributeSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetTeamsDistribute, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(TaskloopSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(Taskloop, std::list<OmpClause>);
+  WRAPPER_CLASS(TeamsDistributeParallelDoSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(TeamsDistributeParallelDo, std::list<OmpClause>);
+  WRAPPER_CLASS(TeamsDistributeSimd, std::list<OmpClause>);
+  WRAPPER_CLASS(TeamsDistribute, std::list<OmpClause>);
+  std::variant<DistributeParallelDoSimd, DistributeParallelDo, DistributeSimd,
+      Distribute, DoSimd, Do, ParallelDoSimd, ParallelDo, Simd,
+      TargetParallelDoSimd, TargetParallelDo,
+      TargetTeamsDistributeParallelDoSimd, TargetTeamsDistributeParallelDo,
+      TargetTeamsDistributeSimd, TargetTeamsDistribute, TargetSimd,
+      TaskloopSimd, Taskloop, TeamsDistributeParallelDoSimd,
+      TeamsDistributeParallelDo, TeamsDistributeSimd, TeamsDistribute>
+      u;
+};
+
+struct OmpStandaloneDirective {
+  UNION_CLASS_BOILERPLATE(OmpStandaloneDirective);
+  WRAPPER_CLASS(Barrier, std::list<OmpClause>);
+  WRAPPER_CLASS(CancellationPoint, std::list<OmpClause>);
+  WRAPPER_CLASS(Cancel, std::list<OmpClause>);
+  WRAPPER_CLASS(Flush, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetEnterData, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetExitData, std::list<OmpClause>);
+  WRAPPER_CLASS(TargetUpdate, std::list<OmpClause>);
+  WRAPPER_CLASS(Taskwait, std::list<OmpClause>);
+  WRAPPER_CLASS(Taskyield, std::list<OmpClause>);
+  std::variant<Barrier, CancellationPoint, Cancel, Flush, TargetEnterData,
+      TargetExitData, TargetUpdate, Taskwait, Taskyield>
       u;
 };
 
-struct OmpDirective {
-  UNION_CLASS_BOILERPLATE(OmpDirective);
-  std::variant<Indirection<OmpExeDir>> u;
+struct OmpEndDirective {
+  UNION_CLASS_BOILERPLATE(OmpEndDirective);
+  std::variant<OmpLoopDirective> u;
+};
+
+struct OpenMPLoopConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPLoopConstruct);
+  std::tuple<Statement<OmpLoopDirective>, DoConstruct,
+      std::optional<OmpEndDirective>>
+      t;
+};
+
+WRAPPER_CLASS(OpenMPDeclConstruct, Statement<OmpDeclDirective>);
+WRAPPER_CLASS(OpenMPStandaloneConstruct, Statement<OmpStandaloneDirective>);
+
+struct OpenMPConstruct {
+  UNION_CLASS_BOILERPLATE(OpenMPConstruct);
+  std::variant<Indirection<OpenMPStandaloneConstruct>,
+      Indirection<OpenMPDeclConstruct>, Indirection<OpenMPLoopConstruct>> u;
 };
 
 }  // namespace parser
index 6774211..1647fe5 100644 (file)
@@ -15,6 +15,7 @@
 #include "parsing.h"
 #include "grammar.h"
 #include "instrumented-parser.h"
+#include "openmp-grammar.h"
 #include "message.h"
 #include "preprocessor.h"
 #include "prescan.h"
index 62394a7..b8dd9dc 100644 (file)
@@ -140,7 +140,7 @@ constexpr Parser<EndSubroutineStmt> endSubroutineStmt;  // R1537
 constexpr Parser<EntryStmt> entryStmt;  // R1541
 constexpr Parser<ContainsStmt> containsStmt;  // R1543
 constexpr Parser<CompilerDirective> compilerDirective;
-constexpr Parser<OmpDirective> ompDirective;
+constexpr Parser<OpenMPConstruct> openmpConstruct;
 
 }  // namespace Fortran::parser
 #endif  // FORTRAN_PARSER_TYPE_PARSERS_H_
index 1ea1a58..4abb32a 100644 (file)
@@ -1648,46 +1648,6 @@ public:
     }
     Walk(std::get<Name>(x.t));
   }
-  // OpenMP Directives
-  void Unparse(const OmpClause &x) {
-    std::visit(visitors{[&](const OmpClause::Firstprivate &y) {
-                          Word(" FIRSTPRIVATE(");
-                          Walk(y.v, ",");
-                          Put(")");
-                        },
-                   [&](const OmpClause::Private &y) {
-                     Word(" PRIVATE(");
-                     Walk(y.v, ",");
-                     Put(")");
-                   }},
-        x.u);
-  }
-  void Unparse(const OmpExeDir &x) {
-    Outdent();
-    std::visit(visitors{[&](const OmpExeDir::ParallelDoSimd &y) {
-                          Word("!OMP$ PARALLEL DO SIMD");
-                          Walk(y.v, " ");
-                        },
-                   [&](const OmpExeDir::ParallelDo &y) {
-                     Word("!OMP$ PARALLEL DO");
-                     Walk(y.v, " ");
-                   },
-                   [&](const OmpExeDir::ParallelSections &y) {
-                     Word("!OMP$ PARALLEL SECTIONS");
-                     Walk(y.v, " ");
-                   },
-                   [&](const OmpExeDir::ParallelWorkshare &y) {
-                     Word("!OMP$ PARALLEL WORKSHARE");
-                     Walk(y.v, " ");
-                   },
-                   [&](const OmpExeDir::Parallel &y) {
-                     Word("!OMP$ PARALLEL");
-                     Walk(y.v, " ");
-                   }},
-        x.u);
-    Put('\n');
-    Indent();
-  }
   void Unparse(const BasedPointerStmt &x) {
     Word("POINTER ("), Walk(std::get<0>(x.t)), Put(", ");
     Walk(std::get<1>(x.t));
index afa748f..4fb5101 100644 (file)
@@ -15,6 +15,7 @@
 #include "user-state.h"
 #include "basic-parsers.h"
 #include "grammar.h"
+#include "openmp-grammar.h"
 #include "parse-state.h"
 #include "stmt-parser.h"
 #include "type-parsers.h"
index 262f525..e93a1eb 100644 (file)
@@ -393,16 +393,114 @@ public:
   NODE(parser, NullInit)
   NODE(parser, ObjectDecl)
   NODE(parser, OldParameterStmt)
+  NODE(parser, OmpAlignedClause)
   NODE(parser, OmpClause)
+  NODE(parser::OmpClause, Collapse)
+  NODE(parser::OmpClause, Copyin)
+  NODE(parser::OmpClause, Copyprivate)
+  NODE(parser::OmpClause, Defaultmap)
+  NODE(parser::OmpClause, Device)
+  NODE(parser::OmpClause, DistSchedule)
+  NODE(parser::OmpClause, Final)
   NODE(parser::OmpClause, Firstprivate)
+  NODE(parser::OmpClause, From)
+  NODE(parser::OmpClause, Grainsize)
+  NODE(parser::OmpClause, Inbranch)
+  NODE(parser::OmpClause, Lastprivate)
+  NODE(parser::OmpClause, Link)
+  NODE(parser::OmpClause, Mergeable)
+  NODE(parser::OmpClause, Nogroup)
+  NODE(parser::OmpClause, Notinbranch)
+  NODE(parser::OmpClause, Nowait)
+  NODE(parser::OmpClause, NumTasks)
+  NODE(parser::OmpClause, NumTeams)
+  NODE(parser::OmpClause, NumThreads)
+  NODE(parser::OmpClause, Ordered)
+  NODE(parser::OmpClause, Priority)
   NODE(parser::OmpClause, Private)
-  NODE(parser, OmpDirective)
-  NODE(parser, OmpExeDir)
-  NODE(parser::OmpExeDir, Parallel)
-  NODE(parser::OmpExeDir, ParallelDo)
-  NODE(parser::OmpExeDir, ParallelDoSimd)
-  NODE(parser::OmpExeDir, ParallelWorkshare)
-  NODE(parser::OmpExeDir, ParallelSections)
+  NODE(parser::OmpClause, Safelen)
+  NODE(parser::OmpClause, Shared)
+  NODE(parser::OmpClause, Simdlen)
+  NODE(parser::OmpClause, ThreadLimit)
+  NODE(parser::OmpClause, To)
+  NODE(parser::OmpClause, Uniform)
+  NODE(parser::OmpClause, Untied)
+  NODE(parser::OmpClause, UseDevicePtr)
+  NODE(parser, OmpDeclDirective)
+  NODE(parser::OmpDeclDirective, DeclareReduction)
+  NODE(parser::OmpDeclDirective, DeclareSimd)
+  NODE(parser::OmpDeclDirective, DeclareTarget)
+  NODE(parser::OmpDeclDirective, Threadprivate)
+  NODE(parser, OmpDefaultClause)
+  NODE(parser::OmpDefaultClause, Type)
+  NODE(parser, OmpDependClause)
+  NODE(parser::OmpDependClause, InOut)
+  NODE(parser::OmpDependClause, Sink)
+  NODE(parser::OmpDependClause, Source)
+  NODE(parser, OmpDependenceType)
+  NODE(parser::OmpDependenceType, Type)
+  NODE(parser, OmpDependSinkVec)
+  NODE(parser, OmpDependSinkVecLength)
+  NODE(parser, OmpEndDirective)
+  NODE(parser, OmpLinearClause)
+  NODE(parser::OmpLinearClause, WithModifier)
+  NODE(parser::OmpLinearClause, WithoutModifier)
+  NODE(parser, OmpLinearModifier)
+  NODE(parser::OmpLinearModifier, Type)
+  NODE(parser, OmpLoopDirective)
+  NODE(parser::OmpLoopDirective, Distribute)
+  NODE(parser::OmpLoopDirective, DistributeParallelDo)
+  NODE(parser::OmpLoopDirective, DistributeParallelDoSimd)
+  NODE(parser::OmpLoopDirective, DistributeSimd)
+  NODE(parser::OmpLoopDirective, Do)
+  NODE(parser::OmpLoopDirective, DoSimd)
+  NODE(parser::OmpLoopDirective, ParallelDo)
+  NODE(parser::OmpLoopDirective, ParallelDoSimd)
+  NODE(parser::OmpLoopDirective, Simd)
+  NODE(parser::OmpLoopDirective, TargetParallelDo)
+  NODE(parser::OmpLoopDirective, TargetParallelDoSimd)
+  NODE(parser::OmpLoopDirective, TargetSimd)
+  NODE(parser::OmpLoopDirective, TargetTeamsDistribute)
+  NODE(parser::OmpLoopDirective, TargetTeamsDistributeParallelDo)
+  NODE(parser::OmpLoopDirective, TargetTeamsDistributeParallelDoSimd)
+  NODE(parser::OmpLoopDirective, TargetTeamsDistributeSimd)
+  NODE(parser::OmpLoopDirective, Taskloop)
+  NODE(parser::OmpLoopDirective, TaskloopSimd)
+  NODE(parser::OmpLoopDirective, TeamsDistribute)
+  NODE(parser::OmpLoopDirective, TeamsDistributeParallelDo)
+  NODE(parser::OmpLoopDirective, TeamsDistributeParallelDoSimd)
+  NODE(parser::OmpLoopDirective, TeamsDistributeSimd)
+  NODE(parser, OmpIfClause)
+  NODE(parser::OmpIfClause, DirectiveNameModifier)
+  NODE(parser, OmpScheduleClause)
+  NODE(parser::OmpScheduleClause, ScheduleType)
+  NODE(parser::OmpScheduleClause, Chunksize)
+  NODE(parser, OmpScheduleModifierType)
+  NODE(parser::OmpScheduleModifierType, ModType)
+  NODE(parser, OmpMapClause)
+  NODE(parser::OmpMapClause, Type)
+  NODE(parser, OmpNameList)
+  NODE(parser::OmpNameList, Kind)
+  NODE(parser, OmpProcBindClause)
+  NODE(parser::OmpProcBindClause, Type)
+  NODE(parser, OmpReductionOperator)
+  NODE(parser::OmpReductionOperator, ProcedureOperator)
+  NODE(parser::OmpReductionOperator, BinaryOperator)
+  NODE(parser, OmpStandaloneDirective)
+  NODE(parser::OmpStandaloneDirective, Barrier)
+  NODE(parser::OmpStandaloneDirective, Cancel)
+  NODE(parser::OmpStandaloneDirective, CancellationPoint)
+  NODE(parser::OmpStandaloneDirective, Flush)
+  NODE(parser::OmpStandaloneDirective, TargetEnterData)
+  NODE(parser::OmpStandaloneDirective, TargetExitData)
+  NODE(parser::OmpStandaloneDirective, TargetUpdate)
+  NODE(parser::OmpStandaloneDirective, Taskwait)
+  NODE(parser::OmpStandaloneDirective, Taskyield)
+  NODE(parser, OpenMPConstruct)
+  NODE(parser, OpenMPDeclConstruct)
+  NODE(parser, OpenMPLoopConstruct)
+  NODE(parser, OpenMPStandaloneConstruct)
+  NODE(parser, OmpReductionClause)
   NODE(parser, Only)
   NODE(parser, OpenStmt)
   NODE(parser, Optional)