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.1 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/Frontend/OpenACC/ACC.h.inc" 22 23 using AccDirectiveSet = Fortran::common::EnumSet<llvm::acc::Directive, 24 llvm::acc::Directive_enumSize>; 25 26 using AccClauseSet = 27 Fortran::common::EnumSet<llvm::acc::Clause, llvm::acc::Clause_enumSize>; 28 29 #define GEN_FLANG_DIRECTIVE_CLAUSE_SETS 30 #include "llvm/Frontend/OpenACC/ACC.cpp.inc" 31 32 namespace Fortran::semantics { 33 34 class AccStructureChecker 35 : public DirectiveStructureChecker<llvm::acc::Directive, llvm::acc::Clause, 36 parser::AccClause, llvm::acc::Clause_enumSize> { 37 public: AccStructureChecker(SemanticsContext & context)38 AccStructureChecker(SemanticsContext &context) 39 : DirectiveStructureChecker(context, 40 #define GEN_FLANG_DIRECTIVE_CLAUSE_MAP 41 #include "llvm/Frontend/OpenACC/ACC.cpp.inc" 42 ) { 43 } 44 45 // Construct and directives 46 void Enter(const parser::OpenACCBlockConstruct &); 47 void Leave(const parser::OpenACCBlockConstruct &); 48 void Enter(const parser::OpenACCCombinedConstruct &); 49 void Leave(const parser::OpenACCCombinedConstruct &); 50 void Enter(const parser::OpenACCLoopConstruct &); 51 void Leave(const parser::OpenACCLoopConstruct &); 52 void Enter(const parser::OpenACCRoutineConstruct &); 53 void Leave(const parser::OpenACCRoutineConstruct &); 54 void Enter(const parser::OpenACCStandaloneConstruct &); 55 void Leave(const parser::OpenACCStandaloneConstruct &); 56 void Enter(const parser::OpenACCStandaloneDeclarativeConstruct &); 57 void Leave(const parser::OpenACCStandaloneDeclarativeConstruct &); 58 void Enter(const parser::OpenACCWaitConstruct &); 59 void Leave(const parser::OpenACCWaitConstruct &); 60 void Enter(const parser::OpenACCAtomicConstruct &); 61 void Leave(const parser::OpenACCAtomicConstruct &); 62 void Enter(const parser::OpenACCCacheConstruct &); 63 void Leave(const parser::OpenACCCacheConstruct &); 64 65 // Clauses 66 void Leave(const parser::AccClauseList &); 67 void Enter(const parser::AccClause &); 68 69 void Enter(const parser::AccClause::Auto &); 70 void Enter(const parser::AccClause::Async &); 71 void Enter(const parser::AccClause::Attach &); 72 void Enter(const parser::AccClause::Bind &); 73 void Enter(const parser::AccClause::Capture &); 74 void Enter(const parser::AccClause::Create &); 75 void Enter(const parser::AccClause::Collapse &); 76 void Enter(const parser::AccClause::Copy &); 77 void Enter(const parser::AccClause::Copyin &); 78 void Enter(const parser::AccClause::Copyout &); 79 void Enter(const parser::AccClause::Default &); 80 void Enter(const parser::AccClause::DefaultAsync &); 81 void Enter(const parser::AccClause::Delete &); 82 void Enter(const parser::AccClause::Detach &); 83 void Enter(const parser::AccClause::Device &); 84 void Enter(const parser::AccClause::DeviceNum &); 85 void Enter(const parser::AccClause::Deviceptr &); 86 void Enter(const parser::AccClause::DeviceResident &); 87 void Enter(const parser::AccClause::DeviceType &); 88 void Enter(const parser::AccClause::Finalize &); 89 void Enter(const parser::AccClause::Firstprivate &); 90 void Enter(const parser::AccClause::Gang &); 91 void Enter(const parser::AccClause::Host &); 92 void Enter(const parser::AccClause::If &); 93 void Enter(const parser::AccClause::IfPresent &); 94 void Enter(const parser::AccClause::Independent &); 95 void Enter(const parser::AccClause::Link &); 96 void Enter(const parser::AccClause::NoCreate &); 97 void Enter(const parser::AccClause::Nohost &); 98 void Enter(const parser::AccClause::NumGangs &); 99 void Enter(const parser::AccClause::NumWorkers &); 100 void Enter(const parser::AccClause::Present &); 101 void Enter(const parser::AccClause::Private &); 102 void Enter(const parser::AccClause::Read &); 103 void Enter(const parser::AccClause::Reduction &); 104 void Enter(const parser::AccClause::Self &); 105 void Enter(const parser::AccClause::Seq &); 106 void Enter(const parser::AccClause::Tile &); 107 void Enter(const parser::AccClause::UseDevice &); 108 void Enter(const parser::AccClause::Vector &); 109 void Enter(const parser::AccClause::VectorLength &); 110 void Enter(const parser::AccClause::Wait &); 111 void Enter(const parser::AccClause::Worker &); 112 void Enter(const parser::AccClause::Write &); 113 114 private: 115 116 bool CheckAllowedModifier(llvm::acc::Clause clause); 117 bool IsComputeConstruct(llvm::acc::Directive directive) const; 118 bool IsInsideComputeConstruct() const; 119 void CheckNotInComputeConstruct(); 120 llvm::StringRef getClauseName(llvm::acc::Clause clause) override; 121 llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override; 122 }; 123 124 } // namespace Fortran::semantics 125 126 #endif // FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_ 127