xref: /llvm-project/flang/lib/Semantics/check-acc-structure.h (revision b096b8b1ff30abc9983da12d1b8c099530663627)
1 //===-- lib/Semantics/check-acc-structure.h ---------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 // OpenACC 3.3 structure validity check list
8 //    1. invalid clauses on directive
9 //    2. invalid repeated clauses on directive
10 //    3. invalid nesting of regions
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_
15 #define FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_
16 
17 #include "check-directive-structure.h"
18 #include "flang/Common/enum-set.h"
19 #include "flang/Parser/parse-tree.h"
20 #include "flang/Semantics/semantics.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/Frontend/OpenACC/ACC.h.inc"
23 
24 using AccDirectiveSet = Fortran::common::EnumSet<llvm::acc::Directive,
25     llvm::acc::Directive_enumSize>;
26 
27 using AccClauseSet =
28     Fortran::common::EnumSet<llvm::acc::Clause, llvm::acc::Clause_enumSize>;
29 
30 #define GEN_FLANG_DIRECTIVE_CLAUSE_SETS
31 #include "llvm/Frontend/OpenACC/ACC.inc"
32 
33 namespace Fortran::semantics {
34 
35 class AccStructureChecker
36     : public DirectiveStructureChecker<llvm::acc::Directive, llvm::acc::Clause,
37           parser::AccClause, llvm::acc::Clause_enumSize> {
38 public:
AccStructureChecker(SemanticsContext & context)39   AccStructureChecker(SemanticsContext &context)
40       : DirectiveStructureChecker(context,
41 #define GEN_FLANG_DIRECTIVE_CLAUSE_MAP
42 #include "llvm/Frontend/OpenACC/ACC.inc"
43         ) {
44   }
45 
46   // Construct and directives
47   void Enter(const parser::OpenACCBlockConstruct &);
48   void Leave(const parser::OpenACCBlockConstruct &);
49   void Enter(const parser::OpenACCCombinedConstruct &);
50   void Leave(const parser::OpenACCCombinedConstruct &);
51   void Enter(const parser::OpenACCLoopConstruct &);
52   void Leave(const parser::OpenACCLoopConstruct &);
53   void Enter(const parser::OpenACCRoutineConstruct &);
54   void Leave(const parser::OpenACCRoutineConstruct &);
55   void Enter(const parser::OpenACCStandaloneConstruct &);
56   void Leave(const parser::OpenACCStandaloneConstruct &);
57   void Enter(const parser::OpenACCStandaloneDeclarativeConstruct &);
58   void Leave(const parser::OpenACCStandaloneDeclarativeConstruct &);
59   void Enter(const parser::OpenACCWaitConstruct &);
60   void Leave(const parser::OpenACCWaitConstruct &);
61   void Enter(const parser::OpenACCAtomicConstruct &);
62   void Leave(const parser::OpenACCAtomicConstruct &);
63   void Enter(const parser::OpenACCCacheConstruct &);
64   void Leave(const parser::OpenACCCacheConstruct &);
65   void Enter(const parser::AccAtomicUpdate &);
66   void Enter(const parser::OpenACCEndConstruct &);
67 
68   // Clauses
69   void Leave(const parser::AccClauseList &);
70   void Enter(const parser::AccClause &);
71 
72   void Enter(const parser::Module &);
73   void Enter(const parser::SubroutineSubprogram &);
74   void Enter(const parser::FunctionSubprogram &);
75   void Enter(const parser::SeparateModuleSubprogram &);
76   void Enter(const parser::DoConstruct &);
77   void Leave(const parser::DoConstruct &);
78 
79 #define GEN_FLANG_CLAUSE_CHECK_ENTER
80 #include "llvm/Frontend/OpenACC/ACC.inc"
81 
82 private:
83   bool CheckAllowedModifier(llvm::acc::Clause clause);
84   bool IsComputeConstruct(llvm::acc::Directive directive) const;
85   bool IsInsideComputeConstruct() const;
86   void CheckNotInComputeConstruct();
87   void CheckMultipleOccurrenceInDeclare(
88       const parser::AccObjectList &, llvm::acc::Clause);
89   void CheckMultipleOccurrenceInDeclare(
90       const parser::AccObjectListWithModifier &, llvm::acc::Clause);
91   llvm::StringRef getClauseName(llvm::acc::Clause clause) override;
92   llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override;
93 
94   llvm::SmallDenseMap<Symbol *, llvm::acc::Clause> declareSymbols;
95   unsigned loopNestLevel = 0;
96 };
97 
98 } // namespace Fortran::semantics
99 
100 #endif // FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_
101