Skip to content

Commit 5d7d66b

Browse files
committed
[OpenACC] Implement 'declare' construct AST/Sema
The 'declare' construct is the first of two 'declaration' level constructs, so it is legal in any place a declaration is, including as a statement, which this accomplishes by wrapping it in a DeclStmt. All clauses on this have a 'same scope' requirement, which this enforces as declaration context instead, which makes it possible to implement these as a template. The 'link' and 'device_resident' clauses are also added, which have some similar/small restrictions, but are otherwise pretty rote. This patch implements all of the above.
1 parent ccf1bfc commit 5d7d66b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1788
-169
lines changed

clang/include/clang/AST/DeclOpenACC.h

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//=- DeclOpenACC.h - Classes for representing OpenACC directives -*- 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+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// This file defines OpenACC nodes for declarative directives.
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_AST_DECLOPENACC_H
15+
#define LLVM_CLANG_AST_DECLOPENACC_H
16+
17+
#include "clang/AST/ASTContext.h"
18+
#include "clang/AST/Decl.h"
19+
#include "clang/AST/OpenACCClause.h"
20+
#include "clang/Basic/OpenACCKinds.h"
21+
22+
namespace clang {
23+
24+
// A base class for the declaration constructs, which manages the clauses and
25+
// basic source location information. Currently not part of the Decl inheritence
26+
// tree, as we should never have a reason to store one of these.
27+
class OpenACCConstructDecl : public Decl {
28+
friend class ASTDeclReader;
29+
friend class ASTDeclWriter;
30+
// The directive kind, each implementation of this interface is expected to
31+
// handle a specific kind.
32+
OpenACCDirectiveKind DirKind = OpenACCDirectiveKind::Invalid;
33+
SourceLocation DirectiveLoc;
34+
SourceLocation EndLoc;
35+
/// The list of clauses. This is stored here as an ArrayRef, as this is the
36+
/// most convienient place to access the list, however the list itself should
37+
/// be stored in leaf nodes, likely in trailing-storage.
38+
MutableArrayRef<const OpenACCClause *> Clauses;
39+
40+
protected:
41+
OpenACCConstructDecl(Kind DeclKind, DeclContext *DC, OpenACCDirectiveKind K,
42+
SourceLocation StartLoc, SourceLocation DirLoc,
43+
SourceLocation EndLoc)
44+
: Decl(DeclKind, DC, StartLoc), DirKind(K), DirectiveLoc(DirLoc),
45+
EndLoc(EndLoc) {}
46+
47+
OpenACCConstructDecl(Kind DeclKind) : Decl(DeclKind, EmptyShell{}) {}
48+
49+
void setClauseList(MutableArrayRef<const OpenACCClause *> NewClauses) {
50+
assert(Clauses.empty() && "Cannot change clause list");
51+
Clauses = NewClauses;
52+
}
53+
54+
public:
55+
OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }
56+
SourceLocation getDirectiveLoc() const { return DirectiveLoc; }
57+
virtual SourceRange getSourceRange() const override LLVM_READONLY {
58+
return SourceRange(getLocation(), EndLoc);
59+
}
60+
61+
ArrayRef<const OpenACCClause *> clauses() const { return Clauses; }
62+
};
63+
64+
class OpenACCDeclareDecl final
65+
: public OpenACCConstructDecl,
66+
private llvm::TrailingObjects<OpenACCDeclareDecl, const OpenACCClause *> {
67+
friend TrailingObjects;
68+
friend class ASTDeclReader;
69+
friend class ASTDeclWriter;
70+
71+
OpenACCDeclareDecl(unsigned NumClauses)
72+
: OpenACCConstructDecl(OpenACCDeclare) {
73+
std::uninitialized_value_construct(
74+
getTrailingObjects<const OpenACCClause *>(),
75+
getTrailingObjects<const OpenACCClause *>() + NumClauses);
76+
setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
77+
NumClauses));
78+
}
79+
80+
OpenACCDeclareDecl(DeclContext *DC, SourceLocation StartLoc,
81+
SourceLocation DirLoc, SourceLocation EndLoc,
82+
ArrayRef<const OpenACCClause *> Clauses)
83+
: OpenACCConstructDecl(OpenACCDeclare, DC, OpenACCDirectiveKind::Declare,
84+
StartLoc, DirLoc, EndLoc) {
85+
// Initialize the trailing storage.
86+
std::uninitialized_copy(Clauses.begin(), Clauses.end(),
87+
getTrailingObjects<const OpenACCClause *>());
88+
89+
setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
90+
Clauses.size()));
91+
}
92+
93+
public:
94+
static OpenACCDeclareDecl *Create(ASTContext &Ctx, DeclContext *DC,
95+
SourceLocation StartLoc,
96+
SourceLocation DirLoc,
97+
SourceLocation EndLoc,
98+
ArrayRef<const OpenACCClause *> Clauses);
99+
static OpenACCDeclareDecl *
100+
CreateDeserialized(ASTContext &Ctx, GlobalDeclID ID, unsigned NumClauses);
101+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
102+
static bool classofKind(Kind K) { return K == OpenACCDeclare; }
103+
};
104+
} // namespace clang
105+
106+
#endif

