#ifndef FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_
#define FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_
#include "check-directive-structure.h"
#include "flang/Common/enum-set.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/semantics.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Frontend/OpenACC/ACC.h.inc"
using AccDirectiveSet = Fortran::common::EnumSet<llvm::acc::Directive,
llvm::acc::Directive_enumSize>;
using AccClauseSet =
Fortran::common::EnumSet<llvm::acc::Clause, llvm::acc::Clause_enumSize>;
#define GEN_FLANG_DIRECTIVE_CLAUSE_SETS
#include "llvm/Frontend/OpenACC/ACC.inc"
namespace Fortran::semantics {
class AccStructureChecker
: public DirectiveStructureChecker<llvm::acc::Directive, llvm::acc::Clause,
parser::AccClause, llvm::acc::Clause_enumSize> {
public:
AccStructureChecker(SemanticsContext &context)
: DirectiveStructureChecker(context,
#define GEN_FLANG_DIRECTIVE_CLAUSE_MAP
#include "llvm/Frontend/OpenACC/ACC.inc"
) {
}
void Enter(const parser::OpenACCBlockConstruct &);
void Leave(const parser::OpenACCBlockConstruct &);
void Enter(const parser::OpenACCCombinedConstruct &);
void Leave(const parser::OpenACCCombinedConstruct &);
void Enter(const parser::OpenACCLoopConstruct &);
void Leave(const parser::OpenACCLoopConstruct &);
void Enter(const parser::OpenACCRoutineConstruct &);
void Leave(const parser::OpenACCRoutineConstruct &);
void Enter(const parser::OpenACCStandaloneConstruct &);
void Leave(const parser::OpenACCStandaloneConstruct &);
void Enter(const parser::OpenACCStandaloneDeclarativeConstruct &);
void Leave(const parser::OpenACCStandaloneDeclarativeConstruct &);
void Enter(const parser::OpenACCWaitConstruct &);
void Leave(const parser::OpenACCWaitConstruct &);
void Enter(const parser::OpenACCAtomicConstruct &);
void Leave(const parser::OpenACCAtomicConstruct &);
void Enter(const parser::OpenACCCacheConstruct &);
void Leave(const parser::OpenACCCacheConstruct &);
void Enter(const parser::AccAtomicUpdate &);
void Enter(const parser::OpenACCEndConstruct &);
void Leave(const parser::AccClauseList &);
void Enter(const parser::AccClause &);
void Enter(const parser::Module &);
void Enter(const parser::SubroutineSubprogram &);
void Enter(const parser::FunctionSubprogram &);
void Enter(const parser::SeparateModuleSubprogram &);
void Enter(const parser::DoConstruct &);
void Leave(const parser::DoConstruct &);
#define GEN_FLANG_CLAUSE_CHECK_ENTER
#include "llvm/Frontend/OpenACC/ACC.inc"
private:
bool CheckAllowedModifier(llvm::acc::Clause clause);
bool IsComputeConstruct(llvm::acc::Directive directive) const;
bool IsInsideComputeConstruct() const;
void CheckNotInComputeConstruct();
void CheckMultipleOccurrenceInDeclare(
const parser::AccObjectList &, llvm::acc::Clause);
void CheckMultipleOccurrenceInDeclare(
const parser::AccObjectListWithModifier &, llvm::acc::Clause);
llvm::StringRef getClauseName(llvm::acc::Clause clause) override;
llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override;
llvm::SmallDenseMap<Symbol *, llvm::acc::Clause> declareSymbols;
unsigned loopNestLevel = 0;
};
}
#endif