156 lines
6.2 KiB
C++
156 lines
6.2 KiB
C++
//=- DeclOpenACC.h - Classes for representing OpenACC directives -*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This file defines OpenACC nodes for declarative directives.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_AST_DECLOPENACC_H
|
|
#define LLVM_CLANG_AST_DECLOPENACC_H
|
|
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/AST/Decl.h"
|
|
#include "clang/AST/OpenACCClause.h"
|
|
#include "clang/Basic/OpenACCKinds.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
namespace clang {
|
|
|
|
// A base class for the declaration constructs, which manages the clauses and
|
|
// basic source location information. Currently not part of the Decl inheritence
|
|
// tree, as we should never have a reason to store one of these.
|
|
class OpenACCConstructDecl : public Decl {
|
|
friend class ASTDeclReader;
|
|
friend class ASTDeclWriter;
|
|
// The directive kind, each implementation of this interface is expected to
|
|
// handle a specific kind.
|
|
OpenACCDirectiveKind DirKind = OpenACCDirectiveKind::Invalid;
|
|
SourceLocation DirectiveLoc;
|
|
SourceLocation EndLoc;
|
|
/// The list of clauses. This is stored here as an ArrayRef, as this is the
|
|
/// most convienient place to access the list, however the list itself should
|
|
/// be stored in leaf nodes, likely in trailing-storage.
|
|
MutableArrayRef<const OpenACCClause *> Clauses;
|
|
|
|
protected:
|
|
OpenACCConstructDecl(Kind DeclKind, DeclContext *DC, OpenACCDirectiveKind K,
|
|
SourceLocation StartLoc, SourceLocation DirLoc,
|
|
SourceLocation EndLoc)
|
|
: Decl(DeclKind, DC, StartLoc), DirKind(K), DirectiveLoc(DirLoc),
|
|
EndLoc(EndLoc) {}
|
|
|
|
OpenACCConstructDecl(Kind DeclKind) : Decl(DeclKind, EmptyShell{}) {}
|
|
|
|
void setClauseList(MutableArrayRef<const OpenACCClause *> NewClauses) {
|
|
assert(Clauses.empty() && "Cannot change clause list");
|
|
Clauses = NewClauses;
|
|
}
|
|
|
|
public:
|
|
OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }
|
|
SourceLocation getDirectiveLoc() const { return DirectiveLoc; }
|
|
virtual SourceRange getSourceRange() const override LLVM_READONLY {
|
|
return SourceRange(getLocation(), EndLoc);
|
|
}
|
|
|
|
ArrayRef<const OpenACCClause *> clauses() const { return Clauses; }
|
|
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
|
static bool classofKind(Kind K);
|
|
};
|
|
|
|
class OpenACCDeclareDecl final
|
|
: public OpenACCConstructDecl,
|
|
private llvm::TrailingObjects<OpenACCDeclareDecl, const OpenACCClause *> {
|
|
friend TrailingObjects;
|
|
friend class ASTDeclReader;
|
|
friend class ASTDeclWriter;
|
|
|
|
OpenACCDeclareDecl(unsigned NumClauses)
|
|
: OpenACCConstructDecl(OpenACCDeclare) {
|
|
std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
|
|
setClauseList(getTrailingObjects(NumClauses));
|
|
}
|
|
|
|
OpenACCDeclareDecl(DeclContext *DC, SourceLocation StartLoc,
|
|
SourceLocation DirLoc, SourceLocation EndLoc,
|
|
ArrayRef<const OpenACCClause *> Clauses)
|
|
: OpenACCConstructDecl(OpenACCDeclare, DC, OpenACCDirectiveKind::Declare,
|
|
StartLoc, DirLoc, EndLoc) {
|
|
// Initialize the trailing storage.
|
|
llvm::uninitialized_copy(Clauses, getTrailingObjects());
|
|
|
|
setClauseList(getTrailingObjects(Clauses.size()));
|
|
}
|
|
|
|
public:
|
|
static OpenACCDeclareDecl *Create(ASTContext &Ctx, DeclContext *DC,
|
|
SourceLocation StartLoc,
|
|
SourceLocation DirLoc,
|
|
SourceLocation EndLoc,
|
|
ArrayRef<const OpenACCClause *> Clauses);
|
|
static OpenACCDeclareDecl *
|
|
CreateDeserialized(ASTContext &Ctx, GlobalDeclID ID, unsigned NumClauses);
|
|
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
|
static bool classofKind(Kind K) { return K == OpenACCDeclare; }
|
|
};
|
|
|
|
// Reprents a 'routine' directive with a name. When this has no name, it is
|
|
// represented as an attribute.
|
|
class OpenACCRoutineDecl final
|
|
: public OpenACCConstructDecl,
|
|
private llvm::TrailingObjects<OpenACCRoutineDecl, const OpenACCClause *> {
|
|
friend TrailingObjects;
|
|
friend class ASTDeclReader;
|
|
friend class ASTDeclWriter;
|
|
|
|
Expr *FuncRef = nullptr;
|
|
SourceRange ParensLoc;
|
|
|
|
OpenACCRoutineDecl(unsigned NumClauses)
|
|
: OpenACCConstructDecl(OpenACCRoutine) {
|
|
std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
|
|
setClauseList(getTrailingObjects(NumClauses));
|
|
}
|
|
|
|
OpenACCRoutineDecl(DeclContext *DC, SourceLocation StartLoc,
|
|
SourceLocation DirLoc, SourceLocation LParenLoc,
|
|
Expr *FuncRef, SourceLocation RParenLoc,
|
|
SourceLocation EndLoc,
|
|
ArrayRef<const OpenACCClause *> Clauses)
|
|
: OpenACCConstructDecl(OpenACCRoutine, DC, OpenACCDirectiveKind::Routine,
|
|
StartLoc, DirLoc, EndLoc),
|
|
FuncRef(FuncRef), ParensLoc(LParenLoc, RParenLoc) {
|
|
assert(LParenLoc.isValid() &&
|
|
"Cannot represent implicit name with this declaration");
|
|
// Initialize the trailing storage.
|
|
llvm::uninitialized_copy(Clauses, getTrailingObjects());
|
|
setClauseList(getTrailingObjects(Clauses.size()));
|
|
}
|
|
|
|
public:
|
|
static OpenACCRoutineDecl *
|
|
Create(ASTContext &Ctx, DeclContext *DC, SourceLocation StartLoc,
|
|
SourceLocation DirLoc, SourceLocation LParenLoc, Expr *FuncRef,
|
|
SourceLocation RParenLoc, SourceLocation EndLoc,
|
|
ArrayRef<const OpenACCClause *> Clauses);
|
|
static OpenACCRoutineDecl *
|
|
CreateDeserialized(ASTContext &Ctx, GlobalDeclID ID, unsigned NumClauses);
|
|
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
|
static bool classofKind(Kind K) { return K == OpenACCRoutine; }
|
|
|
|
const Expr *getFunctionReference() const { return FuncRef; }
|
|
Expr *getFunctionReference() { return FuncRef; }
|
|
|
|
SourceLocation getLParenLoc() const { return ParensLoc.getBegin(); }
|
|
SourceLocation getRParenLoc() const { return ParensLoc.getEnd(); }
|
|
};
|
|
} // namespace clang
|
|
|
|
#endif
|