clang 19.0.0git
SemaOpenACC.cpp
Go to the documentation of this file.
1//===--- SemaOpenACC.cpp - Semantic Analysis for OpenACC constructs -------===//
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/// \file
9/// This file implements semantic analysis for OpenACC constructs and
10/// clauses.
11///
12//===----------------------------------------------------------------------===//
13
17#include "clang/Sema/Sema.h"
18
19using namespace clang;
20
21namespace {
22bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K,
23 SourceLocation StartLoc, bool IsStmt) {
24 switch (K) {
25 default:
26 case OpenACCDirectiveKind::Invalid:
27 // Nothing to do here, both invalid and unimplemented don't really need to
28 // do anything.
29 break;
30 case OpenACCDirectiveKind::Parallel:
31 case OpenACCDirectiveKind::Serial:
32 case OpenACCDirectiveKind::Kernels:
33 if (!IsStmt)
34 return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
35 break;
36 }
37 return false;
38}
39
40bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
41 OpenACCClauseKind ClauseKind) {
42 switch (ClauseKind) {
43 // FIXME: For each clause as we implement them, we can add the
44 // 'legalization' list here.
45 case OpenACCClauseKind::Default:
46 switch (DirectiveKind) {
47 case OpenACCDirectiveKind::Parallel:
48 case OpenACCDirectiveKind::Serial:
49 case OpenACCDirectiveKind::Kernels:
50 case OpenACCDirectiveKind::ParallelLoop:
51 case OpenACCDirectiveKind::SerialLoop:
52 case OpenACCDirectiveKind::KernelsLoop:
53 case OpenACCDirectiveKind::Data:
54 return true;
55 default:
56 return false;
57 }
58 default:
59 // Do nothing so we can go to the 'unimplemented' diagnostic instead.
60 return true;
61 }
62 llvm_unreachable("Invalid clause kind");
63}
64} // namespace
65
67
70 OpenACCParsedClause &Clause) {
72 return nullptr;
73
74 // Diagnose that we don't support this clause on this directive.
75 if (!doesClauseApplyToDirective(Clause.getDirectiveKind(),
76 Clause.getClauseKind())) {
77 Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)
78 << Clause.getDirectiveKind() << Clause.getClauseKind();
79 return nullptr;
80 }
81
82 switch (Clause.getClauseKind()) {
84 // Restrictions only properly implemented on 'compute' constructs, and
85 // 'compute' constructs are the only construct that can do anything with
86 // this yet, so skip/treat as unimplemented in this case.
90 break;
91
92 // Don't add an invalid clause to the AST.
94 return nullptr;
95
96 // OpenACC 3.3, Section 2.5.4:
97 // At most one 'default' clause may appear, and it must have a value of
98 // either 'none' or 'present'.
99 // Second half of the sentence is diagnosed during parsing.
100 auto Itr = llvm::find_if(ExistingClauses, [](const OpenACCClause *C) {
101 return C->getClauseKind() == OpenACCClauseKind::Default;
102 });
103
104 if (Itr != ExistingClauses.end()) {
105 Diag(Clause.getBeginLoc(),
106 diag::err_acc_duplicate_clause_disallowed)
107 << Clause.getDirectiveKind() << Clause.getClauseKind();
108 Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
109 return nullptr;
110 }
111
113 getASTContext(), Clause.getDefaultClauseKind(), Clause.getBeginLoc(),
114 Clause.getLParenLoc(), Clause.getEndLoc());
115 }
116 default:
117 break;
118 }
119
120 Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)
121 << Clause.getClauseKind();
122 return nullptr;
123}
124
126 SourceLocation StartLoc) {
127 switch (K) {
129 // Nothing to do here, an invalid kind has nothing we can check here. We
130 // want to continue parsing clauses as far as we can, so we will just
131 // ensure that we can still work and don't check any construct-specific
132 // rules anywhere.
133 break;
137 // Nothing to do here, there is no real legalization that needs to happen
138 // here as these constructs do not take any arguments.
139 break;
140 default:
141 Diag(StartLoc, diag::warn_acc_construct_unimplemented) << K;
142 break;
143 }
144}
145
147 SourceLocation StartLoc) {
148 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
149}
150
152 SourceLocation StartLoc,
153 SourceLocation EndLoc,
155 StmtResult AssocStmt) {
156 switch (K) {
157 default:
158 return StmtEmpty();
160 return StmtError();
164 // TODO OpenACC: Add clauses to the construct here.
166 getASTContext(), K, StartLoc, EndLoc, Clauses,
167 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
168 }
169 llvm_unreachable("Unhandled case in directive handling?");
170}
171
173 StmtResult AssocStmt) {
174 switch (K) {
175 default:
176 llvm_unreachable("Unimplemented associated statement application");
180 // There really isn't any checking here that could happen. As long as we
181 // have a statement to associate, this should be fine.
182 // OpenACC 3.3 Section 6:
183 // Structured Block: in C or C++, an executable statement, possibly
184 // compound, with a single entry at the top and a single exit at the
185 // bottom.
186 // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and
187 // an interpretation of it is to allow this and treat the initializer as
188 // the 'structured block'.
189 return AssocStmt;
190 }
191 llvm_unreachable("Invalid associated statement application");
192}
193
195 SourceLocation StartLoc) {
196 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
197}
198
This file declares semantic analysis for OpenACC constructs and clauses.
This file defines OpenACC AST classes for statement-level contructs.
PtrTy get() const
Definition: Ownership.h:170
bool isUsable() const
Definition: Ownership.h:168
This is the base type for all OpenACC Clauses.
Definition: OpenACCClause.h:21
static OpenACCComputeConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
Definition: StmtOpenACC.cpp:27
static OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:55
ASTContext & getASTContext() const
Definition: SemaBase.cpp:8
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
Definition: SemaOpenACC.h:33
OpenACCDirectiveKind getDirectiveKind() const
Definition: SemaOpenACC.h:50
SourceLocation getEndLoc() const
Definition: SemaOpenACC.h:58
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:52
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:56
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:54
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:60
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
OpenACCClause * ActOnClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCParsedClause &Clause)
Called after parsing an OpenACC Clause so that it can be checked.
Definition: SemaOpenACC.cpp:69
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
DeclGroupRef ActOnEndDeclDirective()
Called after the directive has been completely parsed, including the declaration group or associated ...
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:428
Encodes a location in the source.
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
Definition: OpenACCKinds.h:158
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Default
'default' clause, allowed on parallel, serial, kernel (and compound) constructs.
StmtResult StmtError()
Definition: Ownership.h:265
@ Invalid
Not a valid option.
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25
StmtResult StmtEmpty()
Definition: Ownership.h:272