Skip to content

Commit d5cec38

Browse files
committed
[OpenACC] Implement 'cache' construct AST/Sema
This statement level construct takes no clauses and has no associated statement, and simply labels a number of array elements as valid for caching. The implementation here is pretty simple, but it is a touch of a special case for parsing, so the parsing code reflects that.
1 parent d6599fc commit d5cec38

29 files changed

+561
-119
lines changed

clang/include/clang-c/Index.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2214,7 +2214,11 @@ enum CXCursorKind {
22142214
*/
22152215
CXCursor_OpenACCAtomicConstruct = 332,
22162216

2217-
CXCursor_LastStmt = CXCursor_OpenACCAtomicConstruct,
2217+
/** OpenACC cache Construct.
2218+
*/
2219+
CXCursor_OpenACCCacheConstruct = 333,
2220+
2221+
CXCursor_LastStmt = CXCursor_OpenACCCacheConstruct,
22182222

22192223
/**
22202224
* Cursor that represents the translation unit itself.

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4113,6 +4113,10 @@ DEF_TRAVERSE_STMT(OpenACCUpdateConstruct,
41134113
{ TRY_TO(VisitOpenACCClauseList(S->clauses())); })
41144114
DEF_TRAVERSE_STMT(OpenACCAtomicConstruct,
41154115
{ TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4116+
DEF_TRAVERSE_STMT(OpenACCCacheConstruct, {
4117+
for (auto *E : S->getVarList())
4118+
TRY_TO(TraverseStmt(E));
4119+
})
41164120

41174121
// Traverse HLSL: Out argument expression
41184122
DEF_TRAVERSE_STMT(HLSLOutArgExpr, {})

clang/include/clang/AST/StmtOpenACC.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,81 @@ class OpenACCWaitConstruct final
593593
}
594594
};
595595

596+
class OpenACCCacheConstruct final
597+
: public OpenACCConstructStmt,
598+
private llvm::TrailingObjects<OpenACCCacheConstruct, Expr *> {
599+
friend TrailingObjects;
600+
friend class ASTStmtWriter;
601+
friend class ASTStmtReader;
602+
// Locations of the left and right parens of the 'var-list'
603+
// expression-list.
604+
SourceRange ParensLoc;
605+
SourceLocation ReadOnlyLoc;
606+
607+
unsigned NumVars = 0;
608+
609+
OpenACCCacheConstruct(unsigned NumVars)
610+
: OpenACCConstructStmt(OpenACCCacheConstructClass,
611+
OpenACCDirectiveKind::Cache, SourceLocation{},
612+
SourceLocation{}, SourceLocation{}),
613+
NumVars(NumVars) {
614+
std::uninitialized_value_construct(getVarListPtr(),
615+
getVarListPtr() + NumVars);
616+
}
617+
OpenACCCacheConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
618+
SourceLocation LParenLoc, SourceLocation ReadOnlyLoc,
619+
ArrayRef<Expr *> VarList, SourceLocation RParenLoc,
620+
SourceLocation End)
621+
: OpenACCConstructStmt(OpenACCCacheConstructClass,
622+
OpenACCDirectiveKind::Cache, Start, DirectiveLoc,
623+
End),
624+
ParensLoc(LParenLoc, RParenLoc), ReadOnlyLoc(ReadOnlyLoc),
625+
NumVars(VarList.size()) {
626+
627+
std::uninitialized_copy(VarList.begin(), VarList.end(), getVarListPtr());
628+
}
629+
630+
Expr **getVarListPtr() const {
631+
return const_cast<Expr **>(getTrailingObjects<Expr *>());
632+
}
633+
634+
public:
635+
llvm::ArrayRef<Expr *> getVarList() const {
636+
return llvm::ArrayRef<Expr *>(getVarListPtr(), NumVars);
637+
}
638+
639+
llvm::ArrayRef<Expr *> getVarList() {
640+
return llvm::ArrayRef<Expr *>(getVarListPtr(), NumVars);
641+
}
642+
643+
static bool classof(const Stmt *T) {
644+
return T->getStmtClass() == OpenACCCacheConstructClass;
645+
}
646+
647+
static OpenACCCacheConstruct *CreateEmpty(const ASTContext &C,
648+
unsigned NumVars);
649+
static OpenACCCacheConstruct *
650+
Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
651+
SourceLocation LParenLoc, SourceLocation ReadOnlyLoc,
652+
ArrayRef<Expr *> VarList, SourceLocation RParenLoc,
653+
SourceLocation End);
654+
655+
SourceLocation getLParenLoc() const { return ParensLoc.getBegin(); }
656+
SourceLocation getRParenLoc() const { return ParensLoc.getEnd(); }
657+
bool hasReadOnly() const { return !ReadOnlyLoc.isInvalid(); }
658+
SourceLocation getReadOnlyLoc() const { return ReadOnlyLoc; }
659+
660+
child_range children() {
661+
Stmt **Begin = reinterpret_cast<Stmt **>(getVarListPtr());
662+
return child_range(Begin, Begin + NumVars);
663+
}
664+
665+
const_child_range children() const {
666+
Stmt *const *Begin = reinterpret_cast<Stmt *const *>(getVarListPtr());
667+
return const_child_range(Begin, Begin + NumVars);
668+
}
669+
};
670+
596671
// This class represents an 'init' construct, which has just a clause list.
597672
class OpenACCInitConstruct final
598673
: public OpenACCConstructStmt,

clang/include/clang/AST/TextNodeDumper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ class TextNodeDumper
422422
void VisitOpenACCShutdownConstruct(const OpenACCShutdownConstruct *S);
423423
void VisitOpenACCUpdateConstruct(const OpenACCUpdateConstruct *S);
424424
void VisitOpenACCAtomicConstruct(const OpenACCAtomicConstruct *S);
425+
void VisitOpenACCCacheConstruct(const OpenACCCacheConstruct *S);
425426
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S);
426427
void VisitOpenACCDeclareDecl(const OpenACCDeclareDecl *D);
427428
void VisitEmbedExpr(const EmbedExpr *S);

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12848,6 +12848,9 @@ def err_acc_not_a_var_ref
1284812848
def err_acc_not_a_var_ref_use_device_declare
1284912849
: Error<"OpenACC variable %select{in 'use_device' clause|on 'declare' "
1285012850
"construct}0 is not a valid variable name or array name">;
12851+
def err_acc_not_a_var_ref_cache
12852+
: Error<"OpenACC variable in cache directive is not a valid sub-array or "
12853+
"array element">;
1285112854
def err_acc_typecheck_subarray_value
1285212855
: Error<"OpenACC sub-array subscripted value is not an array or pointer">;
1285312856
def err_acc_subarray_function_type

clang/include/clang/Basic/StmtNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ def OpenACCShutdownConstruct : StmtNode<OpenACCConstructStmt>;
320320
def OpenACCSetConstruct : StmtNode<OpenACCConstructStmt>;
321321
def OpenACCUpdateConstruct : StmtNode<OpenACCConstructStmt>;
322322
def OpenACCAtomicConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
323+
def OpenACCCacheConstruct : StmtNode<OpenACCConstructStmt>;
323324

324325
// OpenACC Additional Expressions.
325326
def OpenACCAsteriskSizeExpr : StmtNode<Expr>;

clang/include/clang/Parse/Parser.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3730,6 +3730,11 @@ class Parser : public CodeCompletionHandler {
37303730
return Out;
37313731
}
37323732
};
3733+
struct OpenACCCacheParseInfo {
3734+
bool Failed = false;
3735+
SourceLocation ReadOnlyLoc;
3736+
SmallVector<Expr *> Vars;
3737+
};
37333738

37343739
/// Represents the 'error' state of parsing an OpenACC Clause, and stores
37353740
/// whether we can continue parsing, or should give up on the directive.
@@ -3752,7 +3757,7 @@ class Parser : public CodeCompletionHandler {
37523757
/// Helper that parses an ID Expression based on the language options.
37533758
ExprResult ParseOpenACCIDExpression();
37543759
/// Parses the variable list for the `cache` construct.
3755-
void ParseOpenACCCacheVarList();
3760+
OpenACCCacheParseInfo ParseOpenACCCacheVarList();
37563761

37573762
using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
37583763
/// Parses a single variable in a variable list for OpenACC.

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,8 @@ class SemaOpenACC : public SemaBase {
762762
/// declaration reference to a variable of the correct type.
763763
ExprResult ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
764764
Expr *VarExpr);
765+
/// Helper function called by ActonVar that is used to check a 'cache' var.
766+
ExprResult ActOnCacheVar(Expr *VarExpr);
765767

766768
// Called after 'ActOnVar' specifically for a 'link' clause, which has to do
767769
// some minor additional checks.

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,6 +2049,7 @@ enum StmtCode {
20492049
STMT_OPENACC_SET_CONSTRUCT,
20502050
STMT_OPENACC_UPDATE_CONSTRUCT,
20512051
STMT_OPENACC_ATOMIC_CONSTRUCT,
2052+
STMT_OPENACC_CACHE_CONSTRUCT,
20522053

20532054
// HLSL Constructs
20542055
EXPR_HLSL_OUT_ARG,

clang/lib/AST/StmtOpenACC.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,21 @@ OpenACCAtomicConstruct *OpenACCAtomicConstruct::Create(
321321
OpenACCAtomicConstruct(Start, DirectiveLoc, AtKind, End, AssociatedStmt);
322322
return Inst;
323323
}
324+
OpenACCCacheConstruct *OpenACCCacheConstruct::CreateEmpty(const ASTContext &C,
325+
unsigned NumVars) {
326+
void *Mem =
327+
C.Allocate(OpenACCCacheConstruct::totalSizeToAlloc<Expr *>(NumVars));
328+
auto *Inst = new (Mem) OpenACCCacheConstruct(NumVars);
329+
return Inst;
330+
}
331+
332+
OpenACCCacheConstruct *OpenACCCacheConstruct::Create(
333+
const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
334+
SourceLocation LParenLoc, SourceLocation ReadOnlyLoc,
335+
ArrayRef<Expr *> VarList, SourceLocation RParenLoc, SourceLocation End) {
336+
void *Mem = C.Allocate(
337+
OpenACCCacheConstruct::totalSizeToAlloc<Expr *>(VarList.size()));
338+
auto *Inst = new (Mem) OpenACCCacheConstruct(
339+
Start, DirectiveLoc, LParenLoc, ReadOnlyLoc, VarList, RParenLoc, End);
340+
return Inst;
341+
}

0 commit comments

Comments
 (0)