blob: 54c7366b1d769777bd1b761fcf0b5b45142194cf [file] [edit]
//===--- CIRGenOpenMPClause.h - OpenMP clause emitter -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENOPENMPCLAUSE_H
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENOPENMPCLAUSE_H
#include "CIRGenBuilder.h"
#include "CIRGenModule.h"
#include "mlir/Dialect/OpenMP/OpenMPClauseOperands.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/StmtOpenMP.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include <type_traits>
namespace clang::CIRGen {
class CIRGenFunction;
/// A type-only list of OpenMP clause AST node types.
template <typename... Clauses> struct OpenMPNYIClauseList {};
/// Emits OpenMP clauses for a directive, writing results into the
/// auto-generated ClauseOps from the OMP dialect.
class OpenMPClauseEmitter {
CIRGenFunction &cgf;
CIRGenModule &cgm;
CIRGenBuilderTy &builder;
mlir::Location loc;
llvm::ArrayRef<const OMPClause *> clauses;
public:
OpenMPClauseEmitter(CIRGenFunction &cgf, CIRGenModule &cgm,
CIRGenBuilderTy &builder, mlir::Location loc,
llvm::ArrayRef<const OMPClause *> clauses)
: cgf(cgf), cgm(cgm), builder(builder), loc(loc), clauses(clauses) {}
bool emitProcBind(mlir::omp::ProcBindClauseOps &result) const;
/// Emit map clauses. The optional \p mapSyms parameter collects the
/// VarDecls corresponding to each map operand.
bool emitMap(mlir::omp::MapClauseOps &result,
llvm::SmallVectorImpl<const VarDecl *> *mapSyms = nullptr) const;
/// Verify the clauses of a directive to make sure all legal cases are either
/// implemented or give a NYI error. The \p SupportedClauses and \p
/// NYIClauses type lists must be disjoint and cover all clauses eligible for
/// the directive being processed.
template <typename... SupportedClauses, typename... NYIClauses>
void emitNYI(OpenMPNYIClauseList<NYIClauses...> nyi,
llvm::omp::Directive directive) const;
private:
/// True if T is the same type as any of Ts.
template <typename T, typename... Ts>
static constexpr bool isAnyOf = (std::is_same_v<T, Ts> || ...);
};
template <typename... SupportedClauses, typename... NYIClauses>
void OpenMPClauseEmitter::emitNYI(OpenMPNYIClauseList<NYIClauses...>,
llvm::omp::Directive directive) const {
static_assert(
(!isAnyOf<NYIClauses, SupportedClauses...> && ...),
"the supported and not-yet-implemented clause lists must be disjoint");
for (const OMPClause *c : clauses) {
if (isa<NYIClauses...>(c)) {
std::string msg =
(llvm::Twine("OpenMP ") +
llvm::omp::getOpenMPDirectiveName(directive).upper() + " '" +
llvm::omp::getOpenMPClauseName(c->getClauseKind()) + "' clause")
.str();
cgm.errorNYI(c->getBeginLoc(), msg);
} else if (!isa<SupportedClauses...>(c)) {
// Unknown/illegal clause encountered.
llvm_unreachable("unexpected OpenMP clause");
}
}
}
} // namespace clang::CIRGen
#endif // LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENOPENMPCLAUSE_H