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