clang/include/clang/AST/DeclVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/AST/DeclCXX.h"
1919
#include "clang/AST/DeclFriend.h"
2020
#include "clang/AST/DeclObjC.h"
21+
#include "clang/AST/DeclOpenACC.h"
2122
#include "clang/AST/DeclOpenMP.h"
2223
#include "clang/AST/DeclTemplate.h"
2324
#include "llvm/ADT/STLExtras.h"

clang/include/clang/AST/JSONNodeDumper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ class JSONNodeDumper
281281
void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
282282
void VisitBlockDecl(const BlockDecl *D);
283283

284+
void VisitOpenACCDeclareDecl(const OpenACCDeclareDecl *D);
285+
284286
void VisitDeclRefExpr(const DeclRefExpr *DRE);
285287
void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E);
286288
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *E);

clang/include/clang/AST/OpenACCClause.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,55 @@ class OpenACCReductionClause final
11711171
OpenACCReductionOperator getReductionOp() const { return Op; }
11721172
};
11731173

1174+
class OpenACCLinkClause final
1175+
: public OpenACCClauseWithVarList,
1176+
private llvm::TrailingObjects<OpenACCLinkClause, Expr *> {
1177+
friend TrailingObjects;
1178+
1179+
OpenACCLinkClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1180+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1181+
: OpenACCClauseWithVarList(OpenACCClauseKind::Link, BeginLoc, LParenLoc,
1182+
EndLoc) {
1183+
std::uninitialized_copy(VarList.begin(), VarList.end(),
1184+
getTrailingObjects<Expr *>());
1185+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
1186+
}
1187+
1188+
public:
1189+
static bool classof(const OpenACCClause *C) {
1190+
return C->getClauseKind() == OpenACCClauseKind::Link;
1191+
}
1192+
1193+
static OpenACCLinkClause *Create(const ASTContext &C, SourceLocation BeginLoc,
1194+
SourceLocation LParenLoc,
1195+
ArrayRef<Expr *> VarList,
1196+
SourceLocation EndLoc);
1197+
};
1198+
1199+
class OpenACCDeviceResidentClause final
1200+
: public OpenACCClauseWithVarList,
1201+
private llvm::TrailingObjects<OpenACCDeviceResidentClause, Expr *> {
1202+
friend TrailingObjects;
1203+
1204+
OpenACCDeviceResidentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1205+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1206+
: OpenACCClauseWithVarList(OpenACCClauseKind::DeviceResident, BeginLoc,
1207+
LParenLoc, EndLoc) {
1208+
std::uninitialized_copy(VarList.begin(), VarList.end(),
1209+
getTrailingObjects<Expr *>());
1210+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
1211+
}
1212+
1213+
public:
1214+
static bool classof(const OpenACCClause *C) {
1215+
return C->getClauseKind() == OpenACCClauseKind::DeviceResident;
1216+
}
1217+
1218+
static OpenACCDeviceResidentClause *
1219+
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1220+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1221+
};
1222+
11741223
template <class Impl> class OpenACCClauseVisitor {
11751224
Impl &getDerived() { return static_cast<Impl &>(*this); }
11761225

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "clang/AST/DeclCXX.h"
2121
#include "clang/AST/DeclFriend.h"
2222
#include "clang/AST/DeclObjC.h"
23+
#include "clang/AST/DeclOpenACC.h"
2324
#include "clang/AST/DeclOpenMP.h"
2425
#include "clang/AST/DeclTemplate.h"
2526
#include "clang/AST/DeclarationName.h"
@@ -1821,6 +1822,9 @@ DEF_TRAVERSE_DECL(OMPAllocateDecl, {
18211822
TRY_TO(TraverseOMPClause(C));
18221823
})
18231824

1825+
DEF_TRAVERSE_DECL(OpenACCDeclareDecl,
1826+
{ TRY_TO(VisitOpenACCClauseList(D->clauses())); })
1827+
18241828
// A helper method for TemplateDecl's children.
18251829
template <typename Derived>
18261830
bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(

clang/include/clang/AST/TextNodeDumper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ class TextNodeDumper
423423
void VisitOpenACCUpdateConstruct(const OpenACCUpdateConstruct *S);
424424
void VisitOpenACCAtomicConstruct(const OpenACCAtomicConstruct *S);
425425
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S);
426+
void VisitOpenACCDeclareDecl(const OpenACCDeclareDecl *D);
426427
void VisitEmbedExpr(const EmbedExpr *S);
427428
void VisitAtomicExpr(const AtomicExpr *AE);
428429
void VisitConvertVectorExpr(const ConvertVectorExpr *S);

clang/include/clang/Basic/DeclNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,4 @@ def Empty : DeclNode<Decl>;
111111
def RequiresExprBody : DeclNode<Decl>, DeclContext;
112112
def LifetimeExtendedTemporary : DeclNode<Decl>;
113113
def HLSLBuffer : DeclNode<Named, "HLSLBuffer">, DeclContext;
114+
def OpenACCDeclare : DeclNode<Decl, "#pragma acc declare">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12812,6 +12812,7 @@ def err_acc_duplicate_clause_disallowed
1281212812
"directive">;
1281312813
def note_acc_previous_clause_here : Note<"previous clause is here">;
1281412814
def note_acc_previous_expr_here : Note<"previous expression is here">;
12815+
def note_acc_previous_reference : Note<"previous reference is here">;
1281512816
def err_acc_branch_in_out_compute_construct
1281612817
: Error<"invalid %select{branch|return|throw}0 %select{out of|into}1 "
1281712818
"OpenACC Compute/Combined Construct">;
@@ -12844,9 +12845,9 @@ def err_acc_not_a_var_ref
1284412845
: Error<"OpenACC variable is not a valid variable name, sub-array, array "
1284512846
"element,%select{| member of a composite variable,}0 or composite "
1284612847
"variable member">;
12847-
def err_acc_not_a_var_ref_use_device
12848-
: Error<"OpenACC variable in 'use_device' clause is not a valid variable "
12849-
"name or array name">;
12848+
def err_acc_not_a_var_ref_use_device_declare
12849+
: Error<"OpenACC variable %select{in 'use_device' clause|on 'declare' "
12850+
"construct}0 is not a valid variable name or array name">;
1285012851
def err_acc_typecheck_subarray_value
1285112852
: Error<"OpenACC sub-array subscripted value is not an array or pointer">;
1285212853
def err_acc_subarray_function_type
@@ -13014,6 +13015,23 @@ def note_acc_atomic_mismatch_compound_operand
1301413015
"side of assignment|<not possible>|on left hand side of compound "
1301513016
"assignment|on left hand side of assignment}0('%1') from the first "
1301613017
"statement">;
13018+
def err_acc_declare_required_clauses
13019+
: Error<"no valid clauses specified in OpenACC 'declare' directive">;
13020+
def err_acc_declare_clause_at_global
13021+
: Error<"OpenACC '%0' clause on a 'declare' directive is not allowed at "
13022+
"global or namespace scope">;
13023+
def err_acc_link_not_extern
13024+
: Error<"variable referenced by 'link' clause not in global or namespace "
13025+
"scope must be marked 'extern'">;
13026+
def err_acc_declare_extern
13027+
: Error<"'extern' variable may not be referenced by '%0' clause on an "
13028+
"OpenACC 'declare' directive">;
13029+
def err_acc_declare_same_scope
13030+
: Error<"variable appearing in '%0' clause of OpenACC 'declare' directive "
13031+
"must be in the same scope as the directive">;
13032+
def err_acc_multiple_references
13033+
: Error<"variable referenced in '%0' clause of OpenACC 'declare' directive "
13034+
"was already referenced">;
1301713035

1301813036
// AMDGCN builtins diagnostics
1301913037
def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ VISIT_CLAUSE(Detach)
4444
VISIT_CLAUSE(Device)
4545
VISIT_CLAUSE(DeviceNum)
4646
VISIT_CLAUSE(DevicePtr)
47+
VISIT_CLAUSE(DeviceResident)
4748
VISIT_CLAUSE(DeviceType)
4849
CLAUSE_ALIAS(DType, DeviceType, false)
4950
VISIT_CLAUSE(Finalize)
@@ -53,6 +54,7 @@ VISIT_CLAUSE(Host)
5354
VISIT_CLAUSE(If)
5455
VISIT_CLAUSE(IfPresent)
5556
VISIT_CLAUSE(Independent)
57+
VISIT_CLAUSE(Link)
5658
VISIT_CLAUSE(NoCreate)
5759
VISIT_CLAUSE(NumGangs)
5860
VISIT_CLAUSE(NumWorkers)

clang/include/clang/Parse/Parser.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3756,9 +3756,11 @@ class Parser : public CodeCompletionHandler {
37563756

37573757
using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
37583758
/// Parses a single variable in a variable list for OpenACC.
3759-
OpenACCVarParseResult ParseOpenACCVar(OpenACCClauseKind CK);
3759+
OpenACCVarParseResult ParseOpenACCVar(OpenACCDirectiveKind DK,
3760+
OpenACCClauseKind CK);
37603761
/// Parses the variable list for the variety of places that take a var-list.
3761-
llvm::SmallVector<Expr *> ParseOpenACCVarList(OpenACCClauseKind CK);
3762+
llvm::SmallVector<Expr *> ParseOpenACCVarList(OpenACCDirectiveKind DK,
3763+
OpenACCClauseKind CK);
37623764
/// Parses any parameters for an OpenACC Clause, including required/optional
37633765
/// parens.
37643766
OpenACCClauseParseResult

clang/include/clang/Sema/SemaBase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class SemaBase {
4242
ASTContext &getASTContext() const;
4343
DiagnosticsEngine &getDiagnostics() const;
4444
const LangOptions &getLangOpts() const;
45+
DeclContext *getCurContext() const;
4546

4647
/// Helper class that creates diagnostics with optional
4748
/// template instantiation stacks.

0 commit comments

Comments
 (0)