Bug Summary

File:clang/lib/Parse/ParseOpenMP.cpp
Warning:line 2189, column 7
Value stored to 'HasImplicitClause' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ParseOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/lib/Parse -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/lib/Parse -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp
1//===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
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 parsing of all OpenMP directives and clauses.
10///
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/StmtOpenMP.h"
15#include "clang/Basic/OpenMPKinds.h"
16#include "clang/Parse/ParseDiagnostic.h"
17#include "clang/Parse/Parser.h"
18#include "clang/Parse/RAIIObjectsForParser.h"
19#include "clang/Sema/Scope.h"
20#include "llvm/ADT/PointerIntPair.h"
21#include "llvm/ADT/UniqueVector.h"
22#include "llvm/Frontend/OpenMP/OMPContext.h"
23
24using namespace clang;
25using namespace llvm::omp;
26
27//===----------------------------------------------------------------------===//
28// OpenMP declarative directives.
29//===----------------------------------------------------------------------===//
30
31namespace {
32enum OpenMPDirectiveKindEx {
33 OMPD_cancellation = unsigned(OMPD_unknown) + 1,
34 OMPD_data,
35 OMPD_declare,
36 OMPD_end,
37 OMPD_end_declare,
38 OMPD_enter,
39 OMPD_exit,
40 OMPD_point,
41 OMPD_reduction,
42 OMPD_target_enter,
43 OMPD_target_exit,
44 OMPD_update,
45 OMPD_distribute_parallel,
46 OMPD_teams_distribute_parallel,
47 OMPD_target_teams_distribute_parallel,
48 OMPD_mapper,
49 OMPD_variant,
50};
51
52// Helper to unify the enum class OpenMPDirectiveKind with its extension
53// the OpenMPDirectiveKindEx enum which allows to use them together as if they
54// are unsigned values.
55struct OpenMPDirectiveKindExWrapper {
56 OpenMPDirectiveKindExWrapper(unsigned Value) : Value(Value) {}
57 OpenMPDirectiveKindExWrapper(OpenMPDirectiveKind DK) : Value(unsigned(DK)) {}
58 bool operator==(OpenMPDirectiveKind V) const { return Value == unsigned(V); }
59 bool operator!=(OpenMPDirectiveKind V) const { return Value != unsigned(V); }
60 bool operator<(OpenMPDirectiveKind V) const { return Value < unsigned(V); }
61 operator unsigned() const { return Value; }
62 operator OpenMPDirectiveKind() const { return OpenMPDirectiveKind(Value); }
63 unsigned Value;
64};
65
66class DeclDirectiveListParserHelper final {
67 SmallVector<Expr *, 4> Identifiers;
68 Parser *P;
69 OpenMPDirectiveKind Kind;
70
71public:
72 DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
73 : P(P), Kind(Kind) {}
74 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
75 ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
76 P->getCurScope(), SS, NameInfo, Kind);
77 if (Res.isUsable())
78 Identifiers.push_back(Res.get());
79 }
80 llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
81};
82} // namespace
83
84// Map token string to extended OMP token kind that are
85// OpenMPDirectiveKind + OpenMPDirectiveKindEx.
86static unsigned getOpenMPDirectiveKindEx(StringRef S) {
87 OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
88 if (DKind != OMPD_unknown)
89 return DKind;
90
91 return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
92 .Case("cancellation", OMPD_cancellation)
93 .Case("data", OMPD_data)
94 .Case("declare", OMPD_declare)
95 .Case("end", OMPD_end)
96 .Case("enter", OMPD_enter)
97 .Case("exit", OMPD_exit)
98 .Case("point", OMPD_point)
99 .Case("reduction", OMPD_reduction)
100 .Case("update", OMPD_update)
101 .Case("mapper", OMPD_mapper)
102 .Case("variant", OMPD_variant)
103 .Default(OMPD_unknown);
104}
105
106static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
107 // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
108 // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
109 // TODO: add other combined directives in topological order.
110 static const OpenMPDirectiveKindExWrapper F[][3] = {
111 {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
112 {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
113 {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
114 {OMPD_declare, OMPD_simd, OMPD_declare_simd},
115 {OMPD_declare, OMPD_target, OMPD_declare_target},
116 {OMPD_declare, OMPD_variant, OMPD_declare_variant},
117 {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
118 {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
119 {OMPD_distribute_parallel_for, OMPD_simd,
120 OMPD_distribute_parallel_for_simd},
121 {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
122 {OMPD_end, OMPD_declare, OMPD_end_declare},
123 {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
124 {OMPD_target, OMPD_data, OMPD_target_data},
125 {OMPD_target, OMPD_enter, OMPD_target_enter},
126 {OMPD_target, OMPD_exit, OMPD_target_exit},
127 {OMPD_target, OMPD_update, OMPD_target_update},
128 {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
129 {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
130 {OMPD_for, OMPD_simd, OMPD_for_simd},
131 {OMPD_parallel, OMPD_for, OMPD_parallel_for},
132 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
133 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
134 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
135 {OMPD_target, OMPD_parallel, OMPD_target_parallel},
136 {OMPD_target, OMPD_simd, OMPD_target_simd},
137 {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
138 {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
139 {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
140 {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
141 {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
142 {OMPD_teams_distribute_parallel, OMPD_for,
143 OMPD_teams_distribute_parallel_for},
144 {OMPD_teams_distribute_parallel_for, OMPD_simd,
145 OMPD_teams_distribute_parallel_for_simd},
146 {OMPD_target, OMPD_teams, OMPD_target_teams},
147 {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
148 {OMPD_target_teams_distribute, OMPD_parallel,
149 OMPD_target_teams_distribute_parallel},
150 {OMPD_target_teams_distribute, OMPD_simd,
151 OMPD_target_teams_distribute_simd},
152 {OMPD_target_teams_distribute_parallel, OMPD_for,
153 OMPD_target_teams_distribute_parallel_for},
154 {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
155 OMPD_target_teams_distribute_parallel_for_simd},
156 {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
157 {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
158 {OMPD_parallel, OMPD_master, OMPD_parallel_master},
159 {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
160 {OMPD_parallel_master_taskloop, OMPD_simd,
161 OMPD_parallel_master_taskloop_simd}};
162 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
163 Token Tok = P.getCurToken();
164 OpenMPDirectiveKindExWrapper DKind =
165 Tok.isAnnotation()
166 ? static_cast<unsigned>(OMPD_unknown)
167 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
168 if (DKind == OMPD_unknown)
169 return OMPD_unknown;
170
171 for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
172 if (DKind != F[I][0])
173 continue;
174
175 Tok = P.getPreprocessor().LookAhead(0);
176 OpenMPDirectiveKindExWrapper SDKind =
177 Tok.isAnnotation()
178 ? static_cast<unsigned>(OMPD_unknown)
179 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
180 if (SDKind == OMPD_unknown)
181 continue;
182
183 if (SDKind == F[I][1]) {
184 P.ConsumeToken();
185 DKind = F[I][2];
186 }
187 }
188 return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
189 : OMPD_unknown;
190}
191
192static DeclarationName parseOpenMPReductionId(Parser &P) {
193 Token Tok = P.getCurToken();
194 Sema &Actions = P.getActions();
195 OverloadedOperatorKind OOK = OO_None;
196 // Allow to use 'operator' keyword for C++ operators
197 bool WithOperator = false;
198 if (Tok.is(tok::kw_operator)) {
199 P.ConsumeToken();
200 Tok = P.getCurToken();
201 WithOperator = true;
202 }
203 switch (Tok.getKind()) {
204 case tok::plus: // '+'
205 OOK = OO_Plus;
206 break;
207 case tok::minus: // '-'
208 OOK = OO_Minus;
209 break;
210 case tok::star: // '*'
211 OOK = OO_Star;
212 break;
213 case tok::amp: // '&'
214 OOK = OO_Amp;
215 break;
216 case tok::pipe: // '|'
217 OOK = OO_Pipe;
218 break;
219 case tok::caret: // '^'
220 OOK = OO_Caret;
221 break;
222 case tok::ampamp: // '&&'
223 OOK = OO_AmpAmp;
224 break;
225 case tok::pipepipe: // '||'
226 OOK = OO_PipePipe;
227 break;
228 case tok::identifier: // identifier
229 if (!WithOperator)
230 break;
231 LLVM_FALLTHROUGH[[gnu::fallthrough]];
232 default:
233 P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
234 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
235 Parser::StopBeforeMatch);
236 return DeclarationName();
237 }
238 P.ConsumeToken();
239 auto &DeclNames = Actions.getASTContext().DeclarationNames;
240 return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
241 : DeclNames.getCXXOperatorName(OOK);
242}
243
244/// Parse 'omp declare reduction' construct.
245///
246/// declare-reduction-directive:
247/// annot_pragma_openmp 'declare' 'reduction'
248/// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
249/// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
250/// annot_pragma_openmp_end
251/// <reduction_id> is either a base language identifier or one of the following
252/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
253///
254Parser::DeclGroupPtrTy
255Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
256 // Parse '('.
257 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
258 if (T.expectAndConsume(
259 diag::err_expected_lparen_after,
260 getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
261 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
262 return DeclGroupPtrTy();
263 }
264
265 DeclarationName Name = parseOpenMPReductionId(*this);
266 if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
267 return DeclGroupPtrTy();
268
269 // Consume ':'.
270 bool IsCorrect = !ExpectAndConsume(tok::colon);
271
272 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
273 return DeclGroupPtrTy();
274
275 IsCorrect = IsCorrect && !Name.isEmpty();
276
277 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
278 Diag(Tok.getLocation(), diag::err_expected_type);
279 IsCorrect = false;
280 }
281
282 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
283 return DeclGroupPtrTy();
284
285 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
286 // Parse list of types until ':' token.
287 do {
288 ColonProtectionRAIIObject ColonRAII(*this);
289 SourceRange Range;
290 TypeResult TR =
291 ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
292 if (TR.isUsable()) {
293 QualType ReductionType =
294 Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
295 if (!ReductionType.isNull()) {
296 ReductionTypes.push_back(
297 std::make_pair(ReductionType, Range.getBegin()));
298 }
299 } else {
300 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
301 StopBeforeMatch);
302 }
303
304 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
305 break;
306
307 // Consume ','.
308 if (ExpectAndConsume(tok::comma)) {
309 IsCorrect = false;
310 if (Tok.is(tok::annot_pragma_openmp_end)) {
311 Diag(Tok.getLocation(), diag::err_expected_type);
312 return DeclGroupPtrTy();
313 }
314 }
315 } while (Tok.isNot(tok::annot_pragma_openmp_end));
316
317 if (ReductionTypes.empty()) {
318 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
319 return DeclGroupPtrTy();
320 }
321
322 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
323 return DeclGroupPtrTy();
324
325 // Consume ':'.
326 if (ExpectAndConsume(tok::colon))
327 IsCorrect = false;
328
329 if (Tok.is(tok::annot_pragma_openmp_end)) {
330 Diag(Tok.getLocation(), diag::err_expected_expression);
331 return DeclGroupPtrTy();
332 }
333
334 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
335 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
336
337 // Parse <combiner> expression and then parse initializer if any for each
338 // correct type.
339 unsigned I = 0, E = ReductionTypes.size();
340 for (Decl *D : DRD.get()) {
341 TentativeParsingAction TPA(*this);
342 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
343 Scope::CompoundStmtScope |
344 Scope::OpenMPDirectiveScope);
345 // Parse <combiner> expression.
346 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
347 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
348 ParseExpression().get(), D->getLocation(), /*DiscardedValue*/ false);
349 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
350
351 if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
352 Tok.isNot(tok::annot_pragma_openmp_end)) {
353 TPA.Commit();
354 IsCorrect = false;
355 break;
356 }
357 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
358 ExprResult InitializerResult;
359 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
360 // Parse <initializer> expression.
361 if (Tok.is(tok::identifier) &&
362 Tok.getIdentifierInfo()->isStr("initializer")) {
363 ConsumeToken();
364 } else {
365 Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
366 TPA.Commit();
367 IsCorrect = false;
368 break;
369 }
370 // Parse '('.
371 BalancedDelimiterTracker T(*this, tok::l_paren,
372 tok::annot_pragma_openmp_end);
373 IsCorrect =
374 !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
375 IsCorrect;
376 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
377 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
378 Scope::CompoundStmtScope |
379 Scope::OpenMPDirectiveScope);
380 // Parse expression.
381 VarDecl *OmpPrivParm =
382 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
383 D);
384 // Check if initializer is omp_priv <init_expr> or something else.
385 if (Tok.is(tok::identifier) &&
386 Tok.getIdentifierInfo()->isStr("omp_priv")) {
387 ConsumeToken();
388 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
389 } else {
390 InitializerResult = Actions.ActOnFinishFullExpr(
391 ParseAssignmentExpression().get(), D->getLocation(),
392 /*DiscardedValue*/ false);
393 }
394 Actions.ActOnOpenMPDeclareReductionInitializerEnd(
395 D, InitializerResult.get(), OmpPrivParm);
396 if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
397 Tok.isNot(tok::annot_pragma_openmp_end)) {
398 TPA.Commit();
399 IsCorrect = false;
400 break;
401 }
402 IsCorrect =
403 !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
404 }
405 }
406
407 ++I;
408 // Revert parsing if not the last type, otherwise accept it, we're done with
409 // parsing.
410 if (I != E)
411 TPA.Revert();
412 else
413 TPA.Commit();
414 }
415 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
416 IsCorrect);
417}
418
419void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
420 // Parse declarator '=' initializer.
421 // If a '==' or '+=' is found, suggest a fixit to '='.
422 if (isTokenEqualOrEqualTypo()) {
423 ConsumeToken();
424
425 if (Tok.is(tok::code_completion)) {
426 Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
427 Actions.FinalizeDeclaration(OmpPrivParm);
428 cutOffParsing();
429 return;
430 }
431
432 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
433 ExprResult Init = ParseInitializer();
434
435 if (Init.isInvalid()) {
436 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
437 Actions.ActOnInitializerError(OmpPrivParm);
438 } else {
439 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
440 /*DirectInit=*/false);
441 }
442 } else if (Tok.is(tok::l_paren)) {
443 // Parse C++ direct initializer: '(' expression-list ')'
444 BalancedDelimiterTracker T(*this, tok::l_paren);
445 T.consumeOpen();
446
447 ExprVector Exprs;
448 CommaLocsTy CommaLocs;
449
450 SourceLocation LParLoc = T.getOpenLocation();
451 auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
452 QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
453 getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
454 OmpPrivParm->getLocation(), Exprs, LParLoc);
455 CalledSignatureHelp = true;
456 return PreferredType;
457 };
458 if (ParseExpressionList(Exprs, CommaLocs, [&] {
459 PreferredType.enterFunctionArgument(Tok.getLocation(),
460 RunSignatureHelp);
461 })) {
462 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
463 RunSignatureHelp();
464 Actions.ActOnInitializerError(OmpPrivParm);
465 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
466 } else {
467 // Match the ')'.
468 SourceLocation RLoc = Tok.getLocation();
469 if (!T.consumeClose())
470 RLoc = T.getCloseLocation();
471
472 assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&((!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size
() && "Unexpected number of commas!") ? static_cast<
void> (0) : __assert_fail ("!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() && \"Unexpected number of commas!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 473, __PRETTY_FUNCTION__))
473 "Unexpected number of commas!")((!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size
() && "Unexpected number of commas!") ? static_cast<
void> (0) : __assert_fail ("!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() && \"Unexpected number of commas!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 473, __PRETTY_FUNCTION__))
;
474
475 ExprResult Initializer =
476 Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
477 Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
478 /*DirectInit=*/true);
479 }
480 } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
481 // Parse C++0x braced-init-list.
482 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
483
484 ExprResult Init(ParseBraceInitializer());
485
486 if (Init.isInvalid()) {
487 Actions.ActOnInitializerError(OmpPrivParm);
488 } else {
489 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
490 /*DirectInit=*/true);
491 }
492 } else {
493 Actions.ActOnUninitializedDecl(OmpPrivParm);
494 }
495}
496
497/// Parses 'omp declare mapper' directive.
498///
499/// declare-mapper-directive:
500/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
501/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
502/// annot_pragma_openmp_end
503/// <mapper-identifier> and <var> are base language identifiers.
504///
505Parser::DeclGroupPtrTy
506Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
507 bool IsCorrect = true;
508 // Parse '('
509 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
510 if (T.expectAndConsume(diag::err_expected_lparen_after,
511 getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
512 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
513 return DeclGroupPtrTy();
514 }
515
516 // Parse <mapper-identifier>
517 auto &DeclNames = Actions.getASTContext().DeclarationNames;
518 DeclarationName MapperId;
519 if (PP.LookAhead(0).is(tok::colon)) {
520 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
521 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
522 IsCorrect = false;
523 } else {
524 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
525 }
526 ConsumeToken();
527 // Consume ':'.
528 ExpectAndConsume(tok::colon);
529 } else {
530 // If no mapper identifier is provided, its name is "default" by default
531 MapperId =
532 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
533 }
534
535 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
536 return DeclGroupPtrTy();
537
538 // Parse <type> <var>
539 DeclarationName VName;
540 QualType MapperType;
541 SourceRange Range;
542 TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
543 if (ParsedType.isUsable())
544 MapperType =
545 Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
546 if (MapperType.isNull())
547 IsCorrect = false;
548 if (!IsCorrect) {
549 SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
550 return DeclGroupPtrTy();
551 }
552
553 // Consume ')'.
554 IsCorrect &= !T.consumeClose();
555 if (!IsCorrect) {
556 SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
557 return DeclGroupPtrTy();
558 }
559
560 // Enter scope.
561 OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
562 getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
563 Range.getBegin(), VName, AS);
564 DeclarationNameInfo DirName;
565 SourceLocation Loc = Tok.getLocation();
566 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
567 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
568 ParseScope OMPDirectiveScope(this, ScopeFlags);
569 Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
570
571 // Add the mapper variable declaration.
572 Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
573 DMD, getCurScope(), MapperType, Range.getBegin(), VName);
574
575 // Parse map clauses.
576 SmallVector<OMPClause *, 6> Clauses;
577 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
578 OpenMPClauseKind CKind = Tok.isAnnotation()
579 ? OMPC_unknown
580 : getOpenMPClauseKind(PP.getSpelling(Tok));
581 Actions.StartOpenMPClause(CKind);
582 OMPClause *Clause =
583 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
584 if (Clause)
585 Clauses.push_back(Clause);
586 else
587 IsCorrect = false;
588 // Skip ',' if any.
589 if (Tok.is(tok::comma))
590 ConsumeToken();
591 Actions.EndOpenMPClause();
592 }
593 if (Clauses.empty()) {
594 Diag(Tok, diag::err_omp_expected_clause)
595 << getOpenMPDirectiveName(OMPD_declare_mapper);
596 IsCorrect = false;
597 }
598
599 // Exit scope.
600 Actions.EndOpenMPDSABlock(nullptr);
601 OMPDirectiveScope.Exit();
602
603 DeclGroupPtrTy DGP =
604 Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
605 if (!IsCorrect)
606 return DeclGroupPtrTy();
607 return DGP;
608}
609
610TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
611 DeclarationName &Name,
612 AccessSpecifier AS) {
613 // Parse the common declaration-specifiers piece.
614 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
615 DeclSpec DS(AttrFactory);
616 ParseSpecifierQualifierList(DS, AS, DSC);
617
618 // Parse the declarator.
619 DeclaratorContext Context = DeclaratorContext::PrototypeContext;
620 Declarator DeclaratorInfo(DS, Context);
621 ParseDeclarator(DeclaratorInfo);
622 Range = DeclaratorInfo.getSourceRange();
623 if (DeclaratorInfo.getIdentifier() == nullptr) {
624 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
625 return true;
626 }
627 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
628
629 return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
630}
631
632namespace {
633/// RAII that recreates function context for correct parsing of clauses of
634/// 'declare simd' construct.
635/// OpenMP, 2.8.2 declare simd Construct
636/// The expressions appearing in the clauses of this directive are evaluated in
637/// the scope of the arguments of the function declaration or definition.
638class FNContextRAII final {
639 Parser &P;
640 Sema::CXXThisScopeRAII *ThisScope;
641 Parser::ParseScope *TempScope;
642 Parser::ParseScope *FnScope;
643 bool HasTemplateScope = false;
644 bool HasFunScope = false;
645 FNContextRAII() = delete;
646 FNContextRAII(const FNContextRAII &) = delete;
647 FNContextRAII &operator=(const FNContextRAII &) = delete;
648
649public:
650 FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
651 Decl *D = *Ptr.get().begin();
652 NamedDecl *ND = dyn_cast<NamedDecl>(D);
653 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
654 Sema &Actions = P.getActions();
655
656 // Allow 'this' within late-parsed attributes.
657 ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
658 ND && ND->isCXXInstanceMember());
659
660 // If the Decl is templatized, add template parameters to scope.
661 HasTemplateScope = D->isTemplateDecl();
662 TempScope =
663 new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
664 if (HasTemplateScope)
665 Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
666
667 // If the Decl is on a function, add function parameters to the scope.
668 HasFunScope = D->isFunctionOrFunctionTemplate();
669 FnScope = new Parser::ParseScope(
670 &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
671 HasFunScope);
672 if (HasFunScope)
673 Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
674 }
675 ~FNContextRAII() {
676 if (HasFunScope) {
677 P.getActions().ActOnExitFunctionContext();
678 FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
679 }
680 if (HasTemplateScope)
681 TempScope->Exit();
682 delete FnScope;
683 delete TempScope;
684 delete ThisScope;
685 }
686};
687} // namespace
688
689/// Parses clauses for 'declare simd' directive.
690/// clause:
691/// 'inbranch' | 'notinbranch'
692/// 'simdlen' '(' <expr> ')'
693/// { 'uniform' '(' <argument_list> ')' }
694/// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
695/// { 'linear '(' <argument_list> [ ':' <step> ] ')' }
696static bool parseDeclareSimdClauses(
697 Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
698 SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
699 SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
700 SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
701 SourceRange BSRange;
702 const Token &Tok = P.getCurToken();
703 bool IsError = false;
704 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
705 if (Tok.isNot(tok::identifier))
706 break;
707 OMPDeclareSimdDeclAttr::BranchStateTy Out;
708 IdentifierInfo *II = Tok.getIdentifierInfo();
709 StringRef ClauseName = II->getName();
710 // Parse 'inranch|notinbranch' clauses.
711 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
712 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
713 P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
714 << ClauseName
715 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
716 IsError = true;
717 }
718 BS = Out;
719 BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
720 P.ConsumeToken();
721 } else if (ClauseName.equals("simdlen")) {
722 if (SimdLen.isUsable()) {
723 P.Diag(Tok, diag::err_omp_more_one_clause)
724 << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
725 IsError = true;
726 }
727 P.ConsumeToken();
728 SourceLocation RLoc;
729 SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
730 if (SimdLen.isInvalid())
731 IsError = true;
732 } else {
733 OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
734 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
735 CKind == OMPC_linear) {
736 Parser::OpenMPVarListDataTy Data;
737 SmallVectorImpl<Expr *> *Vars = &Uniforms;
738 if (CKind == OMPC_aligned) {
739 Vars = &Aligneds;
740 } else if (CKind == OMPC_linear) {
741 Data.ExtraModifier = OMPC_LINEAR_val;
742 Vars = &Linears;
743 }
744
745 P.ConsumeToken();
746 if (P.ParseOpenMPVarList(OMPD_declare_simd,
747 getOpenMPClauseKind(ClauseName), *Vars, Data))
748 IsError = true;
749 if (CKind == OMPC_aligned) {
750 Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
751 } else if (CKind == OMPC_linear) {
752 assert(0 <= Data.ExtraModifier &&((0 <= Data.ExtraModifier && Data.ExtraModifier <=
OMPC_LINEAR_unknown && "Unexpected linear modifier."
) ? static_cast<void> (0) : __assert_fail ("0 <= Data.ExtraModifier && Data.ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 754, __PRETTY_FUNCTION__))
753 Data.ExtraModifier <= OMPC_LINEAR_unknown &&((0 <= Data.ExtraModifier && Data.ExtraModifier <=
OMPC_LINEAR_unknown && "Unexpected linear modifier."
) ? static_cast<void> (0) : __assert_fail ("0 <= Data.ExtraModifier && Data.ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 754, __PRETTY_FUNCTION__))
754 "Unexpected linear modifier.")((0 <= Data.ExtraModifier && Data.ExtraModifier <=
OMPC_LINEAR_unknown && "Unexpected linear modifier."
) ? static_cast<void> (0) : __assert_fail ("0 <= Data.ExtraModifier && Data.ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 754, __PRETTY_FUNCTION__))
;
755 if (P.getActions().CheckOpenMPLinearModifier(
756 static_cast<OpenMPLinearClauseKind>(Data.ExtraModifier),
757 Data.DepLinMapLastLoc))
758 Data.ExtraModifier = OMPC_LINEAR_val;
759 LinModifiers.append(Linears.size() - LinModifiers.size(),
760 Data.ExtraModifier);
761 Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
762 }
763 } else
764 // TODO: add parsing of other clauses.
765 break;
766 }
767 // Skip ',' if any.
768 if (Tok.is(tok::comma))
769 P.ConsumeToken();
770 }
771 return IsError;
772}
773
774/// Parse clauses for '#pragma omp declare simd'.
775Parser::DeclGroupPtrTy
776Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
777 CachedTokens &Toks, SourceLocation Loc) {
778 PP.EnterToken(Tok, /*IsReinject*/ true);
779 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
780 /*IsReinject*/ true);
781 // Consume the previously pushed token.
782 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
783 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
784
785 FNContextRAII FnContext(*this, Ptr);
786 OMPDeclareSimdDeclAttr::BranchStateTy BS =
787 OMPDeclareSimdDeclAttr::BS_Undefined;
788 ExprResult Simdlen;
789 SmallVector<Expr *, 4> Uniforms;
790 SmallVector<Expr *, 4> Aligneds;
791 SmallVector<Expr *, 4> Alignments;
792 SmallVector<Expr *, 4> Linears;
793 SmallVector<unsigned, 4> LinModifiers;
794 SmallVector<Expr *, 4> Steps;
795 bool IsError =
796 parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
797 Alignments, Linears, LinModifiers, Steps);
798 // Need to check for extra tokens.
799 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
800 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
801 << getOpenMPDirectiveName(OMPD_declare_simd);
802 while (Tok.isNot(tok::annot_pragma_openmp_end))
803 ConsumeAnyToken();
804 }
805 // Skip the last annot_pragma_openmp_end.
806 SourceLocation EndLoc = ConsumeAnnotationToken();
807 if (IsError)
808 return Ptr;
809 return Actions.ActOnOpenMPDeclareSimdDirective(
810 Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
811 LinModifiers, Steps, SourceRange(Loc, EndLoc));
812}
813
814namespace {
815/// Constant used in the diagnostics to distinguish the levels in an OpenMP
816/// contexts: selector-set={selector(trait, ...), ...}, ....
817enum OMPContextLvl {
818 CONTEXT_SELECTOR_SET_LVL = 0,
819 CONTEXT_SELECTOR_LVL = 1,
820 CONTEXT_TRAIT_LVL = 2,
821};
822
823static StringRef stringLiteralParser(Parser &P) {
824 ExprResult Res = P.ParseStringLiteralExpression(true);
825 return Res.isUsable() ? Res.getAs<StringLiteral>()->getString() : "";
826}
827
828static StringRef getNameFromIdOrString(Parser &P, Token &Tok,
829 OMPContextLvl Lvl) {
830 if (Tok.is(tok::identifier)) {
831 llvm::SmallString<16> Buffer;
832 StringRef Name = P.getPreprocessor().getSpelling(Tok, Buffer);
833 (void)P.ConsumeToken();
834 return Name;
835 }
836
837 if (tok::isStringLiteral(Tok.getKind()))
838 return stringLiteralParser(P);
839
840 P.Diag(Tok.getLocation(),
841 diag::warn_omp_declare_variant_string_literal_or_identifier)
842 << Lvl;
843 return "";
844}
845
846static bool checkForDuplicates(Parser &P, StringRef Name,
847 SourceLocation NameLoc,
848 llvm::StringMap<SourceLocation> &Seen,
849 OMPContextLvl Lvl) {
850 auto Res = Seen.try_emplace(Name, NameLoc);
851 if (Res.second)
852 return false;
853
854 // Each trait-set-selector-name, trait-selector-name and trait-name can
855 // only be specified once.
856 P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
857 << Lvl << Name;
858 P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
859 << Lvl << Name;
860 return true;
861}
862} // namespace
863
864void Parser::parseOMPTraitPropertyKind(
865 OMPTraitInfo::OMPTraitProperty &TIProperty, llvm::omp::TraitSet Set,
866 llvm::omp::TraitSelector Selector, llvm::StringMap<SourceLocation> &Seen) {
867 TIProperty.Kind = TraitProperty::invalid;
868
869 SourceLocation NameLoc = Tok.getLocation();
870 StringRef Name =
871 getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
872 if (Name.empty()) {
873 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
874 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
875 return;
876 }
877
878 TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Name);
879 if (TIProperty.Kind != TraitProperty::invalid) {
880 if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
881 TIProperty.Kind = TraitProperty::invalid;
882 return;
883 }
884
885 // It follows diagnosis and helping notes.
886 // FIXME: We should move the diagnosis string generation into libFrontend.
887 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
888 << Name << getOpenMPContextTraitSelectorName(Selector)
889 << getOpenMPContextTraitSetName(Set);
890
891 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
892 if (SetForName != TraitSet::invalid) {
893 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
894 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
895 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
896 << Name << "<selector-name>"
897 << "(<property-name>)";
898 return;
899 }
900 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
901 if (SelectorForName != TraitSelector::invalid) {
902 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
903 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
904 bool AllowsTraitScore = false;
905 bool RequiresProperty = false;
906 isValidTraitSelectorForTraitSet(
907 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
908 AllowsTraitScore, RequiresProperty);
909 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
910 << getOpenMPContextTraitSetName(
911 getOpenMPContextTraitSetForSelector(SelectorForName))
912 << Name << (RequiresProperty ? "(<property-name>)" : "");
913 return;
914 }
915 for (const auto &PotentialSet :
916 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
917 TraitSet::device}) {
918 TraitProperty PropertyForName =
919 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
920 if (PropertyForName == TraitProperty::invalid)
921 continue;
922 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
923 << getOpenMPContextTraitSetName(
924 getOpenMPContextTraitSetForProperty(PropertyForName))
925 << getOpenMPContextTraitSelectorName(
926 getOpenMPContextTraitSelectorForProperty(PropertyForName))
927 << ("(" + Name + ")").str();
928 return;
929 }
930 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
931 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
932}
933
934void Parser::parseOMPContextProperty(OMPTraitInfo::OMPTraitSelector &TISelector,
935 llvm::omp::TraitSet Set,
936 llvm::StringMap<SourceLocation> &Seen) {
937 assert(TISelector.Kind != TraitSelector::user_condition &&((TISelector.Kind != TraitSelector::user_condition &&
"User conditions are special properties not handled here!") ?
static_cast<void> (0) : __assert_fail ("TISelector.Kind != TraitSelector::user_condition && \"User conditions are special properties not handled here!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 938, __PRETTY_FUNCTION__))
938 "User conditions are special properties not handled here!")((TISelector.Kind != TraitSelector::user_condition &&
"User conditions are special properties not handled here!") ?
static_cast<void> (0) : __assert_fail ("TISelector.Kind != TraitSelector::user_condition && \"User conditions are special properties not handled here!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 938, __PRETTY_FUNCTION__))
;
939
940 SourceLocation PropertyLoc = Tok.getLocation();
941 OMPTraitInfo::OMPTraitProperty TIProperty;
942 parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen);
943
944 // If we have an invalid property here we already issued a warning.
945 if (TIProperty.Kind == TraitProperty::invalid) {
946 if (PropertyLoc != Tok.getLocation())
947 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
948 << CONTEXT_TRAIT_LVL;
949 return;
950 }
951
952 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind,
953 TISelector.Kind, Set)) {
954 // If we make it here the property, selector, set, score, condition, ... are
955 // all valid (or have been corrected). Thus we can record the property.
956 TISelector.Properties.push_back(TIProperty);
957 return;
958 }
959
960 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
961 << getOpenMPContextTraitPropertyName(TIProperty.Kind)
962 << getOpenMPContextTraitSelectorName(TISelector.Kind)
963 << getOpenMPContextTraitSetName(Set);
964 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
965 << getOpenMPContextTraitPropertyName(TIProperty.Kind)
966 << getOpenMPContextTraitSelectorName(
967 getOpenMPContextTraitSelectorForProperty(TIProperty.Kind))
968 << getOpenMPContextTraitSetName(
969 getOpenMPContextTraitSetForProperty(TIProperty.Kind));
970 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
971 << CONTEXT_TRAIT_LVL;
972}
973
974void Parser::parseOMPTraitSelectorKind(
975 OMPTraitInfo::OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
976 llvm::StringMap<SourceLocation> &Seen) {
977 TISelector.Kind = TraitSelector::invalid;
978
979 SourceLocation NameLoc = Tok.getLocation();
980 StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_LVL
981 );
982 if (Name.empty()) {
983 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
984 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
985 return;
986 }
987
988 TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
989 if (TISelector.Kind != TraitSelector::invalid) {
990 if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
991 TISelector.Kind = TraitSelector::invalid;
992 return;
993 }
994
995 // It follows diagnosis and helping notes.
996 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
997 << Name << getOpenMPContextTraitSetName(Set);
998
999 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1000 if (SetForName != TraitSet::invalid) {
1001 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1002 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1003 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1004 << Name << "<selector-name>"
1005 << "<property-name>";
1006 return;
1007 }
1008 for (const auto &PotentialSet :
1009 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1010 TraitSet::device}) {
1011 TraitProperty PropertyForName =
1012 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
1013 if (PropertyForName == TraitProperty::invalid)
1014 continue;
1015 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1016 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1017 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1018 << getOpenMPContextTraitSetName(
1019 getOpenMPContextTraitSetForProperty(PropertyForName))
1020 << getOpenMPContextTraitSelectorName(
1021 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1022 << ("(" + Name + ")").str();
1023 return;
1024 }
1025 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1026 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1027}
1028
1029/// Parse optional 'score' '(' <expr> ')' ':'.
1030static ExprResult parseContextScore(Parser &P) {
1031 ExprResult ScoreExpr;
1032 llvm::SmallString<16> Buffer;
1033 StringRef SelectorName =
1034 P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
1035 if (!SelectorName.equals("score"))
1036 return ScoreExpr;
1037 (void)P.ConsumeToken();
1038 SourceLocation RLoc;
1039 ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
1040 // Parse ':'
1041 if (P.getCurToken().is(tok::colon))
1042 (void)P.ConsumeAnyToken();
1043 else
1044 P.Diag(P.getCurToken(), diag::warn_omp_declare_variant_expected)
1045 << "':'"
1046 << "score expression";
1047 return ScoreExpr;
1048}
1049
1050/// Parses an OpenMP context selector.
1051///
1052/// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
1053void Parser::parseOMPContextSelector(
1054 OMPTraitInfo::OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1055 llvm::StringMap<SourceLocation> &SeenSelectors) {
1056 unsigned short OuterPC = ParenCount;
1057
1058 // If anything went wrong we issue an error or warning and then skip the rest
1059 // of the selector. However, commas are ambiguous so we look for the nesting
1060 // of parentheses here as well.
1061 auto FinishSelector = [OuterPC, this]() -> void {
1062 bool Done = false;
1063 while (!Done) {
1064 while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1065 tok::annot_pragma_openmp_end},
1066 StopBeforeMatch))
1067 ;
1068 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1069 (void)ConsumeParen();
1070 if (OuterPC <= ParenCount) {
1071 Done = true;
1072 break;
1073 }
1074 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1075 Done = true;
1076 break;
1077 }
1078 (void)ConsumeAnyToken();
1079 }
1080 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1081 << CONTEXT_SELECTOR_LVL;
1082 };
1083
1084 SourceLocation SelectorLoc = Tok.getLocation();
1085 parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1086 if (TISelector.Kind == TraitSelector::invalid)
1087 return FinishSelector();
1088
1089 bool AllowsTraitScore = false;
1090 bool RequiresProperty = false;
1091 if (!isValidTraitSelectorForTraitSet(TISelector.Kind, Set, AllowsTraitScore,
1092 RequiresProperty)) {
1093 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1094 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1095 << getOpenMPContextTraitSetName(Set);
1096 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1097 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1098 << getOpenMPContextTraitSetName(
1099 getOpenMPContextTraitSetForSelector(TISelector.Kind))
1100 << RequiresProperty;
1101 return FinishSelector();
1102 }
1103
1104 if (!RequiresProperty) {
1105 TISelector.Properties.push_back(
1106 {getOpenMPContextTraitPropertyForSelector(TISelector.Kind)});
1107 return;
1108 }
1109
1110 if (!Tok.is(tok::l_paren)) {
1111 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1112 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1113 << getOpenMPContextTraitSetName(Set);
1114 return FinishSelector();
1115 }
1116
1117 if (TISelector.Kind == TraitSelector::user_condition) {
1118 SourceLocation RLoc;
1119 ExprResult Condition = ParseOpenMPParensExpr("user condition", RLoc);
1120 if (!Condition.isUsable())
1121 return FinishSelector();
1122 TISelector.ScoreOrCondition = Condition.get();
1123 TISelector.Properties.push_back({TraitProperty::user_condition_unknown});
1124 return;
1125 }
1126
1127 BalancedDelimiterTracker BDT(*this, tok::l_paren,
1128 tok::annot_pragma_openmp_end);
1129 // Parse '('.
1130 (void)BDT.consumeOpen();
1131
1132 ExprResult Score = parseContextScore(*this);
1133
1134 if (!AllowsTraitScore && Score.isUsable()) {
1135 Diag(Score.get()->getBeginLoc(),
1136 diag::warn_omp_ctx_incompatible_score_for_property)
1137 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1138 << getOpenMPContextTraitSetName(Set) << Score.get();
1139 Score = ExprResult();
1140 }
1141
1142 if (Score.isUsable())
1143 TISelector.ScoreOrCondition = Score.get();
1144
1145 llvm::StringMap<SourceLocation> SeenProperties;
1146 do {
1147 parseOMPContextProperty(TISelector, Set, SeenProperties);
1148 } while (TryConsumeToken(tok::comma));
1149
1150 // Parse ')'.
1151 BDT.consumeClose();
1152}
1153
1154void Parser::parseOMPTraitSetKind(OMPTraitInfo::OMPTraitSet &TISet,
1155 llvm::StringMap<SourceLocation> &Seen) {
1156 TISet.Kind = TraitSet::invalid;
1157
1158 SourceLocation NameLoc = Tok.getLocation();
1159 StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_SET_LVL
1160 );
1161 if (Name.empty()) {
1162 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1163 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1164 return;
1165 }
1166
1167 TISet.Kind = getOpenMPContextTraitSetKind(Name);
1168 if (TISet.Kind != TraitSet::invalid) {
1169 if (checkForDuplicates(*this, Name, NameLoc, Seen,
1170 CONTEXT_SELECTOR_SET_LVL))
1171 TISet.Kind = TraitSet::invalid;
1172 return;
1173 }
1174
1175 // It follows diagnosis and helping notes.
1176 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1177
1178 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1179 if (SelectorForName != TraitSelector::invalid) {
1180 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1181 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1182 bool AllowsTraitScore = false;
1183 bool RequiresProperty = false;
1184 isValidTraitSelectorForTraitSet(
1185 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1186 AllowsTraitScore, RequiresProperty);
1187 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1188 << getOpenMPContextTraitSetName(
1189 getOpenMPContextTraitSetForSelector(SelectorForName))
1190 << Name << (RequiresProperty ? "(<property-name>)" : "");
1191 return;
1192 }
1193 for (const auto &PotentialSet :
1194 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1195 TraitSet::device}) {
1196 TraitProperty PropertyForName =
1197 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
1198 if (PropertyForName == TraitProperty::invalid)
1199 continue;
1200 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1201 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1202 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1203 << getOpenMPContextTraitSetName(
1204 getOpenMPContextTraitSetForProperty(PropertyForName))
1205 << getOpenMPContextTraitSelectorName(
1206 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1207 << ("(" + Name + ")").str();
1208 return;
1209 }
1210 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1211 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1212}
1213
1214/// Parses an OpenMP context selector set.
1215///
1216/// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
1217void Parser::parseOMPContextSelectorSet(
1218 OMPTraitInfo::OMPTraitSet &TISet,
1219 llvm::StringMap<SourceLocation> &SeenSets) {
1220 auto OuterBC = BraceCount;
1221
1222 // If anything went wrong we issue an error or warning and then skip the rest
1223 // of the set. However, commas are ambiguous so we look for the nesting
1224 // of braces here as well.
1225 auto FinishSelectorSet = [this, OuterBC]() -> void {
1226 bool Done = false;
1227 while (!Done) {
1228 while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1229 tok::annot_pragma_openmp_end},
1230 StopBeforeMatch))
1231 ;
1232 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1233 (void)ConsumeBrace();
1234 if (OuterBC <= BraceCount) {
1235 Done = true;
1236 break;
1237 }
1238 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1239 Done = true;
1240 break;
1241 }
1242 (void)ConsumeAnyToken();
1243 }
1244 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1245 << CONTEXT_SELECTOR_SET_LVL;
1246 };
1247
1248 parseOMPTraitSetKind(TISet, SeenSets);
1249 if (TISet.Kind == TraitSet::invalid)
1250 return FinishSelectorSet();
1251
1252 // Parse '='.
1253 if (!TryConsumeToken(tok::equal))
1254 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1255 << "="
1256 << ("context set name \"" + getOpenMPContextTraitSetName(TISet.Kind) +
1257 "\"")
1258 .str();
1259
1260 // Parse '{'.
1261 if (Tok.is(tok::l_brace)) {
1262 (void)ConsumeBrace();
1263 } else {
1264 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1265 << "{"
1266 << ("'=' that follows the context set name \"" +
1267 getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1268 .str();
1269 }
1270
1271 llvm::StringMap<SourceLocation> SeenSelectors;
1272 do {
1273 OMPTraitInfo::OMPTraitSelector TISelector;
1274 parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors);
1275 if (TISelector.Kind != TraitSelector::invalid &&
1276 !TISelector.Properties.empty())
1277 TISet.Selectors.push_back(TISelector);
1278 } while (TryConsumeToken(tok::comma));
1279
1280 // Parse '}'.
1281 if (Tok.is(tok::r_brace)) {
1282 (void)ConsumeBrace();
1283 } else {
1284 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1285 << "}"
1286 << ("context selectors for the context set \"" +
1287 getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1288 .str();
1289 }
1290}
1291
1292/// Parse OpenMP context selectors:
1293///
1294/// <trait-set-selector> [, <trait-set-selector>]*
1295bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) {
1296 llvm::StringMap<SourceLocation> SeenSets;
1297 do {
1298 OMPTraitInfo::OMPTraitSet TISet;
1299 parseOMPContextSelectorSet(TISet, SeenSets);
1300 if (TISet.Kind != TraitSet::invalid && !TISet.Selectors.empty())
1301 TI.Sets.push_back(TISet);
1302 } while (TryConsumeToken(tok::comma));
1303
1304 return false;
1305}
1306
1307/// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
1308void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
1309 CachedTokens &Toks,
1310 SourceLocation Loc) {
1311 PP.EnterToken(Tok, /*IsReinject*/ true);
1312 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1313 /*IsReinject*/ true);
1314 // Consume the previously pushed token.
1315 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1316 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1317
1318 FNContextRAII FnContext(*this, Ptr);
1319 // Parse function declaration id.
1320 SourceLocation RLoc;
1321 // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs
1322 // instead of MemberExprs.
1323 ExprResult AssociatedFunction;
1324 {
1325 // Do not mark function as is used to prevent its emission if this is the
1326 // only place where it is used.
1327 EnterExpressionEvaluationContext Unevaluated(
1328 Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1329 AssociatedFunction = ParseOpenMPParensExpr(
1330 getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1331 /*IsAddressOfOperand=*/true);
1332 }
1333 if (!AssociatedFunction.isUsable()) {
1334 if (!Tok.is(tok::annot_pragma_openmp_end))
1335 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1336 ;
1337 // Skip the last annot_pragma_openmp_end.
1338 (void)ConsumeAnnotationToken();
1339 return;
1340 }
1341
1342 // Parse 'match'.
1343 OpenMPClauseKind CKind = Tok.isAnnotation()
1344 ? OMPC_unknown
1345 : getOpenMPClauseKind(PP.getSpelling(Tok));
1346 if (CKind != OMPC_match) {
1347 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1348 << getOpenMPClauseName(OMPC_match);
1349 while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
1350 ;
1351 // Skip the last annot_pragma_openmp_end.
1352 (void)ConsumeAnnotationToken();
1353 return;
1354 }
1355 (void)ConsumeToken();
1356 // Parse '('.
1357 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1358 if (T.expectAndConsume(diag::err_expected_lparen_after,
1359 getOpenMPClauseName(OMPC_match))) {
1360 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1361 ;
1362 // Skip the last annot_pragma_openmp_end.
1363 (void)ConsumeAnnotationToken();
1364 return;
1365 }
1366
1367 // Parse inner context selectors.
1368 OMPTraitInfo TI;
1369 parseOMPContextSelectors(Loc, TI);
1370
1371 // Parse ')'
1372 (void)T.consumeClose();
1373
1374 Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1375 Actions.checkOpenMPDeclareVariantFunction(
1376 Ptr, AssociatedFunction.get(), TI,
1377 SourceRange(Loc, Tok.getLocation()));
1378
1379 // Skip last tokens.
1380 while (Tok.isNot(tok::annot_pragma_openmp_end))
1381 ConsumeAnyToken();
1382 if (DeclVarData.hasValue() && !TI.Sets.empty())
1383 Actions.ActOnOpenMPDeclareVariantDirective(
1384 DeclVarData.getValue().first, DeclVarData.getValue().second, TI,
1385 SourceRange(Loc, Tok.getLocation()));
1386
1387 // Skip the last annot_pragma_openmp_end.
1388 (void)ConsumeAnnotationToken();
1389}
1390
1391/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1392///
1393/// default-clause:
1394/// 'default' '(' 'none' | 'shared' ')
1395///
1396/// proc_bind-clause:
1397/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
1398///
1399/// device_type-clause:
1400/// 'device_type' '(' 'host' | 'nohost' | 'any' )'
1401namespace {
1402 struct SimpleClauseData {
1403 unsigned Type;
1404 SourceLocation Loc;
1405 SourceLocation LOpen;
1406 SourceLocation TypeLoc;
1407 SourceLocation RLoc;
1408 SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1409 SourceLocation TypeLoc, SourceLocation RLoc)
1410 : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1411 };
1412} // anonymous namespace
1413
1414static Optional<SimpleClauseData>
1415parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) {
1416 const Token &Tok = P.getCurToken();
1417 SourceLocation Loc = Tok.getLocation();
1418 SourceLocation LOpen = P.ConsumeToken();
1419 // Parse '('.
1420 BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
1421 if (T.expectAndConsume(diag::err_expected_lparen_after,
1422 getOpenMPClauseName(Kind)))
1423 return llvm::None;
1424
1425 unsigned Type = getOpenMPSimpleClauseType(
1426 Kind, Tok.isAnnotation() ? "" : P.getPreprocessor().getSpelling(Tok));
1427 SourceLocation TypeLoc = Tok.getLocation();
1428 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1429 Tok.isNot(tok::annot_pragma_openmp_end))
1430 P.ConsumeAnyToken();
1431
1432 // Parse ')'.
1433 SourceLocation RLoc = Tok.getLocation();
1434 if (!T.consumeClose())
1435 RLoc = T.getCloseLocation();
1436
1437 return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc);
1438}
1439
1440Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
1441 // OpenMP 4.5 syntax with list of entities.
1442 Sema::NamedDeclSetType SameDirectiveDecls;
1443 SmallVector<std::tuple<OMPDeclareTargetDeclAttr::MapTypeTy, SourceLocation,
1444 NamedDecl *>,
1445 4>
1446 DeclareTargetDecls;
1447 OMPDeclareTargetDeclAttr::DevTypeTy DT = OMPDeclareTargetDeclAttr::DT_Any;
1448 SourceLocation DeviceTypeLoc;
1449 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1450 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1451 if (Tok.is(tok::identifier)) {
1452 IdentifierInfo *II = Tok.getIdentifierInfo();
1453 StringRef ClauseName = II->getName();
1454 bool IsDeviceTypeClause =
1455 getLangOpts().OpenMP >= 50 &&
1456 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1457 // Parse 'to|link|device_type' clauses.
1458 if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT) &&
1459 !IsDeviceTypeClause) {
1460 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1461 << ClauseName << (getLangOpts().OpenMP >= 50 ? 1 : 0);
1462 break;
1463 }
1464 // Parse 'device_type' clause and go to next clause if any.
1465 if (IsDeviceTypeClause) {
1466 Optional<SimpleClauseData> DevTypeData =
1467 parseOpenMPSimpleClause(*this, OMPC_device_type);
1468 if (DevTypeData.hasValue()) {
1469 if (DeviceTypeLoc.isValid()) {
1470 // We already saw another device_type clause, diagnose it.
1471 Diag(DevTypeData.getValue().Loc,
1472 diag::warn_omp_more_one_device_type_clause);
1473 }
1474 switch(static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) {
1475 case OMPC_DEVICE_TYPE_any:
1476 DT = OMPDeclareTargetDeclAttr::DT_Any;
1477 break;
1478 case OMPC_DEVICE_TYPE_host:
1479 DT = OMPDeclareTargetDeclAttr::DT_Host;
1480 break;
1481 case OMPC_DEVICE_TYPE_nohost:
1482 DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1483 break;
1484 case OMPC_DEVICE_TYPE_unknown:
1485 llvm_unreachable("Unexpected device_type")::llvm::llvm_unreachable_internal("Unexpected device_type", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 1485)
;
1486 }
1487 DeviceTypeLoc = DevTypeData.getValue().Loc;
1488 }
1489 continue;
1490 }
1491 ConsumeToken();
1492 }
1493 auto &&Callback = [this, MT, &DeclareTargetDecls, &SameDirectiveDecls](
1494 CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
1495 NamedDecl *ND = Actions.lookupOpenMPDeclareTargetName(
1496 getCurScope(), SS, NameInfo, SameDirectiveDecls);
1497 if (ND)
1498 DeclareTargetDecls.emplace_back(MT, NameInfo.getLoc(), ND);
1499 };
1500 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1501 /*AllowScopeSpecifier=*/true))
1502 break;
1503
1504 // Consume optional ','.
1505 if (Tok.is(tok::comma))
1506 ConsumeToken();
1507 }
1508 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1509 ConsumeAnyToken();
1510 for (auto &MTLocDecl : DeclareTargetDecls) {
1511 OMPDeclareTargetDeclAttr::MapTypeTy MT;
1512 SourceLocation Loc;
1513 NamedDecl *ND;
1514 std::tie(MT, Loc, ND) = MTLocDecl;
1515 // device_type clause is applied only to functions.
1516 Actions.ActOnOpenMPDeclareTargetName(
1517 ND, Loc, MT, isa<VarDecl>(ND) ? OMPDeclareTargetDeclAttr::DT_Any : DT);
1518 }
1519 SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
1520 SameDirectiveDecls.end());
1521 if (Decls.empty())
1522 return DeclGroupPtrTy();
1523 return Actions.BuildDeclaratorGroup(Decls);
1524}
1525
1526void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
1527 SourceLocation DTLoc) {
1528 if (DKind != OMPD_end_declare_target) {
1529 Diag(Tok, diag::err_expected_end_declare_target);
1530 Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
1531 return;
1532 }
1533 ConsumeAnyToken();
1534 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1535 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1536 << getOpenMPDirectiveName(OMPD_end_declare_target);
1537 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1538 }
1539 // Skip the last annot_pragma_openmp_end.
1540 ConsumeAnyToken();
1541}
1542
1543/// Parsing of declarative OpenMP directives.
1544///
1545/// threadprivate-directive:
1546/// annot_pragma_openmp 'threadprivate' simple-variable-list
1547/// annot_pragma_openmp_end
1548///
1549/// allocate-directive:
1550/// annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
1551/// annot_pragma_openmp_end
1552///
1553/// declare-reduction-directive:
1554/// annot_pragma_openmp 'declare' 'reduction' [...]
1555/// annot_pragma_openmp_end
1556///
1557/// declare-mapper-directive:
1558/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1559/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
1560/// annot_pragma_openmp_end
1561///
1562/// declare-simd-directive:
1563/// annot_pragma_openmp 'declare simd' {<clause> [,]}
1564/// annot_pragma_openmp_end
1565/// <function declaration/definition>
1566///
1567/// requires directive:
1568/// annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
1569/// annot_pragma_openmp_end
1570///
1571Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
1572 AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
1573 DeclSpec::TST TagType, Decl *Tag) {
1574 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!")((Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"
) ? static_cast<void> (0) : __assert_fail ("Tok.is(tok::annot_pragma_openmp) && \"Not an OpenMP directive!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 1574, __PRETTY_FUNCTION__))
;
1575 ParsingOpenMPDirectiveRAII DirScope(*this);
1576 ParenBraceBracketBalancer BalancerRAIIObj(*this);
1577
1578 SourceLocation Loc;
1579 OpenMPDirectiveKind DKind;
1580 if (Delayed) {
1581 TentativeParsingAction TPA(*this);
1582 Loc = ConsumeAnnotationToken();
1583 DKind = parseOpenMPDirectiveKind(*this);
1584 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1585 // Need to delay parsing until completion of the parent class.
1586 TPA.Revert();
1587 CachedTokens Toks;
1588 unsigned Cnt = 1;
1589 Toks.push_back(Tok);
1590 while (Cnt && Tok.isNot(tok::eof)) {
1591 (void)ConsumeAnyToken();
1592 if (Tok.is(tok::annot_pragma_openmp))
1593 ++Cnt;
1594 else if (Tok.is(tok::annot_pragma_openmp_end))
1595 --Cnt;
1596 Toks.push_back(Tok);
1597 }
1598 // Skip last annot_pragma_openmp_end.
1599 if (Cnt == 0)
1600 (void)ConsumeAnyToken();
1601 auto *LP = new LateParsedPragma(this, AS);
1602 LP->takeToks(Toks);
1603 getCurrentClass().LateParsedDeclarations.push_back(LP);
1604 return nullptr;
1605 }
1606 TPA.Commit();
1607 } else {
1608 Loc = ConsumeAnnotationToken();
1609 DKind = parseOpenMPDirectiveKind(*this);
1610 }
1611
1612 switch (DKind) {
1613 case OMPD_threadprivate: {
1614 ConsumeToken();
1615 DeclDirectiveListParserHelper Helper(this, DKind);
1616 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1617 /*AllowScopeSpecifier=*/true)) {
1618 // The last seen token is annot_pragma_openmp_end - need to check for
1619 // extra tokens.
1620 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1621 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1622 << getOpenMPDirectiveName(DKind);
1623 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1624 }
1625 // Skip the last annot_pragma_openmp_end.
1626 ConsumeAnnotationToken();
1627 return Actions.ActOnOpenMPThreadprivateDirective(Loc,
1628 Helper.getIdentifiers());
1629 }
1630 break;
1631 }
1632 case OMPD_allocate: {
1633 ConsumeToken();
1634 DeclDirectiveListParserHelper Helper(this, DKind);
1635 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1636 /*AllowScopeSpecifier=*/true)) {
1637 SmallVector<OMPClause *, 1> Clauses;
1638 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1639 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1640 OMPC_unknown + 1>
1641 FirstClauses(OMPC_unknown + 1);
1642 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1643 OpenMPClauseKind CKind =
1644 Tok.isAnnotation() ? OMPC_unknown
1645 : getOpenMPClauseKind(PP.getSpelling(Tok));
1646 Actions.StartOpenMPClause(CKind);
1647 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
1648 !FirstClauses[CKind].getInt());
1649 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1650 StopBeforeMatch);
1651 FirstClauses[CKind].setInt(true);
1652 if (Clause != nullptr)
1653 Clauses.push_back(Clause);
1654 if (Tok.is(tok::annot_pragma_openmp_end)) {
1655 Actions.EndOpenMPClause();
1656 break;
1657 }
1658 // Skip ',' if any.
1659 if (Tok.is(tok::comma))
1660 ConsumeToken();
1661 Actions.EndOpenMPClause();
1662 }
1663 // The last seen token is annot_pragma_openmp_end - need to check for
1664 // extra tokens.
1665 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1666 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1667 << getOpenMPDirectiveName(DKind);
1668 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1669 }
1670 }
1671 // Skip the last annot_pragma_openmp_end.
1672 ConsumeAnnotationToken();
1673 return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
1674 Clauses);
1675 }
1676 break;
1677 }
1678 case OMPD_requires: {
1679 SourceLocation StartLoc = ConsumeToken();
1680 SmallVector<OMPClause *, 5> Clauses;
1681 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
1682 FirstClauses(OMPC_unknown + 1);
1683 if (Tok.is(tok::annot_pragma_openmp_end)) {
1684 Diag(Tok, diag::err_omp_expected_clause)
1685 << getOpenMPDirectiveName(OMPD_requires);
1686 break;
1687 }
1688 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1689 OpenMPClauseKind CKind = Tok.isAnnotation()
1690 ? OMPC_unknown
1691 : getOpenMPClauseKind(PP.getSpelling(Tok));
1692 Actions.StartOpenMPClause(CKind);
1693 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
1694 !FirstClauses[CKind].getInt());
1695 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1696 StopBeforeMatch);
1697 FirstClauses[CKind].setInt(true);
1698 if (Clause != nullptr)
1699 Clauses.push_back(Clause);
1700 if (Tok.is(tok::annot_pragma_openmp_end)) {
1701 Actions.EndOpenMPClause();
1702 break;
1703 }
1704 // Skip ',' if any.
1705 if (Tok.is(tok::comma))
1706 ConsumeToken();
1707 Actions.EndOpenMPClause();
1708 }
1709 // Consume final annot_pragma_openmp_end
1710 if (Clauses.empty()) {
1711 Diag(Tok, diag::err_omp_expected_clause)
1712 << getOpenMPDirectiveName(OMPD_requires);
1713 ConsumeAnnotationToken();
1714 return nullptr;
1715 }
1716 ConsumeAnnotationToken();
1717 return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
1718 }
1719 case OMPD_declare_reduction:
1720 ConsumeToken();
1721 if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
1722 // The last seen token is annot_pragma_openmp_end - need to check for
1723 // extra tokens.
1724 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1725 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1726 << getOpenMPDirectiveName(OMPD_declare_reduction);
1727 while (Tok.isNot(tok::annot_pragma_openmp_end))
1728 ConsumeAnyToken();
1729 }
1730 // Skip the last annot_pragma_openmp_end.
1731 ConsumeAnnotationToken();
1732 return Res;
1733 }
1734 break;
1735 case OMPD_declare_mapper: {
1736 ConsumeToken();
1737 if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1738 // Skip the last annot_pragma_openmp_end.
1739 ConsumeAnnotationToken();
1740 return Res;
1741 }
1742 break;
1743 }
1744 case OMPD_declare_variant:
1745 case OMPD_declare_simd: {
1746 // The syntax is:
1747 // { #pragma omp declare {simd|variant} }
1748 // <function-declaration-or-definition>
1749 //
1750 CachedTokens Toks;
1751 Toks.push_back(Tok);
1752 ConsumeToken();
1753 while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1754 Toks.push_back(Tok);
1755 ConsumeAnyToken();
1756 }
1757 Toks.push_back(Tok);
1758 ConsumeAnyToken();
1759
1760 DeclGroupPtrTy Ptr;
1761 if (Tok.is(tok::annot_pragma_openmp)) {
1762 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
1763 TagType, Tag);
1764 } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1765 // Here we expect to see some function declaration.
1766 if (AS == AS_none) {
1767 assert(TagType == DeclSpec::TST_unspecified)((TagType == DeclSpec::TST_unspecified) ? static_cast<void
> (0) : __assert_fail ("TagType == DeclSpec::TST_unspecified"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 1767, __PRETTY_FUNCTION__))
;
1768 MaybeParseCXX11Attributes(Attrs);
1769 ParsingDeclSpec PDS(*this);
1770 Ptr = ParseExternalDeclaration(Attrs, &PDS);
1771 } else {
1772 Ptr =
1773 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1774 }
1775 }
1776 if (!Ptr) {
1777 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
1778 << (DKind == OMPD_declare_simd ? 0 : 1);
1779 return DeclGroupPtrTy();
1780 }
1781 if (DKind == OMPD_declare_simd)
1782 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1783 assert(DKind == OMPD_declare_variant &&((DKind == OMPD_declare_variant && "Expected declare variant directive only"
) ? static_cast<void> (0) : __assert_fail ("DKind == OMPD_declare_variant && \"Expected declare variant directive only\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 1784, __PRETTY_FUNCTION__))
1784 "Expected declare variant directive only")((DKind == OMPD_declare_variant && "Expected declare variant directive only"
) ? static_cast<void> (0) : __assert_fail ("DKind == OMPD_declare_variant && \"Expected declare variant directive only\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 1784, __PRETTY_FUNCTION__))
;
1785 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
1786 return Ptr;
1787 }
1788 case OMPD_declare_target: {
1789 SourceLocation DTLoc = ConsumeAnyToken();
1790 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1791 return ParseOMPDeclareTargetClauses();
1792 }
1793
1794 // Skip the last annot_pragma_openmp_end.
1795 ConsumeAnyToken();
1796
1797 if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1798 return DeclGroupPtrTy();
1799
1800 llvm::SmallVector<Decl *, 4> Decls;
1801 DKind = parseOpenMPDirectiveKind(*this);
1802 while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
1803 Tok.isNot(tok::r_brace)) {
1804 DeclGroupPtrTy Ptr;
1805 // Here we expect to see some function declaration.
1806 if (AS == AS_none) {
1807 assert(TagType == DeclSpec::TST_unspecified)((TagType == DeclSpec::TST_unspecified) ? static_cast<void
> (0) : __assert_fail ("TagType == DeclSpec::TST_unspecified"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 1807, __PRETTY_FUNCTION__))
;
1808 MaybeParseCXX11Attributes(Attrs);
1809 ParsingDeclSpec PDS(*this);
1810 Ptr = ParseExternalDeclaration(Attrs, &PDS);
1811 } else {
1812 Ptr =
1813 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1814 }
1815 if (Ptr) {
1816 DeclGroupRef Ref = Ptr.get();
1817 Decls.append(Ref.begin(), Ref.end());
1818 }
1819 if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
1820 TentativeParsingAction TPA(*this);
1821 ConsumeAnnotationToken();
1822 DKind = parseOpenMPDirectiveKind(*this);
1823 if (DKind != OMPD_end_declare_target)
1824 TPA.Revert();
1825 else
1826 TPA.Commit();
1827 }
1828 }
1829
1830 ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
1831 Actions.ActOnFinishOpenMPDeclareTargetDirective();
1832 return Actions.BuildDeclaratorGroup(Decls);
1833 }
1834 case OMPD_unknown:
1835 Diag(Tok, diag::err_omp_unknown_directive);
1836 break;
1837 case OMPD_parallel:
1838 case OMPD_simd:
1839 case OMPD_task:
1840 case OMPD_taskyield:
1841 case OMPD_barrier:
1842 case OMPD_taskwait:
1843 case OMPD_taskgroup:
1844 case OMPD_flush:
1845 case OMPD_depobj:
1846 case OMPD_for:
1847 case OMPD_for_simd:
1848 case OMPD_sections:
1849 case OMPD_section:
1850 case OMPD_single:
1851 case OMPD_master:
1852 case OMPD_ordered:
1853 case OMPD_critical:
1854 case OMPD_parallel_for:
1855 case OMPD_parallel_for_simd:
1856 case OMPD_parallel_sections:
1857 case OMPD_parallel_master:
1858 case OMPD_atomic:
1859 case OMPD_target:
1860 case OMPD_teams:
1861 case OMPD_cancellation_point:
1862 case OMPD_cancel:
1863 case OMPD_target_data:
1864 case OMPD_target_enter_data:
1865 case OMPD_target_exit_data:
1866 case OMPD_target_parallel:
1867 case OMPD_target_parallel_for:
1868 case OMPD_taskloop:
1869 case OMPD_taskloop_simd:
1870 case OMPD_master_taskloop:
1871 case OMPD_master_taskloop_simd:
1872 case OMPD_parallel_master_taskloop:
1873 case OMPD_parallel_master_taskloop_simd:
1874 case OMPD_distribute:
1875 case OMPD_end_declare_target:
1876 case OMPD_target_update:
1877 case OMPD_distribute_parallel_for:
1878 case OMPD_distribute_parallel_for_simd:
1879 case OMPD_distribute_simd:
1880 case OMPD_target_parallel_for_simd:
1881 case OMPD_target_simd:
1882 case OMPD_teams_distribute:
1883 case OMPD_teams_distribute_simd:
1884 case OMPD_teams_distribute_parallel_for_simd:
1885 case OMPD_teams_distribute_parallel_for:
1886 case OMPD_target_teams:
1887 case OMPD_target_teams_distribute:
1888 case OMPD_target_teams_distribute_parallel_for:
1889 case OMPD_target_teams_distribute_parallel_for_simd:
1890 case OMPD_target_teams_distribute_simd:
1891 Diag(Tok, diag::err_omp_unexpected_directive)
1892 << 1 << getOpenMPDirectiveName(DKind);
1893 break;
1894 }
1895 while (Tok.isNot(tok::annot_pragma_openmp_end))
1896 ConsumeAnyToken();
1897 ConsumeAnyToken();
1898 return nullptr;
1899}
1900
1901/// Parsing of declarative or executable OpenMP directives.
1902///
1903/// threadprivate-directive:
1904/// annot_pragma_openmp 'threadprivate' simple-variable-list
1905/// annot_pragma_openmp_end
1906///
1907/// allocate-directive:
1908/// annot_pragma_openmp 'allocate' simple-variable-list
1909/// annot_pragma_openmp_end
1910///
1911/// declare-reduction-directive:
1912/// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
1913/// <type> {',' <type>} ':' <expression> ')' ['initializer' '('
1914/// ('omp_priv' '=' <expression>|<function_call>) ')']
1915/// annot_pragma_openmp_end
1916///
1917/// declare-mapper-directive:
1918/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1919/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
1920/// annot_pragma_openmp_end
1921///
1922/// executable-directive:
1923/// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
1924/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
1925/// 'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
1926/// 'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
1927/// 'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
1928/// data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
1929/// 'master taskloop' | 'master taskloop simd' | 'parallel master
1930/// taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
1931/// enter data' | 'target exit data' | 'target parallel' | 'target
1932/// parallel for' | 'target update' | 'distribute parallel for' |
1933/// 'distribute paralle for simd' | 'distribute simd' | 'target parallel
1934/// for simd' | 'target simd' | 'teams distribute' | 'teams distribute
1935/// simd' | 'teams distribute parallel for simd' | 'teams distribute
1936/// parallel for' | 'target teams' | 'target teams distribute' | 'target
1937/// teams distribute parallel for' | 'target teams distribute parallel
1938/// for simd' | 'target teams distribute simd' {clause}
1939/// annot_pragma_openmp_end
1940///
1941StmtResult
1942Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
1943 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!")((Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"
) ? static_cast<void> (0) : __assert_fail ("Tok.is(tok::annot_pragma_openmp) && \"Not an OpenMP directive!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 1943, __PRETTY_FUNCTION__))
;
1944 ParsingOpenMPDirectiveRAII DirScope(*this);
1945 ParenBraceBracketBalancer BalancerRAIIObj(*this);
1946 SmallVector<OMPClause *, 5> Clauses;
1947 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
1948 FirstClauses(OMPC_unknown + 1);
1949 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
1950 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
1951 SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
1952 OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
1953 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
1954 // Name of critical directive.
1955 DeclarationNameInfo DirName;
1956 StmtResult Directive = StmtError();
1957 bool HasAssociatedStatement = true;
1958
1959 switch (DKind) {
1960 case OMPD_threadprivate: {
1961 // FIXME: Should this be permitted in C++?
1962 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1963 ParsedStmtContext()) {
1964 Diag(Tok, diag::err_omp_immediate_directive)
1965 << getOpenMPDirectiveName(DKind) << 0;
1966 }
1967 ConsumeToken();
1968 DeclDirectiveListParserHelper Helper(this, DKind);
1969 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1970 /*AllowScopeSpecifier=*/false)) {
1971 // The last seen token is annot_pragma_openmp_end - need to check for
1972 // extra tokens.
1973 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1974 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1975 << getOpenMPDirectiveName(DKind);
1976 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1977 }
1978 DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1979 Loc, Helper.getIdentifiers());
1980 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1981 }
1982 SkipUntil(tok::annot_pragma_openmp_end);
1983 break;
1984 }
1985 case OMPD_allocate: {
1986 // FIXME: Should this be permitted in C++?
1987 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1988 ParsedStmtContext()) {
1989 Diag(Tok, diag::err_omp_immediate_directive)
1990 << getOpenMPDirectiveName(DKind) << 0;
1991 }
1992 ConsumeToken();
1993 DeclDirectiveListParserHelper Helper(this, DKind);
1994 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1995 /*AllowScopeSpecifier=*/false)) {
1996 SmallVector<OMPClause *, 1> Clauses;
1997 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1998 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1999 OMPC_unknown + 1>
2000 FirstClauses(OMPC_unknown + 1);
2001 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2002 OpenMPClauseKind CKind =
2003 Tok.isAnnotation() ? OMPC_unknown
2004 : getOpenMPClauseKind(PP.getSpelling(Tok));
2005 Actions.StartOpenMPClause(CKind);
2006 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2007 !FirstClauses[CKind].getInt());
2008 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2009 StopBeforeMatch);
2010 FirstClauses[CKind].setInt(true);
2011 if (Clause != nullptr)
2012 Clauses.push_back(Clause);
2013 if (Tok.is(tok::annot_pragma_openmp_end)) {
2014 Actions.EndOpenMPClause();
2015 break;
2016 }
2017 // Skip ',' if any.
2018 if (Tok.is(tok::comma))
2019 ConsumeToken();
2020 Actions.EndOpenMPClause();
2021 }
2022 // The last seen token is annot_pragma_openmp_end - need to check for
2023 // extra tokens.
2024 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2025 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
2026 << getOpenMPDirectiveName(DKind);
2027 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
2028 }
2029 }
2030 DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2031 Loc, Helper.getIdentifiers(), Clauses);
2032 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2033 }
2034 SkipUntil(tok::annot_pragma_openmp_end);
2035 break;
2036 }
2037 case OMPD_declare_reduction:
2038 ConsumeToken();
2039 if (DeclGroupPtrTy Res =
2040 ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
2041 // The last seen token is annot_pragma_openmp_end - need to check for
2042 // extra tokens.
2043 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2044 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
2045 << getOpenMPDirectiveName(OMPD_declare_reduction);
2046 while (Tok.isNot(tok::annot_pragma_openmp_end))
2047 ConsumeAnyToken();
2048 }
2049 ConsumeAnyToken();
2050 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2051 } else {
2052 SkipUntil(tok::annot_pragma_openmp_end);
2053 }
2054 break;
2055 case OMPD_declare_mapper: {
2056 ConsumeToken();
2057 if (DeclGroupPtrTy Res =
2058 ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2059 // Skip the last annot_pragma_openmp_end.
2060 ConsumeAnnotationToken();
2061 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2062 } else {
2063 SkipUntil(tok::annot_pragma_openmp_end);
2064 }
2065 break;
2066 }
2067 case OMPD_flush:
2068 case OMPD_depobj:
2069 case OMPD_taskyield:
2070 case OMPD_barrier:
2071 case OMPD_taskwait:
2072 case OMPD_cancellation_point:
2073 case OMPD_cancel:
2074 case OMPD_target_enter_data:
2075 case OMPD_target_exit_data:
2076 case OMPD_target_update:
2077 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2078 ParsedStmtContext()) {
2079 Diag(Tok, diag::err_omp_immediate_directive)
2080 << getOpenMPDirectiveName(DKind) << 0;
2081 }
2082 HasAssociatedStatement = false;
2083 // Fall through for further analysis.
2084 LLVM_FALLTHROUGH[[gnu::fallthrough]];
2085 case OMPD_parallel:
2086 case OMPD_simd:
2087 case OMPD_for:
2088 case OMPD_for_simd:
2089 case OMPD_sections:
2090 case OMPD_single:
2091 case OMPD_section:
2092 case OMPD_master:
2093 case OMPD_critical:
2094 case OMPD_parallel_for:
2095 case OMPD_parallel_for_simd:
2096 case OMPD_parallel_sections:
2097 case OMPD_parallel_master:
2098 case OMPD_task:
2099 case OMPD_ordered:
2100 case OMPD_atomic:
2101 case OMPD_target:
2102 case OMPD_teams:
2103 case OMPD_taskgroup:
2104 case OMPD_target_data:
2105 case OMPD_target_parallel:
2106 case OMPD_target_parallel_for:
2107 case OMPD_taskloop:
2108 case OMPD_taskloop_simd:
2109 case OMPD_master_taskloop:
2110 case OMPD_master_taskloop_simd:
2111 case OMPD_parallel_master_taskloop:
2112 case OMPD_parallel_master_taskloop_simd:
2113 case OMPD_distribute:
2114 case OMPD_distribute_parallel_for:
2115 case OMPD_distribute_parallel_for_simd:
2116 case OMPD_distribute_simd:
2117 case OMPD_target_parallel_for_simd:
2118 case OMPD_target_simd:
2119 case OMPD_teams_distribute:
2120 case OMPD_teams_distribute_simd:
2121 case OMPD_teams_distribute_parallel_for_simd:
2122 case OMPD_teams_distribute_parallel_for:
2123 case OMPD_target_teams:
2124 case OMPD_target_teams_distribute:
2125 case OMPD_target_teams_distribute_parallel_for:
2126 case OMPD_target_teams_distribute_parallel_for_simd:
2127 case OMPD_target_teams_distribute_simd: {
2128 // Special processing for flush and depobj clauses.
2129 Token ImplicitTok;
2130 bool ImplicitClauseAllowed = false;
2131 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2132 ImplicitTok = Tok;
2133 ImplicitClauseAllowed = true;
2134 }
2135 ConsumeToken();
2136 // Parse directive name of the 'critical' directive if any.
2137 if (DKind == OMPD_critical) {
2138 BalancedDelimiterTracker T(*this, tok::l_paren,
2139 tok::annot_pragma_openmp_end);
2140 if (!T.consumeOpen()) {
2141 if (Tok.isAnyIdentifier()) {
2142 DirName =
2143 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2144 ConsumeAnyToken();
2145 } else {
2146 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2147 }
2148 T.consumeClose();
2149 }
2150 } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2151 CancelRegion = parseOpenMPDirectiveKind(*this);
2152 if (Tok.isNot(tok::annot_pragma_openmp_end))
2153 ConsumeToken();
2154 }
2155
2156 if (isOpenMPLoopDirective(DKind))
2157 ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2158 if (isOpenMPSimdDirective(DKind))
2159 ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2160 ParseScope OMPDirectiveScope(this, ScopeFlags);
2161 Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
2162
2163 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2164 bool HasImplicitClause = false;
2165 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2166 HasImplicitClause = true;
2167 // Push copy of the current token back to stream to properly parse
2168 // pseudo-clause OMPFlushClause or OMPDepobjClause.
2169 PP.EnterToken(Tok, /*IsReinject*/ true);
2170 PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
2171 ConsumeAnyToken();
2172 }
2173 OpenMPClauseKind CKind = Tok.isAnnotation()
2174 ? OMPC_unknown
2175 : getOpenMPClauseKind(PP.getSpelling(Tok));
2176 if (HasImplicitClause) {
2177 assert(CKind == OMPC_unknown && "Must be unknown implicit clause.")((CKind == OMPC_unknown && "Must be unknown implicit clause."
) ? static_cast<void> (0) : __assert_fail ("CKind == OMPC_unknown && \"Must be unknown implicit clause.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 2177, __PRETTY_FUNCTION__))
;
2178 if (DKind == OMPD_flush) {
2179 CKind = OMPC_flush;
2180 } else {
2181 assert(DKind == OMPD_depobj &&((DKind == OMPD_depobj && "Expected flush or depobj directives."
) ? static_cast<void> (0) : __assert_fail ("DKind == OMPD_depobj && \"Expected flush or depobj directives.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 2182, __PRETTY_FUNCTION__))
2182 "Expected flush or depobj directives.")((DKind == OMPD_depobj && "Expected flush or depobj directives."
) ? static_cast<void> (0) : __assert_fail ("DKind == OMPD_depobj && \"Expected flush or depobj directives.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 2182, __PRETTY_FUNCTION__))
;
2183 CKind = OMPC_depobj;
2184 }
2185 }
2186 // No more implicit clauses allowed.
2187 ImplicitClauseAllowed = false;
2188 Actions.StartOpenMPClause(CKind);
2189 HasImplicitClause = false;
Value stored to 'HasImplicitClause' is never read
2190 OMPClause *Clause =
2191 ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
2192 FirstClauses[CKind].setInt(true);
2193 if (Clause) {
2194 FirstClauses[CKind].setPointer(Clause);
2195 Clauses.push_back(Clause);
2196 }
2197
2198 // Skip ',' if any.
2199 if (Tok.is(tok::comma))
2200 ConsumeToken();
2201 Actions.EndOpenMPClause();
2202 }
2203 // End location of the directive.
2204 EndLoc = Tok.getLocation();
2205 // Consume final annot_pragma_openmp_end.
2206 ConsumeAnnotationToken();
2207
2208 // OpenMP [2.13.8, ordered Construct, Syntax]
2209 // If the depend clause is specified, the ordered construct is a stand-alone
2210 // directive.
2211 if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
2212 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2213 ParsedStmtContext()) {
2214 Diag(Loc, diag::err_omp_immediate_directive)
2215 << getOpenMPDirectiveName(DKind) << 1
2216 << getOpenMPClauseName(OMPC_depend);
2217 }
2218 HasAssociatedStatement = false;
2219 }
2220
2221 StmtResult AssociatedStmt;
2222 if (HasAssociatedStatement) {
2223 // The body is a block scope like in Lambdas and Blocks.
2224 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2225 // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2226 // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2227 // should have at least one compound statement scope within it.
2228 AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
2229 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2230 } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2231 DKind == OMPD_target_exit_data) {
2232 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2233 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2234 Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2235 /*isStmtExpr=*/false));
2236 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2237 }
2238 Directive = Actions.ActOnOpenMPExecutableDirective(
2239 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2240 EndLoc);
2241
2242 // Exit scope.
2243 Actions.EndOpenMPDSABlock(Directive.get());
2244 OMPDirectiveScope.Exit();
2245 break;
2246 }
2247 case OMPD_declare_simd:
2248 case OMPD_declare_target:
2249 case OMPD_end_declare_target:
2250 case OMPD_requires:
2251 case OMPD_declare_variant:
2252 Diag(Tok, diag::err_omp_unexpected_directive)
2253 << 1 << getOpenMPDirectiveName(DKind);
2254 SkipUntil(tok::annot_pragma_openmp_end);
2255 break;
2256 case OMPD_unknown:
2257 Diag(Tok, diag::err_omp_unknown_directive);
2258 SkipUntil(tok::annot_pragma_openmp_end);
2259 break;
2260 }
2261 return Directive;
2262}
2263
2264// Parses simple list:
2265// simple-variable-list:
2266// '(' id-expression {, id-expression} ')'
2267//
2268bool Parser::ParseOpenMPSimpleVarList(
2269 OpenMPDirectiveKind Kind,
2270 const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
2271 Callback,
2272 bool AllowScopeSpecifier) {
2273 // Parse '('.
2274 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2275 if (T.expectAndConsume(diag::err_expected_lparen_after,
2276 getOpenMPDirectiveName(Kind).data()))
2277 return true;
2278 bool IsCorrect = true;
2279 bool NoIdentIsFound = true;
2280
2281 // Read tokens while ')' or annot_pragma_openmp_end is not found.
2282 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2283 CXXScopeSpec SS;
2284 UnqualifiedId Name;
2285 // Read var name.
2286 Token PrevTok = Tok;
2287 NoIdentIsFound = false;
2288
2289 if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
2290 ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
2291 IsCorrect = false;
2292 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2293 StopBeforeMatch);
2294 } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
2295 nullptr, Name)) {
2296 IsCorrect = false;
2297 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2298 StopBeforeMatch);
2299 } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2300 Tok.isNot(tok::annot_pragma_openmp_end)) {
2301 IsCorrect = false;
2302 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2303 StopBeforeMatch);
2304 Diag(PrevTok.getLocation(), diag::err_expected)
2305 << tok::identifier
2306 << SourceRange(PrevTok.getLocation(), PrevTokLocation);
2307 } else {
2308 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2309 }
2310 // Consume ','.
2311 if (Tok.is(tok::comma)) {
2312 ConsumeToken();
2313 }
2314 }
2315
2316 if (NoIdentIsFound) {
2317 Diag(Tok, diag::err_expected) << tok::identifier;
2318 IsCorrect = false;
2319 }
2320
2321 // Parse ')'.
2322 IsCorrect = !T.consumeClose() && IsCorrect;
2323
2324 return !IsCorrect;
2325}
2326
2327/// Parsing of OpenMP clauses.
2328///
2329/// clause:
2330/// if-clause | final-clause | num_threads-clause | safelen-clause |
2331/// default-clause | private-clause | firstprivate-clause | shared-clause
2332/// | linear-clause | aligned-clause | collapse-clause |
2333/// lastprivate-clause | reduction-clause | proc_bind-clause |
2334/// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
2335/// mergeable-clause | flush-clause | read-clause | write-clause |
2336/// update-clause | capture-clause | seq_cst-clause | device-clause |
2337/// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
2338/// thread_limit-clause | priority-clause | grainsize-clause |
2339/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
2340/// from-clause | is_device_ptr-clause | task_reduction-clause |
2341/// in_reduction-clause | allocator-clause | allocate-clause |
2342/// acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
2343/// depobj-clause | destroy-clause
2344///
2345OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
2346 OpenMPClauseKind CKind, bool FirstClause) {
2347 OMPClause *Clause = nullptr;
2348 bool ErrorFound = false;
2349 bool WrongDirective = false;
2350 // Check if clause is allowed for the given directive.
2351 if (CKind != OMPC_unknown &&
2352 !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
2353 Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
2354 << getOpenMPDirectiveName(DKind);
2355 ErrorFound = true;
2356 WrongDirective = true;
2357 }
2358
2359 switch (CKind) {
2360 case OMPC_final:
2361 case OMPC_num_threads:
2362 case OMPC_safelen:
2363 case OMPC_simdlen:
2364 case OMPC_collapse:
2365 case OMPC_ordered:
2366 case OMPC_device:
2367 case OMPC_num_teams:
2368 case OMPC_thread_limit:
2369 case OMPC_priority:
2370 case OMPC_grainsize:
2371 case OMPC_num_tasks:
2372 case OMPC_hint:
2373 case OMPC_allocator:
2374 case OMPC_depobj:
2375 // OpenMP [2.5, Restrictions]
2376 // At most one num_threads clause can appear on the directive.
2377 // OpenMP [2.8.1, simd construct, Restrictions]
2378 // Only one safelen clause can appear on a simd directive.
2379 // Only one simdlen clause can appear on a simd directive.
2380 // Only one collapse clause can appear on a simd directive.
2381 // OpenMP [2.9.1, target data construct, Restrictions]
2382 // At most one device clause can appear on the directive.
2383 // OpenMP [2.11.1, task Construct, Restrictions]
2384 // At most one if clause can appear on the directive.
2385 // At most one final clause can appear on the directive.
2386 // OpenMP [teams Construct, Restrictions]
2387 // At most one num_teams clause can appear on the directive.
2388 // At most one thread_limit clause can appear on the directive.
2389 // OpenMP [2.9.1, task Construct, Restrictions]
2390 // At most one priority clause can appear on the directive.
2391 // OpenMP [2.9.2, taskloop Construct, Restrictions]
2392 // At most one grainsize clause can appear on the directive.
2393 // OpenMP [2.9.2, taskloop Construct, Restrictions]
2394 // At most one num_tasks clause can appear on the directive.
2395 // OpenMP [2.11.3, allocate Directive, Restrictions]
2396 // At most one allocator clause can appear on the directive.
2397 if (!FirstClause) {
2398 Diag(Tok, diag::err_omp_more_one_clause)
2399 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2400 ErrorFound = true;
2401 }
2402
2403 if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
2404 Clause = ParseOpenMPClause(CKind, WrongDirective);
2405 else
2406 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
2407 break;
2408 case OMPC_default:
2409 case OMPC_proc_bind:
2410 case OMPC_atomic_default_mem_order:
2411 case OMPC_order:
2412 // OpenMP [2.14.3.1, Restrictions]
2413 // Only a single default clause may be specified on a parallel, task or
2414 // teams directive.
2415 // OpenMP [2.5, parallel Construct, Restrictions]
2416 // At most one proc_bind clause can appear on the directive.
2417 // OpenMP [5.0, Requires directive, Restrictions]
2418 // At most one atomic_default_mem_order clause can appear
2419 // on the directive
2420 if (!FirstClause && CKind != OMPC_order) {
2421 Diag(Tok, diag::err_omp_more_one_clause)
2422 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2423 ErrorFound = true;
2424 }
2425
2426 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
2427 break;
2428 case OMPC_schedule:
2429 case OMPC_dist_schedule:
2430 case OMPC_defaultmap:
2431 // OpenMP [2.7.1, Restrictions, p. 3]
2432 // Only one schedule clause can appear on a loop directive.
2433 // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
2434 // At most one defaultmap clause can appear on the directive.
2435 if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
2436 !FirstClause) {
2437 Diag(Tok, diag::err_omp_more_one_clause)
2438 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2439 ErrorFound = true;
2440 }
2441 LLVM_FALLTHROUGH[[gnu::fallthrough]];
2442 case OMPC_if:
2443 Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
2444 break;
2445 case OMPC_nowait:
2446 case OMPC_untied:
2447 case OMPC_mergeable:
2448 case OMPC_read:
2449 case OMPC_write:
2450 case OMPC_capture:
2451 case OMPC_seq_cst:
2452 case OMPC_acq_rel:
2453 case OMPC_acquire:
2454 case OMPC_release:
2455 case OMPC_relaxed:
2456 case OMPC_threads:
2457 case OMPC_simd:
2458 case OMPC_nogroup:
2459 case OMPC_unified_address:
2460 case OMPC_unified_shared_memory:
2461 case OMPC_reverse_offload:
2462 case OMPC_dynamic_allocators:
2463 case OMPC_destroy:
2464 // OpenMP [2.7.1, Restrictions, p. 9]
2465 // Only one ordered clause can appear on a loop directive.
2466 // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
2467 // Only one nowait clause can appear on a for directive.
2468 // OpenMP [5.0, Requires directive, Restrictions]
2469 // Each of the requires clauses can appear at most once on the directive.
2470 if (!FirstClause) {
2471 Diag(Tok, diag::err_omp_more_one_clause)
2472 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2473 ErrorFound = true;
2474 }
2475
2476 Clause = ParseOpenMPClause(CKind, WrongDirective);
2477 break;
2478 case OMPC_update:
2479 if (!FirstClause) {
2480 Diag(Tok, diag::err_omp_more_one_clause)
2481 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2482 ErrorFound = true;
2483 }
2484
2485 Clause = (DKind == OMPD_depobj)
2486 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
2487 : ParseOpenMPClause(CKind, WrongDirective);
2488 break;
2489 case OMPC_private:
2490 case OMPC_firstprivate:
2491 case OMPC_lastprivate:
2492 case OMPC_shared:
2493 case OMPC_reduction:
2494 case OMPC_task_reduction:
2495 case OMPC_in_reduction:
2496 case OMPC_linear:
2497 case OMPC_aligned:
2498 case OMPC_copyin:
2499 case OMPC_copyprivate:
2500 case OMPC_flush:
2501 case OMPC_depend:
2502 case OMPC_map:
2503 case OMPC_to:
2504 case OMPC_from:
2505 case OMPC_use_device_ptr:
2506 case OMPC_is_device_ptr:
2507 case OMPC_allocate:
2508 case OMPC_nontemporal:
2509 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
2510 break;
2511 case OMPC_device_type:
2512 case OMPC_unknown:
2513 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
2514 << getOpenMPDirectiveName(DKind);
2515 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
2516 break;
2517 case OMPC_threadprivate:
2518 case OMPC_uniform:
2519 case OMPC_match:
2520 if (!WrongDirective)
2521 Diag(Tok, diag::err_omp_unexpected_clause)
2522 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
2523 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
2524 break;
2525 }
2526 return ErrorFound ? nullptr : Clause;
2527}
2528
2529/// Parses simple expression in parens for single-expression clauses of OpenMP
2530/// constructs.
2531/// \param RLoc Returned location of right paren.
2532ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
2533 SourceLocation &RLoc,
2534 bool IsAddressOfOperand) {
2535 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2536 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
2537 return ExprError();
2538
2539 SourceLocation ELoc = Tok.getLocation();
2540 ExprResult LHS(ParseCastExpression(AnyCastExpr, IsAddressOfOperand,
2541 NotTypeCast));
2542 ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
2543 Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
2544
2545 // Parse ')'.
2546 RLoc = Tok.getLocation();
2547 if (!T.consumeClose())
2548 RLoc = T.getCloseLocation();
2549
2550 return Val;
2551}
2552
2553/// Parsing of OpenMP clauses with single expressions like 'final',
2554/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
2555/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
2556///
2557/// final-clause:
2558/// 'final' '(' expression ')'
2559///
2560/// num_threads-clause:
2561/// 'num_threads' '(' expression ')'
2562///
2563/// safelen-clause:
2564/// 'safelen' '(' expression ')'
2565///
2566/// simdlen-clause:
2567/// 'simdlen' '(' expression ')'
2568///
2569/// collapse-clause:
2570/// 'collapse' '(' expression ')'
2571///
2572/// priority-clause:
2573/// 'priority' '(' expression ')'
2574///
2575/// grainsize-clause:
2576/// 'grainsize' '(' expression ')'
2577///
2578/// num_tasks-clause:
2579/// 'num_tasks' '(' expression ')'
2580///
2581/// hint-clause:
2582/// 'hint' '(' expression ')'
2583///
2584/// allocator-clause:
2585/// 'allocator' '(' expression ')'
2586///
2587OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
2588 bool ParseOnly) {
2589 SourceLocation Loc = ConsumeToken();
2590 SourceLocation LLoc = Tok.getLocation();
2591 SourceLocation RLoc;
2592
2593 ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
2594
2595 if (Val.isInvalid())
2596 return nullptr;
2597
2598 if (ParseOnly)
2599 return nullptr;
2600 return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
2601}
2602
2603/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
2604///
2605/// default-clause:
2606/// 'default' '(' 'none' | 'shared' ')'
2607///
2608/// proc_bind-clause:
2609/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')'
2610///
2611/// update-clause:
2612/// 'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
2613///
2614OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
2615 bool ParseOnly) {
2616 llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
2617 if (!Val || ParseOnly)
2618 return nullptr;
2619 return Actions.ActOnOpenMPSimpleClause(
2620 Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
2621 Val.getValue().Loc, Val.getValue().RLoc);
2622}
2623
2624/// Parsing of OpenMP clauses like 'ordered'.
2625///
2626/// ordered-clause:
2627/// 'ordered'
2628///
2629/// nowait-clause:
2630/// 'nowait'
2631///
2632/// untied-clause:
2633/// 'untied'
2634///
2635/// mergeable-clause:
2636/// 'mergeable'
2637///
2638/// read-clause:
2639/// 'read'
2640///
2641/// threads-clause:
2642/// 'threads'
2643///
2644/// simd-clause:
2645/// 'simd'
2646///
2647/// nogroup-clause:
2648/// 'nogroup'
2649///
2650OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
2651 SourceLocation Loc = Tok.getLocation();
2652 ConsumeAnyToken();
2653
2654 if (ParseOnly)
2655 return nullptr;
2656 return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
2657}
2658
2659
2660/// Parsing of OpenMP clauses with single expressions and some additional
2661/// argument like 'schedule' or 'dist_schedule'.
2662///
2663/// schedule-clause:
2664/// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
2665/// ')'
2666///
2667/// if-clause:
2668/// 'if' '(' [ directive-name-modifier ':' ] expression ')'
2669///
2670/// defaultmap:
2671/// 'defaultmap' '(' modifier ':' kind ')'
2672///
2673OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
2674 bool ParseOnly) {
2675 SourceLocation Loc = ConsumeToken();
2676 SourceLocation DelimLoc;
2677 // Parse '('.
2678 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2679 if (T.expectAndConsume(diag::err_expected_lparen_after,
2680 getOpenMPClauseName(Kind)))
2681 return nullptr;
2682
2683 ExprResult Val;
2684 SmallVector<unsigned, 4> Arg;
2685 SmallVector<SourceLocation, 4> KLoc;
2686 if (Kind == OMPC_schedule) {
2687 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
2688 Arg.resize(NumberOfElements);
2689 KLoc.resize(NumberOfElements);
2690 Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
2691 Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
2692 Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
2693 unsigned KindModifier = getOpenMPSimpleClauseType(
2694 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2695 if (KindModifier > OMPC_SCHEDULE_unknown) {
2696 // Parse 'modifier'
2697 Arg[Modifier1] = KindModifier;
2698 KLoc[Modifier1] = Tok.getLocation();
2699 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2700 Tok.isNot(tok::annot_pragma_openmp_end))
2701 ConsumeAnyToken();
2702 if (Tok.is(tok::comma)) {
2703 // Parse ',' 'modifier'
2704 ConsumeAnyToken();
2705 KindModifier = getOpenMPSimpleClauseType(
2706 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2707 Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
2708 ? KindModifier
2709 : (unsigned)OMPC_SCHEDULE_unknown;
2710 KLoc[Modifier2] = Tok.getLocation();
2711 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2712 Tok.isNot(tok::annot_pragma_openmp_end))
2713 ConsumeAnyToken();
2714 }
2715 // Parse ':'
2716 if (Tok.is(tok::colon))
2717 ConsumeAnyToken();
2718 else
2719 Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
2720 KindModifier = getOpenMPSimpleClauseType(
2721 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2722 }
2723 Arg[ScheduleKind] = KindModifier;
2724 KLoc[ScheduleKind] = Tok.getLocation();
2725 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2726 Tok.isNot(tok::annot_pragma_openmp_end))
2727 ConsumeAnyToken();
2728 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
2729 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
2730 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
2731 Tok.is(tok::comma))
2732 DelimLoc = ConsumeAnyToken();
2733 } else if (Kind == OMPC_dist_schedule) {
2734 Arg.push_back(getOpenMPSimpleClauseType(
2735 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
2736 KLoc.push_back(Tok.getLocation());
2737 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2738 Tok.isNot(tok::annot_pragma_openmp_end))
2739 ConsumeAnyToken();
2740 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
2741 DelimLoc = ConsumeAnyToken();
2742 } else if (Kind == OMPC_defaultmap) {
2743 // Get a defaultmap modifier
2744 unsigned Modifier = getOpenMPSimpleClauseType(
2745 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2746 // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
2747 // pointer
2748 if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
2749 Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
2750 Arg.push_back(Modifier);
2751 KLoc.push_back(Tok.getLocation());
2752 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2753 Tok.isNot(tok::annot_pragma_openmp_end))
2754 ConsumeAnyToken();
2755 // Parse ':'
2756 if (Tok.is(tok::colon))
2757 ConsumeAnyToken();
2758 else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
2759 Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
2760 // Get a defaultmap kind
2761 Arg.push_back(getOpenMPSimpleClauseType(
2762 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
2763 KLoc.push_back(Tok.getLocation());
2764 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2765 Tok.isNot(tok::annot_pragma_openmp_end))
2766 ConsumeAnyToken();
2767 } else {
2768 assert(Kind == OMPC_if)((Kind == OMPC_if) ? static_cast<void> (0) : __assert_fail
("Kind == OMPC_if", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 2768, __PRETTY_FUNCTION__))
;
2769 KLoc.push_back(Tok.getLocation());
2770 TentativeParsingAction TPA(*this);
2771 auto DK = parseOpenMPDirectiveKind(*this);
2772 Arg.push_back(DK);
2773 if (DK != OMPD_unknown) {
2774 ConsumeToken();
2775 if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
2776 TPA.Commit();
2777 DelimLoc = ConsumeToken();
2778 } else {
2779 TPA.Revert();
2780 Arg.back() = unsigned(OMPD_unknown);
2781 }
2782 } else {
2783 TPA.Revert();
2784 }
2785 }
2786
2787 bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
2788 (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
2789 Kind == OMPC_if;
2790 if (NeedAnExpression) {
2791 SourceLocation ELoc = Tok.getLocation();
2792 ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
2793 Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
2794 Val =
2795 Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
2796 }
2797
2798 // Parse ')'.
2799 SourceLocation RLoc = Tok.getLocation();
2800 if (!T.consumeClose())
2801 RLoc = T.getCloseLocation();
2802
2803 if (NeedAnExpression && Val.isInvalid())
2804 return nullptr;
2805
2806 if (ParseOnly)
2807 return nullptr;
2808 return Actions.ActOnOpenMPSingleExprWithArgClause(
2809 Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
2810}
2811
2812static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
2813 UnqualifiedId &ReductionId) {
2814 if (ReductionIdScopeSpec.isEmpty()) {
2815 auto OOK = OO_None;
2816 switch (P.getCurToken().getKind()) {
2817 case tok::plus:
2818 OOK = OO_Plus;
2819 break;
2820 case tok::minus:
2821 OOK = OO_Minus;
2822 break;
2823 case tok::star:
2824 OOK = OO_Star;
2825 break;
2826 case tok::amp:
2827 OOK = OO_Amp;
2828 break;
2829 case tok::pipe:
2830 OOK = OO_Pipe;
2831 break;
2832 case tok::caret:
2833 OOK = OO_Caret;
2834 break;
2835 case tok::ampamp:
2836 OOK = OO_AmpAmp;
2837 break;
2838 case tok::pipepipe:
2839 OOK = OO_PipePipe;
2840 break;
2841 default:
2842 break;
2843 }
2844 if (OOK != OO_None) {
2845 SourceLocation OpLoc = P.ConsumeToken();
2846 SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
2847 ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
2848 return false;
2849 }
2850 }
2851 return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
2852 /*AllowDestructorName*/ false,
2853 /*AllowConstructorName*/ false,
2854 /*AllowDeductionGuide*/ false,
2855 nullptr, nullptr, ReductionId);
2856}
2857
2858/// Checks if the token is a valid map-type-modifier.
2859static OpenMPMapModifierKind isMapModifier(Parser &P) {
2860 Token Tok = P.getCurToken();
2861 if (!Tok.is(tok::identifier))
2862 return OMPC_MAP_MODIFIER_unknown;
2863
2864 Preprocessor &PP = P.getPreprocessor();
2865 OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
2866 getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2867 return TypeModifier;
2868}
2869
2870/// Parse the mapper modifier in map, to, and from clauses.
2871bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
2872 // Parse '('.
2873 BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
2874 if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
2875 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2876 StopBeforeMatch);
2877 return true;
2878 }
2879 // Parse mapper-identifier
2880 if (getLangOpts().CPlusPlus)
2881 ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2882 /*ObjectType=*/nullptr,
2883 /*EnteringContext=*/false);
2884 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
2885 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2886 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2887 StopBeforeMatch);
2888 return true;
2889 }
2890 auto &DeclNames = Actions.getASTContext().DeclarationNames;
2891 Data.ReductionOrMapperId = DeclarationNameInfo(
2892 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
2893 ConsumeToken();
2894 // Parse ')'.
2895 return T.consumeClose();
2896}
2897
2898/// Parse map-type-modifiers in map clause.
2899/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2900/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
2901bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
2902 while (getCurToken().isNot(tok::colon)) {
2903 OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
2904 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2905 TypeModifier == OMPC_MAP_MODIFIER_close) {
2906 Data.MapTypeModifiers.push_back(TypeModifier);
2907 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2908 ConsumeToken();
2909 } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2910 Data.MapTypeModifiers.push_back(TypeModifier);
2911 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2912 ConsumeToken();
2913 if (parseMapperModifier(Data))
2914 return true;
2915 } else {
2916 // For the case of unknown map-type-modifier or a map-type.
2917 // Map-type is followed by a colon; the function returns when it
2918 // encounters a token followed by a colon.
2919 if (Tok.is(tok::comma)) {
2920 Diag(Tok, diag::err_omp_map_type_modifier_missing);
2921 ConsumeToken();
2922 continue;
2923 }
2924 // Potential map-type token as it is followed by a colon.
2925 if (PP.LookAhead(0).is(tok::colon))
2926 return false;
2927 Diag(Tok, diag::err_omp_unknown_map_type_modifier);
2928 ConsumeToken();
2929 }
2930 if (getCurToken().is(tok::comma))
2931 ConsumeToken();
2932 }
2933 return false;
2934}
2935
2936/// Checks if the token is a valid map-type.
2937static OpenMPMapClauseKind isMapType(Parser &P) {
2938 Token Tok = P.getCurToken();
2939 // The map-type token can be either an identifier or the C++ delete keyword.
2940 if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
2941 return OMPC_MAP_unknown;
2942 Preprocessor &PP = P.getPreprocessor();
2943 OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
2944 getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2945 return MapType;
2946}
2947
2948/// Parse map-type in map clause.
2949/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2950/// where, map-type ::= to | from | tofrom | alloc | release | delete
2951static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
2952 Token Tok = P.getCurToken();
2953 if (Tok.is(tok::colon)) {
2954 P.Diag(Tok, diag::err_omp_map_type_missing);
2955 return;
2956 }
2957 Data.ExtraModifier = isMapType(P);
2958 if (Data.ExtraModifier == OMPC_MAP_unknown)
2959 P.Diag(Tok, diag::err_omp_unknown_map_type);
2960 P.ConsumeToken();
2961}
2962
2963/// Parses clauses with list.
2964bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
2965 OpenMPClauseKind Kind,
2966 SmallVectorImpl<Expr *> &Vars,
2967 OpenMPVarListDataTy &Data) {
2968 UnqualifiedId UnqualifiedReductionId;
2969 bool InvalidReductionId = false;
2970 bool IsInvalidMapperModifier = false;
2971
2972 // Parse '('.
2973 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2974 if (T.expectAndConsume(diag::err_expected_lparen_after,
2975 getOpenMPClauseName(Kind)))
2976 return true;
2977
2978 bool NeedRParenForLinear = false;
2979 BalancedDelimiterTracker LinearT(*this, tok::l_paren,
2980 tok::annot_pragma_openmp_end);
2981 // Handle reduction-identifier for reduction clause.
2982 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
2983 Kind == OMPC_in_reduction) {
2984 ColonProtectionRAIIObject ColonRAII(*this);
2985 if (getLangOpts().CPlusPlus)
2986 ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2987 /*ObjectType=*/nullptr,
2988 /*EnteringContext=*/false);
2989 InvalidReductionId = ParseReductionId(
2990 *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
2991 if (InvalidReductionId) {
2992 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2993 StopBeforeMatch);
2994 }
2995 if (Tok.is(tok::colon))
2996 Data.ColonLoc = ConsumeToken();
2997 else
2998 Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
2999 if (!InvalidReductionId)
3000 Data.ReductionOrMapperId =
3001 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
3002 } else if (Kind == OMPC_depend) {
3003 // Handle dependency type for depend clause.
3004 ColonProtectionRAIIObject ColonRAII(*this);
3005 Data.ExtraModifier = getOpenMPSimpleClauseType(
3006 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "");
3007 Data.DepLinMapLastLoc = Tok.getLocation();
3008 if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
3009 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3010 StopBeforeMatch);
3011 } else {
3012 ConsumeToken();
3013 // Special processing for depend(source) clause.
3014 if (DKind == OMPD_ordered && Data.ExtraModifier == OMPC_DEPEND_source) {
3015 // Parse ')'.
3016 T.consumeClose();
3017 return false;
3018 }
3019 }
3020 if (Tok.is(tok::colon)) {
3021 Data.ColonLoc = ConsumeToken();
3022 } else {
3023 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
3024 : diag::warn_pragma_expected_colon)
3025 << "dependency type";
3026 }
3027 } else if (Kind == OMPC_linear) {
3028 // Try to parse modifier if any.
3029 Data.ExtraModifier = OMPC_LINEAR_val;
3030 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
3031 Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
3032 Data.DepLinMapLastLoc = ConsumeToken();
3033 LinearT.consumeOpen();
3034 NeedRParenForLinear = true;
3035 }
3036 } else if (Kind == OMPC_lastprivate) {
3037 // Try to parse modifier if any.
3038 Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
3039 // Conditional modifier allowed only in OpenMP 5.0 and not supported in
3040 // distribute and taskloop based directives.
3041 if ((getLangOpts().OpenMP >= 50 && !isOpenMPDistributeDirective(DKind) &&
3042 !isOpenMPTaskLoopDirective(DKind)) &&
3043 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
3044 Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
3045 Data.DepLinMapLastLoc = Tok.getLocation();
3046 if (Data.ExtraModifier == OMPC_LASTPRIVATE_unknown) {
3047 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3048 StopBeforeMatch);
3049 } else {
3050 ConsumeToken();
3051 }
3052 assert(Tok.is(tok::colon) && "Expected colon.")((Tok.is(tok::colon) && "Expected colon.") ? static_cast
<void> (0) : __assert_fail ("Tok.is(tok::colon) && \"Expected colon.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Parse/ParseOpenMP.cpp"
, 3052, __PRETTY_FUNCTION__))
;
3053 Data.ColonLoc = ConsumeToken();
3054 }
3055 } else if (Kind == OMPC_map) {
3056 // Handle map type for map clause.
3057 ColonProtectionRAIIObject ColonRAII(*this);
3058
3059 // The first identifier may be a list item, a map-type or a
3060 // map-type-modifier. The map-type can also be delete which has the same
3061 // spelling of the C++ delete keyword.
3062 Data.ExtraModifier = OMPC_MAP_unknown;
3063 Data.DepLinMapLastLoc = Tok.getLocation();
3064
3065 // Check for presence of a colon in the map clause.
3066 TentativeParsingAction TPA(*this);
3067 bool ColonPresent = false;
3068 if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3069 StopBeforeMatch)) {
3070 if (Tok.is(tok::colon))
3071 ColonPresent = true;
3072 }
3073 TPA.Revert();
3074 // Only parse map-type-modifier[s] and map-type if a colon is present in
3075 // the map clause.
3076 if (ColonPresent) {
3077 IsInvalidMapperModifier = parseMapTypeModifiers(Data);
3078 if (!IsInvalidMapperModifier)
3079 parseMapType(*this, Data);
3080 else
3081 SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
3082 }
3083 if (Data.ExtraModifier == OMPC_MAP_unknown) {
3084 Data.ExtraModifier = OMPC_MAP_tofrom;
3085 Data.IsMapTypeImplicit = true;
3086 }
3087
3088 if (Tok.is(tok::colon))
3089 Data.ColonLoc = ConsumeToken();
3090 } else if (Kind == OMPC_to || Kind == OMPC_from) {
3091 if (Tok.is(tok::identifier)) {
3092 bool IsMapperModifier = false;
3093 if (Kind == OMPC_to) {
3094 auto Modifier = static_cast<OpenMPToModifierKind>(
3095 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
3096 if (Modifier == OMPC_TO_MODIFIER_mapper)
3097 IsMapperModifier = true;
3098 } else {
3099 auto Modifier = static_cast<OpenMPFromModifierKind>(
3100 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
3101 if (Modifier == OMPC_FROM_MODIFIER_mapper)
3102 IsMapperModifier = true;
3103 }
3104 if (IsMapperModifier) {
3105 // Parse the mapper modifier.
3106 ConsumeToken();
3107 IsInvalidMapperModifier = parseMapperModifier(Data);
3108 if (Tok.isNot(tok::colon)) {
3109 if (!IsInvalidMapperModifier)
3110 Diag(Tok, diag::warn_pragma_expected_colon) << ")";
3111 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3112 StopBeforeMatch);
3113 }
3114 // Consume ':'.
3115 if (Tok.is(tok::colon))
3116 ConsumeToken();
3117 }
3118 }
3119 } else if (Kind == OMPC_allocate) {
3120 // Handle optional allocator expression followed by colon delimiter.
3121 ColonProtectionRAIIObject ColonRAII(*this);
3122 TentativeParsingAction TPA(*this);
3123 ExprResult Tail =
3124 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3125 Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
3126 /*DiscardedValue=*/false);
3127 if (Tail.isUsable()) {
3128 if (Tok.is(tok::colon)) {
3129 Data.TailExpr = Tail.get();
3130 Data.ColonLoc = ConsumeToken();
3131 TPA.Commit();
3132 } else {
3133 // colon not found, no allocator specified, parse only list of
3134 // variables.
3135 TPA.Revert();
3136 }
3137 } else {
3138 // Parsing was unsuccessfull, revert and skip to the end of clause or
3139 // directive.
3140 TPA.Revert();
3141 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3142 StopBeforeMatch);
3143 }
3144 }
3145
3146 bool IsComma =
3147 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
3148 Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
3149 (Kind == OMPC_reduction && !InvalidReductionId) ||
3150 (Kind == OMPC_map && Data.ExtraModifier != OMPC_MAP_unknown) ||
3151 (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown);
3152 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
3153 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
3154 Tok.isNot(tok::annot_pragma_openmp_end))) {
3155 ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
3156 // Parse variable
3157 ExprResult VarExpr =
3158 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3159 if (VarExpr.isUsable()) {
3160 Vars.push_back(VarExpr.get());
3161 } else {
3162 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3163 StopBeforeMatch);
3164 }
3165 // Skip ',' if any
3166 IsComma = Tok.is(tok::comma);
3167 if (IsComma)
3168 ConsumeToken();
3169 else if (Tok.isNot(tok::r_paren) &&
3170 Tok.isNot(tok::annot_pragma_openmp_end) &&
3171 (!MayHaveTail || Tok.isNot(tok::colon)))
3172 Diag(Tok, diag::err_omp_expected_punc)
3173 << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
3174 : getOpenMPClauseName(Kind))
3175 << (Kind == OMPC_flush);
3176 }
3177
3178 // Parse ')' for linear clause with modifier.
3179 if (NeedRParenForLinear)
3180 LinearT.consumeClose();
3181
3182 // Parse ':' linear-step (or ':' alignment).
3183 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
3184 if (MustHaveTail) {
3185 Data.ColonLoc = Tok.getLocation();
3186 SourceLocation ELoc = ConsumeToken();
3187 ExprResult Tail = ParseAssignmentExpression();
3188 Tail =
3189 Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
3190 if (Tail.isUsable())
3191 Data.TailExpr = Tail.get();
3192 else
3193 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3194 StopBeforeMatch);
3195 }
3196
3197 // Parse ')'.
3198 Data.RLoc = Tok.getLocation();
3199 if (!T.consumeClose())
3200 Data.RLoc = T.getCloseLocation();
3201 return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
3202 (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
3203 IsInvalidMapperModifier;
3204}
3205
3206/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
3207/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
3208/// 'in_reduction'.
3209///
3210/// private-clause:
3211/// 'private' '(' list ')'
3212/// firstprivate-clause:
3213/// 'firstprivate' '(' list ')'
3214/// lastprivate-clause:
3215/// 'lastprivate' '(' list ')'
3216/// shared-clause:
3217/// 'shared' '(' list ')'
3218/// linear-clause:
3219/// 'linear' '(' linear-list [ ':' linear-step ] ')'
3220/// aligned-clause:
3221/// 'aligned' '(' list [ ':' alignment ] ')'
3222/// reduction-clause:
3223/// 'reduction' '(' reduction-identifier ':' list ')'
3224/// task_reduction-clause:
3225/// 'task_reduction' '(' reduction-identifier ':' list ')'
3226/// in_reduction-clause:
3227/// 'in_reduction' '(' reduction-identifier ':' list ')'
3228/// copyprivate-clause:
3229/// 'copyprivate' '(' list ')'
3230/// flush-clause:
3231/// 'flush' '(' list ')'
3232/// depend-clause:
3233/// 'depend' '(' in | out | inout : list | source ')'
3234/// map-clause:
3235/// 'map' '(' [ [ always [,] ] [ close [,] ]
3236/// [ mapper '(' mapper-identifier ')' [,] ]
3237/// to | from | tofrom | alloc | release | delete ':' ] list ')';
3238/// to-clause:
3239/// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
3240/// from-clause:
3241/// 'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
3242/// use_device_ptr-clause:
3243/// 'use_device_ptr' '(' list ')'
3244/// is_device_ptr-clause:
3245/// 'is_device_ptr' '(' list ')'
3246/// allocate-clause:
3247/// 'allocate' '(' [ allocator ':' ] list ')'
3248///
3249/// For 'linear' clause linear-list may have the following forms:
3250/// list
3251/// modifier(list)
3252/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
3253OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
3254 OpenMPClauseKind Kind,
3255 bool ParseOnly) {
3256 SourceLocation Loc = Tok.getLocation();
3257 SourceLocation LOpen = ConsumeToken();
3258 SmallVector<Expr *, 4> Vars;
3259 OpenMPVarListDataTy Data;
3260
3261 if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
3262 return nullptr;
3263
3264 if (ParseOnly)
3265 return nullptr;
3266 OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
3267 return Actions.ActOnOpenMPVarListClause(
3268 Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
3269 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
3270 Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
3271 Data.IsMapTypeImplicit, Data.DepLinMapLastLoc);
3272}
3273