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/OpenMPClause.h"
15 #include "clang/AST/StmtOpenMP.h"
16 #include "clang/Basic/OpenMPKinds.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Basic/TokenKinds.h"
19 #include "clang/Parse/ParseDiagnostic.h"
20 #include "clang/Parse/Parser.h"
21 #include "clang/Parse/RAIIObjectsForParser.h"
22 #include "clang/Sema/Scope.h"
23 #include "llvm/ADT/PointerIntPair.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/ADT/UniqueVector.h"
26 #include "llvm/Frontend/OpenMP/OMPContext.h"
27 
28 using namespace clang;
29 using namespace llvm::omp;
30 
31 //===----------------------------------------------------------------------===//
32 // OpenMP declarative directives.
33 //===----------------------------------------------------------------------===//
34 
35 namespace {
36 enum OpenMPDirectiveKindEx {
37   OMPD_cancellation = llvm::omp::Directive_enumSize + 1,
38   OMPD_data,
39   OMPD_declare,
40   OMPD_end,
41   OMPD_end_declare,
42   OMPD_enter,
43   OMPD_exit,
44   OMPD_point,
45   OMPD_reduction,
46   OMPD_target_enter,
47   OMPD_target_exit,
48   OMPD_update,
49   OMPD_distribute_parallel,
50   OMPD_teams_distribute_parallel,
51   OMPD_target_teams_distribute_parallel,
52   OMPD_mapper,
53   OMPD_variant,
54   OMPD_begin,
55   OMPD_begin_declare,
56 };
57 
58 // Helper to unify the enum class OpenMPDirectiveKind with its extension
59 // the OpenMPDirectiveKindEx enum which allows to use them together as if they
60 // are unsigned values.
61 struct OpenMPDirectiveKindExWrapper {
OpenMPDirectiveKindExWrapper__anon831cac940111::OpenMPDirectiveKindExWrapper62   OpenMPDirectiveKindExWrapper(unsigned Value) : Value(Value) {}
OpenMPDirectiveKindExWrapper__anon831cac940111::OpenMPDirectiveKindExWrapper63   OpenMPDirectiveKindExWrapper(OpenMPDirectiveKind DK) : Value(unsigned(DK)) {}
operator ==__anon831cac940111::OpenMPDirectiveKindExWrapper64   bool operator==(OpenMPDirectiveKindExWrapper V) const {
65     return Value == V.Value;
66   }
operator !=__anon831cac940111::OpenMPDirectiveKindExWrapper67   bool operator!=(OpenMPDirectiveKindExWrapper V) const {
68     return Value != V.Value;
69   }
operator ==__anon831cac940111::OpenMPDirectiveKindExWrapper70   bool operator==(OpenMPDirectiveKind V) const { return Value == unsigned(V); }
operator !=__anon831cac940111::OpenMPDirectiveKindExWrapper71   bool operator!=(OpenMPDirectiveKind V) const { return Value != unsigned(V); }
operator <__anon831cac940111::OpenMPDirectiveKindExWrapper72   bool operator<(OpenMPDirectiveKind V) const { return Value < unsigned(V); }
operator unsigned__anon831cac940111::OpenMPDirectiveKindExWrapper73   operator unsigned() const { return Value; }
operator OpenMPDirectiveKind__anon831cac940111::OpenMPDirectiveKindExWrapper74   operator OpenMPDirectiveKind() const { return OpenMPDirectiveKind(Value); }
75   unsigned Value;
76 };
77 
78 class DeclDirectiveListParserHelper final {
79   SmallVector<Expr *, 4> Identifiers;
80   Parser *P;
81   OpenMPDirectiveKind Kind;
82 
83 public:
DeclDirectiveListParserHelper(Parser * P,OpenMPDirectiveKind Kind)84   DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
85       : P(P), Kind(Kind) {}
operator ()(CXXScopeSpec & SS,DeclarationNameInfo NameInfo)86   void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
87     ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
88         P->getCurScope(), SS, NameInfo, Kind);
89     if (Res.isUsable())
90       Identifiers.push_back(Res.get());
91   }
getIdentifiers() const92   llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
93 };
94 } // namespace
95 
96 // Map token string to extended OMP token kind that are
97 // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
getOpenMPDirectiveKindEx(StringRef S)98 static unsigned getOpenMPDirectiveKindEx(StringRef S) {
99   OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
100   if (DKind != OMPD_unknown)
101     return DKind;
102 
103   return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
104       .Case("cancellation", OMPD_cancellation)
105       .Case("data", OMPD_data)
106       .Case("declare", OMPD_declare)
107       .Case("end", OMPD_end)
108       .Case("enter", OMPD_enter)
109       .Case("exit", OMPD_exit)
110       .Case("point", OMPD_point)
111       .Case("reduction", OMPD_reduction)
112       .Case("update", OMPD_update)
113       .Case("mapper", OMPD_mapper)
114       .Case("variant", OMPD_variant)
115       .Case("begin", OMPD_begin)
116       .Default(OMPD_unknown);
117 }
118 
parseOpenMPDirectiveKind(Parser & P)119 static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
120   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
121   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
122   // TODO: add other combined directives in topological order.
123   static const OpenMPDirectiveKindExWrapper F[][3] = {
124       {OMPD_begin, OMPD_declare, OMPD_begin_declare},
125       {OMPD_begin, OMPD_assumes, OMPD_begin_assumes},
126       {OMPD_end, OMPD_declare, OMPD_end_declare},
127       {OMPD_end, OMPD_assumes, OMPD_end_assumes},
128       {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
129       {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
130       {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
131       {OMPD_declare, OMPD_simd, OMPD_declare_simd},
132       {OMPD_declare, OMPD_target, OMPD_declare_target},
133       {OMPD_declare, OMPD_variant, OMPD_declare_variant},
134       {OMPD_begin_declare, OMPD_target, OMPD_begin_declare_target},
135       {OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},
136       {OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},
137       {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
138       {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
139       {OMPD_distribute_parallel_for, OMPD_simd,
140        OMPD_distribute_parallel_for_simd},
141       {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
142       {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
143       {OMPD_target, OMPD_data, OMPD_target_data},
144       {OMPD_target, OMPD_enter, OMPD_target_enter},
145       {OMPD_target, OMPD_exit, OMPD_target_exit},
146       {OMPD_target, OMPD_update, OMPD_target_update},
147       {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
148       {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
149       {OMPD_for, OMPD_simd, OMPD_for_simd},
150       {OMPD_parallel, OMPD_for, OMPD_parallel_for},
151       {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
152       {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
153       {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
154       {OMPD_target, OMPD_parallel, OMPD_target_parallel},
155       {OMPD_target, OMPD_simd, OMPD_target_simd},
156       {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
157       {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
158       {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
159       {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
160       {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
161       {OMPD_teams_distribute_parallel, OMPD_for,
162        OMPD_teams_distribute_parallel_for},
163       {OMPD_teams_distribute_parallel_for, OMPD_simd,
164        OMPD_teams_distribute_parallel_for_simd},
165       {OMPD_target, OMPD_teams, OMPD_target_teams},
166       {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
167       {OMPD_target_teams_distribute, OMPD_parallel,
168        OMPD_target_teams_distribute_parallel},
169       {OMPD_target_teams_distribute, OMPD_simd,
170        OMPD_target_teams_distribute_simd},
171       {OMPD_target_teams_distribute_parallel, OMPD_for,
172        OMPD_target_teams_distribute_parallel_for},
173       {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
174        OMPD_target_teams_distribute_parallel_for_simd},
175       {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
176       {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
177       {OMPD_parallel, OMPD_master, OMPD_parallel_master},
178       {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
179       {OMPD_parallel_master_taskloop, OMPD_simd,
180        OMPD_parallel_master_taskloop_simd}};
181   enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
182   Token Tok = P.getCurToken();
183   OpenMPDirectiveKindExWrapper DKind =
184       Tok.isAnnotation()
185           ? static_cast<unsigned>(OMPD_unknown)
186           : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
187   if (DKind == OMPD_unknown)
188     return OMPD_unknown;
189 
190   for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
191     if (DKind != F[I][0])
192       continue;
193 
194     Tok = P.getPreprocessor().LookAhead(0);
195     OpenMPDirectiveKindExWrapper SDKind =
196         Tok.isAnnotation()
197             ? static_cast<unsigned>(OMPD_unknown)
198             : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
199     if (SDKind == OMPD_unknown)
200       continue;
201 
202     if (SDKind == F[I][1]) {
203       P.ConsumeToken();
204       DKind = F[I][2];
205     }
206   }
207   return unsigned(DKind) < llvm::omp::Directive_enumSize
208              ? static_cast<OpenMPDirectiveKind>(DKind)
209              : OMPD_unknown;
210 }
211 
parseOpenMPReductionId(Parser & P)212 static DeclarationName parseOpenMPReductionId(Parser &P) {
213   Token Tok = P.getCurToken();
214   Sema &Actions = P.getActions();
215   OverloadedOperatorKind OOK = OO_None;
216   // Allow to use 'operator' keyword for C++ operators
217   bool WithOperator = false;
218   if (Tok.is(tok::kw_operator)) {
219     P.ConsumeToken();
220     Tok = P.getCurToken();
221     WithOperator = true;
222   }
223   switch (Tok.getKind()) {
224   case tok::plus: // '+'
225     OOK = OO_Plus;
226     break;
227   case tok::minus: // '-'
228     OOK = OO_Minus;
229     break;
230   case tok::star: // '*'
231     OOK = OO_Star;
232     break;
233   case tok::amp: // '&'
234     OOK = OO_Amp;
235     break;
236   case tok::pipe: // '|'
237     OOK = OO_Pipe;
238     break;
239   case tok::caret: // '^'
240     OOK = OO_Caret;
241     break;
242   case tok::ampamp: // '&&'
243     OOK = OO_AmpAmp;
244     break;
245   case tok::pipepipe: // '||'
246     OOK = OO_PipePipe;
247     break;
248   case tok::identifier: // identifier
249     if (!WithOperator)
250       break;
251     LLVM_FALLTHROUGH;
252   default:
253     P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
254     P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
255                 Parser::StopBeforeMatch);
256     return DeclarationName();
257   }
258   P.ConsumeToken();
259   auto &DeclNames = Actions.getASTContext().DeclarationNames;
260   return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
261                         : DeclNames.getCXXOperatorName(OOK);
262 }
263 
264 /// Parse 'omp declare reduction' construct.
265 ///
266 ///       declare-reduction-directive:
267 ///        annot_pragma_openmp 'declare' 'reduction'
268 ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
269 ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
270 ///        annot_pragma_openmp_end
271 /// <reduction_id> is either a base language identifier or one of the following
272 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
273 ///
274 Parser::DeclGroupPtrTy
ParseOpenMPDeclareReductionDirective(AccessSpecifier AS)275 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
276   // Parse '('.
277   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
278   if (T.expectAndConsume(
279           diag::err_expected_lparen_after,
280           getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
281     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
282     return DeclGroupPtrTy();
283   }
284 
285   DeclarationName Name = parseOpenMPReductionId(*this);
286   if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
287     return DeclGroupPtrTy();
288 
289   // Consume ':'.
290   bool IsCorrect = !ExpectAndConsume(tok::colon);
291 
292   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
293     return DeclGroupPtrTy();
294 
295   IsCorrect = IsCorrect && !Name.isEmpty();
296 
297   if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
298     Diag(Tok.getLocation(), diag::err_expected_type);
299     IsCorrect = false;
300   }
301 
302   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
303     return DeclGroupPtrTy();
304 
305   SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
306   // Parse list of types until ':' token.
307   do {
308     ColonProtectionRAIIObject ColonRAII(*this);
309     SourceRange Range;
310     TypeResult TR = ParseTypeName(&Range, DeclaratorContext::Prototype, AS);
311     if (TR.isUsable()) {
312       QualType ReductionType =
313           Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
314       if (!ReductionType.isNull()) {
315         ReductionTypes.push_back(
316             std::make_pair(ReductionType, Range.getBegin()));
317       }
318     } else {
319       SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
320                 StopBeforeMatch);
321     }
322 
323     if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
324       break;
325 
326     // Consume ','.
327     if (ExpectAndConsume(tok::comma)) {
328       IsCorrect = false;
329       if (Tok.is(tok::annot_pragma_openmp_end)) {
330         Diag(Tok.getLocation(), diag::err_expected_type);
331         return DeclGroupPtrTy();
332       }
333     }
334   } while (Tok.isNot(tok::annot_pragma_openmp_end));
335 
336   if (ReductionTypes.empty()) {
337     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
338     return DeclGroupPtrTy();
339   }
340 
341   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
342     return DeclGroupPtrTy();
343 
344   // Consume ':'.
345   if (ExpectAndConsume(tok::colon))
346     IsCorrect = false;
347 
348   if (Tok.is(tok::annot_pragma_openmp_end)) {
349     Diag(Tok.getLocation(), diag::err_expected_expression);
350     return DeclGroupPtrTy();
351   }
352 
353   DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
354       getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
355 
356   // Parse <combiner> expression and then parse initializer if any for each
357   // correct type.
358   unsigned I = 0, E = ReductionTypes.size();
359   for (Decl *D : DRD.get()) {
360     TentativeParsingAction TPA(*this);
361     ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
362                                     Scope::CompoundStmtScope |
363                                     Scope::OpenMPDirectiveScope);
364     // Parse <combiner> expression.
365     Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
366     ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
367         ParseExpression().get(), D->getLocation(), /*DiscardedValue*/ false);
368     Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
369 
370     if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
371         Tok.isNot(tok::annot_pragma_openmp_end)) {
372       TPA.Commit();
373       IsCorrect = false;
374       break;
375     }
376     IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
377     ExprResult InitializerResult;
378     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
379       // Parse <initializer> expression.
380       if (Tok.is(tok::identifier) &&
381           Tok.getIdentifierInfo()->isStr("initializer")) {
382         ConsumeToken();
383       } else {
384         Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
385         TPA.Commit();
386         IsCorrect = false;
387         break;
388       }
389       // Parse '('.
390       BalancedDelimiterTracker T(*this, tok::l_paren,
391                                  tok::annot_pragma_openmp_end);
392       IsCorrect =
393           !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
394           IsCorrect;
395       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
396         ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
397                                         Scope::CompoundStmtScope |
398                                         Scope::OpenMPDirectiveScope);
399         // Parse expression.
400         VarDecl *OmpPrivParm =
401             Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
402                                                                 D);
403         // Check if initializer is omp_priv <init_expr> or something else.
404         if (Tok.is(tok::identifier) &&
405             Tok.getIdentifierInfo()->isStr("omp_priv")) {
406           ConsumeToken();
407           ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
408         } else {
409           InitializerResult = Actions.ActOnFinishFullExpr(
410               ParseAssignmentExpression().get(), D->getLocation(),
411               /*DiscardedValue*/ false);
412         }
413         Actions.ActOnOpenMPDeclareReductionInitializerEnd(
414             D, InitializerResult.get(), OmpPrivParm);
415         if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
416             Tok.isNot(tok::annot_pragma_openmp_end)) {
417           TPA.Commit();
418           IsCorrect = false;
419           break;
420         }
421         IsCorrect =
422             !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
423       }
424     }
425 
426     ++I;
427     // Revert parsing if not the last type, otherwise accept it, we're done with
428     // parsing.
429     if (I != E)
430       TPA.Revert();
431     else
432       TPA.Commit();
433   }
434   return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
435                                                          IsCorrect);
436 }
437 
ParseOpenMPReductionInitializerForDecl(VarDecl * OmpPrivParm)438 void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
439   // Parse declarator '=' initializer.
440   // If a '==' or '+=' is found, suggest a fixit to '='.
441   if (isTokenEqualOrEqualTypo()) {
442     ConsumeToken();
443 
444     if (Tok.is(tok::code_completion)) {
445       cutOffParsing();
446       Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
447       Actions.FinalizeDeclaration(OmpPrivParm);
448       return;
449     }
450 
451     PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
452     ExprResult Init = ParseInitializer();
453 
454     if (Init.isInvalid()) {
455       SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
456       Actions.ActOnInitializerError(OmpPrivParm);
457     } else {
458       Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
459                                    /*DirectInit=*/false);
460     }
461   } else if (Tok.is(tok::l_paren)) {
462     // Parse C++ direct initializer: '(' expression-list ')'
463     BalancedDelimiterTracker T(*this, tok::l_paren);
464     T.consumeOpen();
465 
466     ExprVector Exprs;
467     CommaLocsTy CommaLocs;
468 
469     SourceLocation LParLoc = T.getOpenLocation();
470     auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
471       QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
472           getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
473           OmpPrivParm->getLocation(), Exprs, LParLoc);
474       CalledSignatureHelp = true;
475       return PreferredType;
476     };
477     if (ParseExpressionList(Exprs, CommaLocs, [&] {
478           PreferredType.enterFunctionArgument(Tok.getLocation(),
479                                               RunSignatureHelp);
480         })) {
481       if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
482         RunSignatureHelp();
483       Actions.ActOnInitializerError(OmpPrivParm);
484       SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
485     } else {
486       // Match the ')'.
487       SourceLocation RLoc = Tok.getLocation();
488       if (!T.consumeClose())
489         RLoc = T.getCloseLocation();
490 
491       assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
492              "Unexpected number of commas!");
493 
494       ExprResult Initializer =
495           Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
496       Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
497                                    /*DirectInit=*/true);
498     }
499   } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
500     // Parse C++0x braced-init-list.
501     Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
502 
503     ExprResult Init(ParseBraceInitializer());
504 
505     if (Init.isInvalid()) {
506       Actions.ActOnInitializerError(OmpPrivParm);
507     } else {
508       Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
509                                    /*DirectInit=*/true);
510     }
511   } else {
512     Actions.ActOnUninitializedDecl(OmpPrivParm);
513   }
514 }
515 
516 /// Parses 'omp declare mapper' directive.
517 ///
518 ///       declare-mapper-directive:
519 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
520 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
521 ///         annot_pragma_openmp_end
522 /// <mapper-identifier> and <var> are base language identifiers.
523 ///
524 Parser::DeclGroupPtrTy
ParseOpenMPDeclareMapperDirective(AccessSpecifier AS)525 Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
526   bool IsCorrect = true;
527   // Parse '('
528   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
529   if (T.expectAndConsume(diag::err_expected_lparen_after,
530                          getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
531     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
532     return DeclGroupPtrTy();
533   }
534 
535   // Parse <mapper-identifier>
536   auto &DeclNames = Actions.getASTContext().DeclarationNames;
537   DeclarationName MapperId;
538   if (PP.LookAhead(0).is(tok::colon)) {
539     if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
540       Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
541       IsCorrect = false;
542     } else {
543       MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
544     }
545     ConsumeToken();
546     // Consume ':'.
547     ExpectAndConsume(tok::colon);
548   } else {
549     // If no mapper identifier is provided, its name is "default" by default
550     MapperId =
551         DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
552   }
553 
554   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
555     return DeclGroupPtrTy();
556 
557   // Parse <type> <var>
558   DeclarationName VName;
559   QualType MapperType;
560   SourceRange Range;
561   TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
562   if (ParsedType.isUsable())
563     MapperType =
564         Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
565   if (MapperType.isNull())
566     IsCorrect = false;
567   if (!IsCorrect) {
568     SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
569     return DeclGroupPtrTy();
570   }
571 
572   // Consume ')'.
573   IsCorrect &= !T.consumeClose();
574   if (!IsCorrect) {
575     SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
576     return DeclGroupPtrTy();
577   }
578 
579   // Enter scope.
580   DeclarationNameInfo DirName;
581   SourceLocation Loc = Tok.getLocation();
582   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
583                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
584   ParseScope OMPDirectiveScope(this, ScopeFlags);
585   Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
586 
587   // Add the mapper variable declaration.
588   ExprResult MapperVarRef = Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
589       getCurScope(), MapperType, Range.getBegin(), VName);
590 
591   // Parse map clauses.
592   SmallVector<OMPClause *, 6> Clauses;
593   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
594     OpenMPClauseKind CKind = Tok.isAnnotation()
595                                  ? OMPC_unknown
596                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
597     Actions.StartOpenMPClause(CKind);
598     OMPClause *Clause =
599         ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
600     if (Clause)
601       Clauses.push_back(Clause);
602     else
603       IsCorrect = false;
604     // Skip ',' if any.
605     if (Tok.is(tok::comma))
606       ConsumeToken();
607     Actions.EndOpenMPClause();
608   }
609   if (Clauses.empty()) {
610     Diag(Tok, diag::err_omp_expected_clause)
611         << getOpenMPDirectiveName(OMPD_declare_mapper);
612     IsCorrect = false;
613   }
614 
615   // Exit scope.
616   Actions.EndOpenMPDSABlock(nullptr);
617   OMPDirectiveScope.Exit();
618   DeclGroupPtrTy DG = Actions.ActOnOpenMPDeclareMapperDirective(
619       getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
620       Range.getBegin(), VName, AS, MapperVarRef.get(), Clauses);
621   if (!IsCorrect)
622     return DeclGroupPtrTy();
623 
624   return DG;
625 }
626 
parseOpenMPDeclareMapperVarDecl(SourceRange & Range,DeclarationName & Name,AccessSpecifier AS)627 TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
628                                                    DeclarationName &Name,
629                                                    AccessSpecifier AS) {
630   // Parse the common declaration-specifiers piece.
631   Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
632   DeclSpec DS(AttrFactory);
633   ParseSpecifierQualifierList(DS, AS, DSC);
634 
635   // Parse the declarator.
636   DeclaratorContext Context = DeclaratorContext::Prototype;
637   Declarator DeclaratorInfo(DS, Context);
638   ParseDeclarator(DeclaratorInfo);
639   Range = DeclaratorInfo.getSourceRange();
640   if (DeclaratorInfo.getIdentifier() == nullptr) {
641     Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
642     return true;
643   }
644   Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
645 
646   return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
647 }
648 
649 namespace {
650 /// RAII that recreates function context for correct parsing of clauses of
651 /// 'declare simd' construct.
652 /// OpenMP, 2.8.2 declare simd Construct
653 /// The expressions appearing in the clauses of this directive are evaluated in
654 /// the scope of the arguments of the function declaration or definition.
655 class FNContextRAII final {
656   Parser &P;
657   Sema::CXXThisScopeRAII *ThisScope;
658   Parser::MultiParseScope Scopes;
659   bool HasFunScope = false;
660   FNContextRAII() = delete;
661   FNContextRAII(const FNContextRAII &) = delete;
662   FNContextRAII &operator=(const FNContextRAII &) = delete;
663 
664 public:
FNContextRAII(Parser & P,Parser::DeclGroupPtrTy Ptr)665   FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P), Scopes(P) {
666     Decl *D = *Ptr.get().begin();
667     NamedDecl *ND = dyn_cast<NamedDecl>(D);
668     RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
669     Sema &Actions = P.getActions();
670 
671     // Allow 'this' within late-parsed attributes.
672     ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
673                                            ND && ND->isCXXInstanceMember());
674 
675     // If the Decl is templatized, add template parameters to scope.
676     // FIXME: Track CurTemplateDepth?
677     P.ReenterTemplateScopes(Scopes, D);
678 
679     // If the Decl is on a function, add function parameters to the scope.
680     if (D->isFunctionOrFunctionTemplate()) {
681       HasFunScope = true;
682       Scopes.Enter(Scope::FnScope | Scope::DeclScope |
683                    Scope::CompoundStmtScope);
684       Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
685     }
686   }
~FNContextRAII()687   ~FNContextRAII() {
688     if (HasFunScope)
689       P.getActions().ActOnExitFunctionContext();
690     delete ThisScope;
691   }
692 };
693 } // namespace
694 
695 /// Parses clauses for 'declare simd' directive.
696 ///    clause:
697 ///      'inbranch' | 'notinbranch'
698 ///      'simdlen' '(' <expr> ')'
699 ///      { 'uniform' '(' <argument_list> ')' }
700 ///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
701 ///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
parseDeclareSimdClauses(Parser & P,OMPDeclareSimdDeclAttr::BranchStateTy & BS,ExprResult & SimdLen,SmallVectorImpl<Expr * > & Uniforms,SmallVectorImpl<Expr * > & Aligneds,SmallVectorImpl<Expr * > & Alignments,SmallVectorImpl<Expr * > & Linears,SmallVectorImpl<unsigned> & LinModifiers,SmallVectorImpl<Expr * > & Steps)702 static bool parseDeclareSimdClauses(
703     Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
704     SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
705     SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
706     SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
707   SourceRange BSRange;
708   const Token &Tok = P.getCurToken();
709   bool IsError = false;
710   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
711     if (Tok.isNot(tok::identifier))
712       break;
713     OMPDeclareSimdDeclAttr::BranchStateTy Out;
714     IdentifierInfo *II = Tok.getIdentifierInfo();
715     StringRef ClauseName = II->getName();
716     // Parse 'inranch|notinbranch' clauses.
717     if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
718       if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
719         P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
720             << ClauseName
721             << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
722         IsError = true;
723       }
724       BS = Out;
725       BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
726       P.ConsumeToken();
727     } else if (ClauseName.equals("simdlen")) {
728       if (SimdLen.isUsable()) {
729         P.Diag(Tok, diag::err_omp_more_one_clause)
730             << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
731         IsError = true;
732       }
733       P.ConsumeToken();
734       SourceLocation RLoc;
735       SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
736       if (SimdLen.isInvalid())
737         IsError = true;
738     } else {
739       OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
740       if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
741           CKind == OMPC_linear) {
742         Parser::OpenMPVarListDataTy Data;
743         SmallVectorImpl<Expr *> *Vars = &Uniforms;
744         if (CKind == OMPC_aligned) {
745           Vars = &Aligneds;
746         } else if (CKind == OMPC_linear) {
747           Data.ExtraModifier = OMPC_LINEAR_val;
748           Vars = &Linears;
749         }
750 
751         P.ConsumeToken();
752         if (P.ParseOpenMPVarList(OMPD_declare_simd,
753                                  getOpenMPClauseKind(ClauseName), *Vars, Data))
754           IsError = true;
755         if (CKind == OMPC_aligned) {
756           Alignments.append(Aligneds.size() - Alignments.size(),
757                             Data.DepModOrTailExpr);
758         } else if (CKind == OMPC_linear) {
759           assert(0 <= Data.ExtraModifier &&
760                  Data.ExtraModifier <= OMPC_LINEAR_unknown &&
761                  "Unexpected linear modifier.");
762           if (P.getActions().CheckOpenMPLinearModifier(
763                   static_cast<OpenMPLinearClauseKind>(Data.ExtraModifier),
764                   Data.ExtraModifierLoc))
765             Data.ExtraModifier = OMPC_LINEAR_val;
766           LinModifiers.append(Linears.size() - LinModifiers.size(),
767                               Data.ExtraModifier);
768           Steps.append(Linears.size() - Steps.size(), Data.DepModOrTailExpr);
769         }
770       } else
771         // TODO: add parsing of other clauses.
772         break;
773     }
774     // Skip ',' if any.
775     if (Tok.is(tok::comma))
776       P.ConsumeToken();
777   }
778   return IsError;
779 }
780 
781 /// Parse clauses for '#pragma omp declare simd'.
782 Parser::DeclGroupPtrTy
ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,CachedTokens & Toks,SourceLocation Loc)783 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
784                                    CachedTokens &Toks, SourceLocation Loc) {
785   PP.EnterToken(Tok, /*IsReinject*/ true);
786   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
787                       /*IsReinject*/ true);
788   // Consume the previously pushed token.
789   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
790   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
791 
792   FNContextRAII FnContext(*this, Ptr);
793   OMPDeclareSimdDeclAttr::BranchStateTy BS =
794       OMPDeclareSimdDeclAttr::BS_Undefined;
795   ExprResult Simdlen;
796   SmallVector<Expr *, 4> Uniforms;
797   SmallVector<Expr *, 4> Aligneds;
798   SmallVector<Expr *, 4> Alignments;
799   SmallVector<Expr *, 4> Linears;
800   SmallVector<unsigned, 4> LinModifiers;
801   SmallVector<Expr *, 4> Steps;
802   bool IsError =
803       parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
804                               Alignments, Linears, LinModifiers, Steps);
805   skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
806   // Skip the last annot_pragma_openmp_end.
807   SourceLocation EndLoc = ConsumeAnnotationToken();
808   if (IsError)
809     return Ptr;
810   return Actions.ActOnOpenMPDeclareSimdDirective(
811       Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
812       LinModifiers, Steps, SourceRange(Loc, EndLoc));
813 }
814 
815 namespace {
816 /// Constant used in the diagnostics to distinguish the levels in an OpenMP
817 /// contexts: selector-set={selector(trait, ...), ...}, ....
818 enum OMPContextLvl {
819   CONTEXT_SELECTOR_SET_LVL = 0,
820   CONTEXT_SELECTOR_LVL = 1,
821   CONTEXT_TRAIT_LVL = 2,
822 };
823 
stringLiteralParser(Parser & P)824 static StringRef stringLiteralParser(Parser &P) {
825   ExprResult Res = P.ParseStringLiteralExpression(true);
826   return Res.isUsable() ? Res.getAs<StringLiteral>()->getString() : "";
827 }
828 
getNameFromIdOrString(Parser & P,Token & Tok,OMPContextLvl Lvl)829 static StringRef getNameFromIdOrString(Parser &P, Token &Tok,
830                                        OMPContextLvl Lvl) {
831   if (Tok.is(tok::identifier)) {
832     llvm::SmallString<16> Buffer;
833     StringRef Name = P.getPreprocessor().getSpelling(Tok, Buffer);
834     (void)P.ConsumeToken();
835     return Name;
836   }
837 
838   if (tok::isStringLiteral(Tok.getKind()))
839     return stringLiteralParser(P);
840 
841   P.Diag(Tok.getLocation(),
842          diag::warn_omp_declare_variant_string_literal_or_identifier)
843       << Lvl;
844   return "";
845 }
846 
checkForDuplicates(Parser & P,StringRef Name,SourceLocation NameLoc,llvm::StringMap<SourceLocation> & Seen,OMPContextLvl Lvl)847 static bool checkForDuplicates(Parser &P, StringRef Name,
848                                SourceLocation NameLoc,
849                                llvm::StringMap<SourceLocation> &Seen,
850                                OMPContextLvl Lvl) {
851   auto Res = Seen.try_emplace(Name, NameLoc);
852   if (Res.second)
853     return false;
854 
855   // Each trait-set-selector-name, trait-selector-name and trait-name can
856   // only be specified once.
857   P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
858       << Lvl << Name;
859   P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
860       << Lvl << Name;
861   return true;
862 }
863 } // namespace
864 
parseOMPTraitPropertyKind(OMPTraitProperty & TIProperty,llvm::omp::TraitSet Set,llvm::omp::TraitSelector Selector,llvm::StringMap<SourceLocation> & Seen)865 void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
866                                        llvm::omp::TraitSet Set,
867                                        llvm::omp::TraitSelector Selector,
868                                        llvm::StringMap<SourceLocation> &Seen) {
869   TIProperty.Kind = TraitProperty::invalid;
870 
871   SourceLocation NameLoc = Tok.getLocation();
872   StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
873   if (Name.empty()) {
874     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
875         << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
876     return;
877   }
878 
879   TIProperty.RawString = Name;
880   TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Selector, Name);
881   if (TIProperty.Kind != TraitProperty::invalid) {
882     if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
883       TIProperty.Kind = TraitProperty::invalid;
884     return;
885   }
886 
887   // It follows diagnosis and helping notes.
888   // FIXME: We should move the diagnosis string generation into libFrontend.
889   Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
890       << Name << getOpenMPContextTraitSelectorName(Selector)
891       << getOpenMPContextTraitSetName(Set);
892 
893   TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
894   if (SetForName != TraitSet::invalid) {
895     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
896         << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
897     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
898         << Name << "<selector-name>"
899         << "(<property-name>)";
900     return;
901   }
902   TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
903   if (SelectorForName != TraitSelector::invalid) {
904     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
905         << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
906     bool AllowsTraitScore = false;
907     bool RequiresProperty = false;
908     isValidTraitSelectorForTraitSet(
909         SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
910         AllowsTraitScore, RequiresProperty);
911     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
912         << getOpenMPContextTraitSetName(
913                getOpenMPContextTraitSetForSelector(SelectorForName))
914         << Name << (RequiresProperty ? "(<property-name>)" : "");
915     return;
916   }
917   for (const auto &PotentialSet :
918        {TraitSet::construct, TraitSet::user, TraitSet::implementation,
919         TraitSet::device}) {
920     TraitProperty PropertyForName =
921         getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
922     if (PropertyForName == TraitProperty::invalid)
923       continue;
924     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
925         << getOpenMPContextTraitSetName(
926                getOpenMPContextTraitSetForProperty(PropertyForName))
927         << getOpenMPContextTraitSelectorName(
928                getOpenMPContextTraitSelectorForProperty(PropertyForName))
929         << ("(" + Name + ")").str();
930     return;
931   }
932   Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
933       << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
934 }
935 
checkExtensionProperty(Parser & P,SourceLocation Loc,OMPTraitProperty & TIProperty,OMPTraitSelector & TISelector,llvm::StringMap<SourceLocation> & Seen)936 static bool checkExtensionProperty(Parser &P, SourceLocation Loc,
937                                    OMPTraitProperty &TIProperty,
938                                    OMPTraitSelector &TISelector,
939                                    llvm::StringMap<SourceLocation> &Seen) {
940   assert(TISelector.Kind ==
941              llvm::omp::TraitSelector::implementation_extension &&
942          "Only for extension properties, e.g., "
943          "`implementation={extension(PROPERTY)}`");
944   if (TIProperty.Kind == TraitProperty::invalid)
945     return false;
946 
947   if (TIProperty.Kind ==
948       TraitProperty::implementation_extension_disable_implicit_base)
949     return true;
950 
951   if (TIProperty.Kind ==
952       TraitProperty::implementation_extension_allow_templates)
953     return true;
954 
955   auto IsMatchExtension = [](OMPTraitProperty &TP) {
956     return (TP.Kind ==
957                 llvm::omp::TraitProperty::implementation_extension_match_all ||
958             TP.Kind ==
959                 llvm::omp::TraitProperty::implementation_extension_match_any ||
960             TP.Kind ==
961                 llvm::omp::TraitProperty::implementation_extension_match_none);
962   };
963 
964   if (IsMatchExtension(TIProperty)) {
965     for (OMPTraitProperty &SeenProp : TISelector.Properties)
966       if (IsMatchExtension(SeenProp)) {
967         P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
968         StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
969             SeenProp.Kind, SeenProp.RawString);
970         SourceLocation SeenLoc = Seen[SeenName];
971         P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
972             << CONTEXT_TRAIT_LVL << SeenName;
973         return false;
974       }
975     return true;
976   }
977 
978   llvm_unreachable("Unknown extension property!");
979 }
980 
parseOMPContextProperty(OMPTraitSelector & TISelector,llvm::omp::TraitSet Set,llvm::StringMap<SourceLocation> & Seen)981 void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
982                                      llvm::omp::TraitSet Set,
983                                      llvm::StringMap<SourceLocation> &Seen) {
984   assert(TISelector.Kind != TraitSelector::user_condition &&
985          "User conditions are special properties not handled here!");
986 
987   SourceLocation PropertyLoc = Tok.getLocation();
988   OMPTraitProperty TIProperty;
989   parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen);
990 
991   if (TISelector.Kind == llvm::omp::TraitSelector::implementation_extension)
992     if (!checkExtensionProperty(*this, Tok.getLocation(), TIProperty,
993                                 TISelector, Seen))
994       TIProperty.Kind = TraitProperty::invalid;
995 
996   // If we have an invalid property here we already issued a warning.
997   if (TIProperty.Kind == TraitProperty::invalid) {
998     if (PropertyLoc != Tok.getLocation())
999       Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1000           << CONTEXT_TRAIT_LVL;
1001     return;
1002   }
1003 
1004   if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind,
1005                                                  TISelector.Kind, Set)) {
1006 
1007     // If we make it here the property, selector, set, score, condition, ... are
1008     // all valid (or have been corrected). Thus we can record the property.
1009     TISelector.Properties.push_back(TIProperty);
1010     return;
1011   }
1012 
1013   Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
1014       << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1015                                            TIProperty.RawString)
1016       << getOpenMPContextTraitSelectorName(TISelector.Kind)
1017       << getOpenMPContextTraitSetName(Set);
1018   Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1019       << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1020                                            TIProperty.RawString)
1021       << getOpenMPContextTraitSelectorName(
1022              getOpenMPContextTraitSelectorForProperty(TIProperty.Kind))
1023       << getOpenMPContextTraitSetName(
1024              getOpenMPContextTraitSetForProperty(TIProperty.Kind));
1025   Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1026       << CONTEXT_TRAIT_LVL;
1027 }
1028 
parseOMPTraitSelectorKind(OMPTraitSelector & TISelector,llvm::omp::TraitSet Set,llvm::StringMap<SourceLocation> & Seen)1029 void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1030                                        llvm::omp::TraitSet Set,
1031                                        llvm::StringMap<SourceLocation> &Seen) {
1032   TISelector.Kind = TraitSelector::invalid;
1033 
1034   SourceLocation NameLoc = Tok.getLocation();
1035   StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_LVL);
1036   if (Name.empty()) {
1037     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1038         << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1039     return;
1040   }
1041 
1042   TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
1043   if (TISelector.Kind != TraitSelector::invalid) {
1044     if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1045       TISelector.Kind = TraitSelector::invalid;
1046     return;
1047   }
1048 
1049   // It follows diagnosis and helping notes.
1050   Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1051       << Name << getOpenMPContextTraitSetName(Set);
1052 
1053   TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1054   if (SetForName != TraitSet::invalid) {
1055     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1056         << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1057     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1058         << Name << "<selector-name>"
1059         << "<property-name>";
1060     return;
1061   }
1062   for (const auto &PotentialSet :
1063        {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1064         TraitSet::device}) {
1065     TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1066         PotentialSet, TraitSelector::invalid, Name);
1067     if (PropertyForName == TraitProperty::invalid)
1068       continue;
1069     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1070         << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1071     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1072         << getOpenMPContextTraitSetName(
1073                getOpenMPContextTraitSetForProperty(PropertyForName))
1074         << getOpenMPContextTraitSelectorName(
1075                getOpenMPContextTraitSelectorForProperty(PropertyForName))
1076         << ("(" + Name + ")").str();
1077     return;
1078   }
1079   Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1080       << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1081 }
1082 
1083 /// Parse optional 'score' '(' <expr> ')' ':'.
parseContextScore(Parser & P)1084 static ExprResult parseContextScore(Parser &P) {
1085   ExprResult ScoreExpr;
1086   llvm::SmallString<16> Buffer;
1087   StringRef SelectorName =
1088       P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
1089   if (!SelectorName.equals("score"))
1090     return ScoreExpr;
1091   (void)P.ConsumeToken();
1092   SourceLocation RLoc;
1093   ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
1094   // Parse ':'
1095   if (P.getCurToken().is(tok::colon))
1096     (void)P.ConsumeAnyToken();
1097   else
1098     P.Diag(P.getCurToken(), diag::warn_omp_declare_variant_expected)
1099         << "':'"
1100         << "score expression";
1101   return ScoreExpr;
1102 }
1103 
1104 /// Parses an OpenMP context selector.
1105 ///
1106 /// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
parseOMPContextSelector(OMPTraitSelector & TISelector,llvm::omp::TraitSet Set,llvm::StringMap<SourceLocation> & SeenSelectors)1107 void Parser::parseOMPContextSelector(
1108     OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1109     llvm::StringMap<SourceLocation> &SeenSelectors) {
1110   unsigned short OuterPC = ParenCount;
1111 
1112   // If anything went wrong we issue an error or warning and then skip the rest
1113   // of the selector. However, commas are ambiguous so we look for the nesting
1114   // of parentheses here as well.
1115   auto FinishSelector = [OuterPC, this]() -> void {
1116     bool Done = false;
1117     while (!Done) {
1118       while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1119                          tok::annot_pragma_openmp_end},
1120                         StopBeforeMatch))
1121         ;
1122       if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1123         (void)ConsumeParen();
1124       if (OuterPC <= ParenCount) {
1125         Done = true;
1126         break;
1127       }
1128       if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1129         Done = true;
1130         break;
1131       }
1132       (void)ConsumeAnyToken();
1133     }
1134     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1135         << CONTEXT_SELECTOR_LVL;
1136   };
1137 
1138   SourceLocation SelectorLoc = Tok.getLocation();
1139   parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1140   if (TISelector.Kind == TraitSelector::invalid)
1141     return FinishSelector();
1142 
1143   bool AllowsTraitScore = false;
1144   bool RequiresProperty = false;
1145   if (!isValidTraitSelectorForTraitSet(TISelector.Kind, Set, AllowsTraitScore,
1146                                        RequiresProperty)) {
1147     Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1148         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1149         << getOpenMPContextTraitSetName(Set);
1150     Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1151         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1152         << getOpenMPContextTraitSetName(
1153                getOpenMPContextTraitSetForSelector(TISelector.Kind))
1154         << RequiresProperty;
1155     return FinishSelector();
1156   }
1157 
1158   if (!RequiresProperty) {
1159     TISelector.Properties.push_back(
1160         {getOpenMPContextTraitPropertyForSelector(TISelector.Kind),
1161          getOpenMPContextTraitSelectorName(TISelector.Kind)});
1162     return;
1163   }
1164 
1165   if (!Tok.is(tok::l_paren)) {
1166     Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1167         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1168         << getOpenMPContextTraitSetName(Set);
1169     return FinishSelector();
1170   }
1171 
1172   if (TISelector.Kind == TraitSelector::user_condition) {
1173     SourceLocation RLoc;
1174     ExprResult Condition = ParseOpenMPParensExpr("user condition", RLoc);
1175     if (!Condition.isUsable())
1176       return FinishSelector();
1177     TISelector.ScoreOrCondition = Condition.get();
1178     TISelector.Properties.push_back(
1179         {TraitProperty::user_condition_unknown, "<condition>"});
1180     return;
1181   }
1182 
1183   BalancedDelimiterTracker BDT(*this, tok::l_paren,
1184                                tok::annot_pragma_openmp_end);
1185   // Parse '('.
1186   (void)BDT.consumeOpen();
1187 
1188   SourceLocation ScoreLoc = Tok.getLocation();
1189   ExprResult Score = parseContextScore(*this);
1190 
1191   if (!AllowsTraitScore && !Score.isUnset()) {
1192     if (Score.isUsable()) {
1193       Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1194           << getOpenMPContextTraitSelectorName(TISelector.Kind)
1195           << getOpenMPContextTraitSetName(Set) << Score.get();
1196     } else {
1197       Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1198           << getOpenMPContextTraitSelectorName(TISelector.Kind)
1199           << getOpenMPContextTraitSetName(Set) << "<invalid>";
1200     }
1201     Score = ExprResult();
1202   }
1203 
1204   if (Score.isUsable())
1205     TISelector.ScoreOrCondition = Score.get();
1206 
1207   llvm::StringMap<SourceLocation> SeenProperties;
1208   do {
1209     parseOMPContextProperty(TISelector, Set, SeenProperties);
1210   } while (TryConsumeToken(tok::comma));
1211 
1212   // Parse ')'.
1213   BDT.consumeClose();
1214 }
1215 
parseOMPTraitSetKind(OMPTraitSet & TISet,llvm::StringMap<SourceLocation> & Seen)1216 void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1217                                   llvm::StringMap<SourceLocation> &Seen) {
1218   TISet.Kind = TraitSet::invalid;
1219 
1220   SourceLocation NameLoc = Tok.getLocation();
1221   StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_SET_LVL);
1222   if (Name.empty()) {
1223     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1224         << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1225     return;
1226   }
1227 
1228   TISet.Kind = getOpenMPContextTraitSetKind(Name);
1229   if (TISet.Kind != TraitSet::invalid) {
1230     if (checkForDuplicates(*this, Name, NameLoc, Seen,
1231                            CONTEXT_SELECTOR_SET_LVL))
1232       TISet.Kind = TraitSet::invalid;
1233     return;
1234   }
1235 
1236   // It follows diagnosis and helping notes.
1237   Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1238 
1239   TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1240   if (SelectorForName != TraitSelector::invalid) {
1241     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1242         << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1243     bool AllowsTraitScore = false;
1244     bool RequiresProperty = false;
1245     isValidTraitSelectorForTraitSet(
1246         SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1247         AllowsTraitScore, RequiresProperty);
1248     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1249         << getOpenMPContextTraitSetName(
1250                getOpenMPContextTraitSetForSelector(SelectorForName))
1251         << Name << (RequiresProperty ? "(<property-name>)" : "");
1252     return;
1253   }
1254   for (const auto &PotentialSet :
1255        {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1256         TraitSet::device}) {
1257     TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1258         PotentialSet, TraitSelector::invalid, Name);
1259     if (PropertyForName == TraitProperty::invalid)
1260       continue;
1261     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1262         << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1263     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1264         << getOpenMPContextTraitSetName(
1265                getOpenMPContextTraitSetForProperty(PropertyForName))
1266         << getOpenMPContextTraitSelectorName(
1267                getOpenMPContextTraitSelectorForProperty(PropertyForName))
1268         << ("(" + Name + ")").str();
1269     return;
1270   }
1271   Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1272       << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1273 }
1274 
1275 /// Parses an OpenMP context selector set.
1276 ///
1277 /// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
parseOMPContextSelectorSet(OMPTraitSet & TISet,llvm::StringMap<SourceLocation> & SeenSets)1278 void Parser::parseOMPContextSelectorSet(
1279     OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1280   auto OuterBC = BraceCount;
1281 
1282   // If anything went wrong we issue an error or warning and then skip the rest
1283   // of the set. However, commas are ambiguous so we look for the nesting
1284   // of braces here as well.
1285   auto FinishSelectorSet = [this, OuterBC]() -> void {
1286     bool Done = false;
1287     while (!Done) {
1288       while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1289                          tok::annot_pragma_openmp_end},
1290                         StopBeforeMatch))
1291         ;
1292       if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1293         (void)ConsumeBrace();
1294       if (OuterBC <= BraceCount) {
1295         Done = true;
1296         break;
1297       }
1298       if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1299         Done = true;
1300         break;
1301       }
1302       (void)ConsumeAnyToken();
1303     }
1304     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1305         << CONTEXT_SELECTOR_SET_LVL;
1306   };
1307 
1308   parseOMPTraitSetKind(TISet, SeenSets);
1309   if (TISet.Kind == TraitSet::invalid)
1310     return FinishSelectorSet();
1311 
1312   // Parse '='.
1313   if (!TryConsumeToken(tok::equal))
1314     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1315         << "="
1316         << ("context set name \"" + getOpenMPContextTraitSetName(TISet.Kind) +
1317             "\"")
1318                .str();
1319 
1320   // Parse '{'.
1321   if (Tok.is(tok::l_brace)) {
1322     (void)ConsumeBrace();
1323   } else {
1324     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1325         << "{"
1326         << ("'=' that follows the context set name \"" +
1327             getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1328                .str();
1329   }
1330 
1331   llvm::StringMap<SourceLocation> SeenSelectors;
1332   do {
1333     OMPTraitSelector TISelector;
1334     parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors);
1335     if (TISelector.Kind != TraitSelector::invalid &&
1336         !TISelector.Properties.empty())
1337       TISet.Selectors.push_back(TISelector);
1338   } while (TryConsumeToken(tok::comma));
1339 
1340   // Parse '}'.
1341   if (Tok.is(tok::r_brace)) {
1342     (void)ConsumeBrace();
1343   } else {
1344     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1345         << "}"
1346         << ("context selectors for the context set \"" +
1347             getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1348                .str();
1349   }
1350 }
1351 
1352 /// Parse OpenMP context selectors:
1353 ///
1354 /// <trait-set-selector> [, <trait-set-selector>]*
parseOMPContextSelectors(SourceLocation Loc,OMPTraitInfo & TI)1355 bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) {
1356   llvm::StringMap<SourceLocation> SeenSets;
1357   do {
1358     OMPTraitSet TISet;
1359     parseOMPContextSelectorSet(TISet, SeenSets);
1360     if (TISet.Kind != TraitSet::invalid && !TISet.Selectors.empty())
1361       TI.Sets.push_back(TISet);
1362   } while (TryConsumeToken(tok::comma));
1363 
1364   return false;
1365 }
1366 
1367 /// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,CachedTokens & Toks,SourceLocation Loc)1368 void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
1369                                            CachedTokens &Toks,
1370                                            SourceLocation Loc) {
1371   PP.EnterToken(Tok, /*IsReinject*/ true);
1372   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1373                       /*IsReinject*/ true);
1374   // Consume the previously pushed token.
1375   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1376   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1377 
1378   FNContextRAII FnContext(*this, Ptr);
1379   // Parse function declaration id.
1380   SourceLocation RLoc;
1381   // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs
1382   // instead of MemberExprs.
1383   ExprResult AssociatedFunction;
1384   {
1385     // Do not mark function as is used to prevent its emission if this is the
1386     // only place where it is used.
1387     EnterExpressionEvaluationContext Unevaluated(
1388         Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1389     AssociatedFunction = ParseOpenMPParensExpr(
1390         getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1391         /*IsAddressOfOperand=*/true);
1392   }
1393   if (!AssociatedFunction.isUsable()) {
1394     if (!Tok.is(tok::annot_pragma_openmp_end))
1395       while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1396         ;
1397     // Skip the last annot_pragma_openmp_end.
1398     (void)ConsumeAnnotationToken();
1399     return;
1400   }
1401 
1402   OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
1403   ASTContext &ASTCtx = Actions.getASTContext();
1404   OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
1405   if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI))
1406     return;
1407 
1408   Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1409       Actions.checkOpenMPDeclareVariantFunction(
1410           Ptr, AssociatedFunction.get(), TI,
1411           SourceRange(Loc, Tok.getLocation()));
1412 
1413   // Skip last tokens.
1414   while (Tok.isNot(tok::annot_pragma_openmp_end))
1415     ConsumeAnyToken();
1416   if (DeclVarData && !TI.Sets.empty())
1417     Actions.ActOnOpenMPDeclareVariantDirective(
1418         DeclVarData->first, DeclVarData->second, TI,
1419         SourceRange(Loc, Tok.getLocation()));
1420 
1421   // Skip the last annot_pragma_openmp_end.
1422   (void)ConsumeAnnotationToken();
1423 }
1424 
parseOMPDeclareVariantMatchClause(SourceLocation Loc,OMPTraitInfo & TI,OMPTraitInfo * ParentTI)1425 bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
1426                                                OMPTraitInfo &TI,
1427                                                OMPTraitInfo *ParentTI) {
1428   // Parse 'match'.
1429   OpenMPClauseKind CKind = Tok.isAnnotation()
1430                                ? OMPC_unknown
1431                                : getOpenMPClauseKind(PP.getSpelling(Tok));
1432   if (CKind != OMPC_match) {
1433     Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1434         << getOpenMPClauseName(OMPC_match);
1435     while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
1436       ;
1437     // Skip the last annot_pragma_openmp_end.
1438     (void)ConsumeAnnotationToken();
1439     return true;
1440   }
1441   (void)ConsumeToken();
1442   // Parse '('.
1443   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1444   if (T.expectAndConsume(diag::err_expected_lparen_after,
1445                          getOpenMPClauseName(OMPC_match).data())) {
1446     while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1447       ;
1448     // Skip the last annot_pragma_openmp_end.
1449     (void)ConsumeAnnotationToken();
1450     return true;
1451   }
1452 
1453   // Parse inner context selectors.
1454   parseOMPContextSelectors(Loc, TI);
1455 
1456   // Parse ')'
1457   (void)T.consumeClose();
1458 
1459   if (!ParentTI)
1460     return false;
1461 
1462   // Merge the parent/outer trait info into the one we just parsed and diagnose
1463   // problems.
1464   // TODO: Keep some source location in the TI to provide better diagnostics.
1465   // TODO: Perform some kind of equivalence check on the condition and score
1466   //       expressions.
1467   for (const OMPTraitSet &ParentSet : ParentTI->Sets) {
1468     bool MergedSet = false;
1469     for (OMPTraitSet &Set : TI.Sets) {
1470       if (Set.Kind != ParentSet.Kind)
1471         continue;
1472       MergedSet = true;
1473       for (const OMPTraitSelector &ParentSelector : ParentSet.Selectors) {
1474         bool MergedSelector = false;
1475         for (OMPTraitSelector &Selector : Set.Selectors) {
1476           if (Selector.Kind != ParentSelector.Kind)
1477             continue;
1478           MergedSelector = true;
1479           for (const OMPTraitProperty &ParentProperty :
1480                ParentSelector.Properties) {
1481             bool MergedProperty = false;
1482             for (OMPTraitProperty &Property : Selector.Properties) {
1483               // Ignore "equivalent" properties.
1484               if (Property.Kind != ParentProperty.Kind)
1485                 continue;
1486 
1487               // If the kind is the same but the raw string not, we don't want
1488               // to skip out on the property.
1489               MergedProperty |= Property.RawString == ParentProperty.RawString;
1490 
1491               if (Property.RawString == ParentProperty.RawString &&
1492                   Selector.ScoreOrCondition == ParentSelector.ScoreOrCondition)
1493                 continue;
1494 
1495               if (Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1496                 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1497               } else if (Selector.ScoreOrCondition !=
1498                          ParentSelector.ScoreOrCondition) {
1499                 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1500                     << getOpenMPContextTraitPropertyName(
1501                            ParentProperty.Kind, ParentProperty.RawString)
1502                     << getOpenMPContextTraitSelectorName(ParentSelector.Kind)
1503                     << getOpenMPContextTraitSetName(ParentSet.Kind);
1504               }
1505             }
1506             if (!MergedProperty)
1507               Selector.Properties.push_back(ParentProperty);
1508           }
1509         }
1510         if (!MergedSelector)
1511           Set.Selectors.push_back(ParentSelector);
1512       }
1513     }
1514     if (!MergedSet)
1515       TI.Sets.push_back(ParentSet);
1516   }
1517 
1518   return false;
1519 }
1520 
1521 /// `omp assumes` or `omp begin/end assumes` <clause> [[,]<clause>]...
1522 /// where
1523 ///
1524 ///   clause:
1525 ///     'ext_IMPL_DEFINED'
1526 ///     'absent' '(' directive-name [, directive-name]* ')'
1527 ///     'contains' '(' directive-name [, directive-name]* ')'
1528 ///     'holds' '(' scalar-expression ')'
1529 ///     'no_openmp'
1530 ///     'no_openmp_routines'
1531 ///     'no_parallelism'
1532 ///
ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,SourceLocation Loc)1533 void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
1534                                          SourceLocation Loc) {
1535   SmallVector<StringRef, 4> Assumptions;
1536   bool SkippedClauses = false;
1537 
1538   auto SkipBraces = [&](llvm::StringRef Spelling, bool IssueNote) {
1539     BalancedDelimiterTracker T(*this, tok::l_paren,
1540                                tok::annot_pragma_openmp_end);
1541     if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1542       return;
1543     T.skipToEnd();
1544     if (IssueNote && T.getCloseLocation().isValid())
1545       Diag(T.getCloseLocation(),
1546            diag::note_omp_assumption_clause_continue_here);
1547   };
1548 
1549   /// Helper to determine which AssumptionClauseMapping (ACM) in the
1550   /// AssumptionClauseMappings table matches \p RawString. The return value is
1551   /// the index of the matching ACM into the table or -1 if there was no match.
1552   auto MatchACMClause = [&](StringRef RawString) {
1553     llvm::StringSwitch<int> SS(RawString);
1554     unsigned ACMIdx = 0;
1555     for (const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1556       if (ACMI.StartsWith)
1557         SS.StartsWith(ACMI.Identifier, ACMIdx++);
1558       else
1559         SS.Case(ACMI.Identifier, ACMIdx++);
1560     }
1561     return SS.Default(-1);
1562   };
1563 
1564   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1565     IdentifierInfo *II = nullptr;
1566     SourceLocation StartLoc = Tok.getLocation();
1567     int Idx = -1;
1568     if (Tok.isAnyIdentifier()) {
1569       II = Tok.getIdentifierInfo();
1570       Idx = MatchACMClause(II->getName());
1571     }
1572     ConsumeAnyToken();
1573 
1574     bool NextIsLPar = Tok.is(tok::l_paren);
1575     // Handle unknown clauses by skipping them.
1576     if (Idx == -1) {
1577       Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1578           << llvm::omp::getOpenMPDirectiveName(DKind)
1579           << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1580       if (NextIsLPar)
1581         SkipBraces(II ? II->getName() : "", /* IssueNote */ true);
1582       SkippedClauses = true;
1583       continue;
1584     }
1585     const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1586     if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1587       // TODO: We ignore absent, contains, and holds assumptions for now. We
1588       //       also do not verify the content in the parenthesis at all.
1589       SkippedClauses = true;
1590       SkipBraces(II->getName(), /* IssueNote */ false);
1591       continue;
1592     }
1593 
1594     if (NextIsLPar) {
1595       Diag(Tok.getLocation(),
1596            diag::warn_omp_unknown_assumption_clause_without_args)
1597           << II;
1598       SkipBraces(II->getName(), /* IssueNote */ true);
1599     }
1600 
1601     assert(II && "Expected an identifier clause!");
1602     StringRef Assumption = II->getName();
1603     if (ACMI.StartsWith)
1604       Assumption = Assumption.substr(ACMI.Identifier.size());
1605     Assumptions.push_back(Assumption);
1606   }
1607 
1608   Actions.ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions, SkippedClauses);
1609 }
1610 
ParseOpenMPEndAssumesDirective(SourceLocation Loc)1611 void Parser::ParseOpenMPEndAssumesDirective(SourceLocation Loc) {
1612   if (Actions.isInOpenMPAssumeScope())
1613     Actions.ActOnOpenMPEndAssumesDirective();
1614   else
1615     Diag(Loc, diag::err_expected_begin_assumes);
1616 }
1617 
1618 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1619 ///
1620 ///    default-clause:
1621 ///         'default' '(' 'none' | 'shared'  | 'firstprivate' ')
1622 ///
1623 ///    proc_bind-clause:
1624 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1625 ///
1626 ///    device_type-clause:
1627 ///         'device_type' '(' 'host' | 'nohost' | 'any' )'
1628 namespace {
1629 struct SimpleClauseData {
1630   unsigned Type;
1631   SourceLocation Loc;
1632   SourceLocation LOpen;
1633   SourceLocation TypeLoc;
1634   SourceLocation RLoc;
SimpleClauseData__anon831cac940c11::SimpleClauseData1635   SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1636                    SourceLocation TypeLoc, SourceLocation RLoc)
1637       : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1638 };
1639 } // anonymous namespace
1640 
1641 static Optional<SimpleClauseData>
parseOpenMPSimpleClause(Parser & P,OpenMPClauseKind Kind)1642 parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) {
1643   const Token &Tok = P.getCurToken();
1644   SourceLocation Loc = Tok.getLocation();
1645   SourceLocation LOpen = P.ConsumeToken();
1646   // Parse '('.
1647   BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
1648   if (T.expectAndConsume(diag::err_expected_lparen_after,
1649                          getOpenMPClauseName(Kind).data()))
1650     return llvm::None;
1651 
1652   unsigned Type = getOpenMPSimpleClauseType(
1653       Kind, Tok.isAnnotation() ? "" : P.getPreprocessor().getSpelling(Tok),
1654       P.getLangOpts().OpenMP);
1655   SourceLocation TypeLoc = Tok.getLocation();
1656   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1657       Tok.isNot(tok::annot_pragma_openmp_end))
1658     P.ConsumeAnyToken();
1659 
1660   // Parse ')'.
1661   SourceLocation RLoc = Tok.getLocation();
1662   if (!T.consumeClose())
1663     RLoc = T.getCloseLocation();
1664 
1665   return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc);
1666 }
1667 
ParseOMPDeclareTargetClauses(Sema::DeclareTargetContextInfo & DTCI)1668 void Parser::ParseOMPDeclareTargetClauses(
1669     Sema::DeclareTargetContextInfo &DTCI) {
1670   SourceLocation DeviceTypeLoc;
1671   bool RequiresToOrLinkClause = false;
1672   bool HasToOrLinkClause = false;
1673   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1674     OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1675     bool HasIdentifier = Tok.is(tok::identifier);
1676     if (HasIdentifier) {
1677       // If we see any clause we need a to or link clause.
1678       RequiresToOrLinkClause = true;
1679       IdentifierInfo *II = Tok.getIdentifierInfo();
1680       StringRef ClauseName = II->getName();
1681       bool IsDeviceTypeClause =
1682           getLangOpts().OpenMP >= 50 &&
1683           getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1684 
1685       bool IsToOrLinkClause =
1686           OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1687       assert((!IsDeviceTypeClause || !IsToOrLinkClause) && "Cannot be both!");
1688 
1689       if (!IsDeviceTypeClause && DTCI.Kind == OMPD_begin_declare_target) {
1690         Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1691             << ClauseName << 0;
1692         break;
1693       }
1694       if (!IsDeviceTypeClause && !IsToOrLinkClause) {
1695         Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1696             << ClauseName << (getLangOpts().OpenMP >= 50 ? 2 : 1);
1697         break;
1698       }
1699 
1700       if (IsToOrLinkClause)
1701         HasToOrLinkClause = true;
1702 
1703       // Parse 'device_type' clause and go to next clause if any.
1704       if (IsDeviceTypeClause) {
1705         Optional<SimpleClauseData> DevTypeData =
1706             parseOpenMPSimpleClause(*this, OMPC_device_type);
1707         if (DevTypeData.hasValue()) {
1708           if (DeviceTypeLoc.isValid()) {
1709             // We already saw another device_type clause, diagnose it.
1710             Diag(DevTypeData.getValue().Loc,
1711                  diag::warn_omp_more_one_device_type_clause);
1712             break;
1713           }
1714           switch (static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) {
1715           case OMPC_DEVICE_TYPE_any:
1716             DTCI.DT = OMPDeclareTargetDeclAttr::DT_Any;
1717             break;
1718           case OMPC_DEVICE_TYPE_host:
1719             DTCI.DT = OMPDeclareTargetDeclAttr::DT_Host;
1720             break;
1721           case OMPC_DEVICE_TYPE_nohost:
1722             DTCI.DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1723             break;
1724           case OMPC_DEVICE_TYPE_unknown:
1725             llvm_unreachable("Unexpected device_type");
1726           }
1727           DeviceTypeLoc = DevTypeData.getValue().Loc;
1728         }
1729         continue;
1730       }
1731       ConsumeToken();
1732     }
1733 
1734     if (DTCI.Kind == OMPD_declare_target || HasIdentifier) {
1735       auto &&Callback = [this, MT, &DTCI](CXXScopeSpec &SS,
1736                                           DeclarationNameInfo NameInfo) {
1737         NamedDecl *ND =
1738             Actions.lookupOpenMPDeclareTargetName(getCurScope(), SS, NameInfo);
1739         if (!ND)
1740           return;
1741         Sema::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.getLoc()};
1742         bool FirstMapping = DTCI.ExplicitlyMapped.try_emplace(ND, MI).second;
1743         if (!FirstMapping)
1744           Diag(NameInfo.getLoc(), diag::err_omp_declare_target_multiple)
1745               << NameInfo.getName();
1746       };
1747       if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1748                                    /*AllowScopeSpecifier=*/true))
1749         break;
1750     }
1751 
1752     if (Tok.is(tok::l_paren)) {
1753       Diag(Tok,
1754            diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1755       break;
1756     }
1757     if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1758       Diag(Tok,
1759            diag::err_omp_declare_target_unexpected_clause_after_implicit_to);
1760       break;
1761     }
1762 
1763     // Consume optional ','.
1764     if (Tok.is(tok::comma))
1765       ConsumeToken();
1766   }
1767 
1768   // For declare target require at least 'to' or 'link' to be present.
1769   if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkClause &&
1770       !HasToOrLinkClause)
1771     Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause);
1772 
1773   SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1774 }
1775 
skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind)1776 void Parser::skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind) {
1777   // The last seen token is annot_pragma_openmp_end - need to check for
1778   // extra tokens.
1779   if (Tok.is(tok::annot_pragma_openmp_end))
1780     return;
1781 
1782   Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1783       << getOpenMPDirectiveName(DKind);
1784   while (Tok.isNot(tok::annot_pragma_openmp_end))
1785     ConsumeAnyToken();
1786 }
1787 
parseOMPEndDirective(OpenMPDirectiveKind BeginKind,OpenMPDirectiveKind ExpectedKind,OpenMPDirectiveKind FoundKind,SourceLocation BeginLoc,SourceLocation FoundLoc,bool SkipUntilOpenMPEnd)1788 void Parser::parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
1789                                   OpenMPDirectiveKind ExpectedKind,
1790                                   OpenMPDirectiveKind FoundKind,
1791                                   SourceLocation BeginLoc,
1792                                   SourceLocation FoundLoc,
1793                                   bool SkipUntilOpenMPEnd) {
1794   int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1795 
1796   if (FoundKind == ExpectedKind) {
1797     ConsumeAnyToken();
1798     skipUntilPragmaOpenMPEnd(ExpectedKind);
1799     return;
1800   }
1801 
1802   Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1803       << DiagSelection;
1804   Diag(BeginLoc, diag::note_matching)
1805       << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind) + "'").str();
1806   if (SkipUntilOpenMPEnd)
1807     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1808 }
1809 
ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,OpenMPDirectiveKind EndDKind,SourceLocation DKLoc)1810 void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,
1811                                                OpenMPDirectiveKind EndDKind,
1812                                                SourceLocation DKLoc) {
1813   parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1814                        Tok.getLocation(),
1815                        /* SkipUntilOpenMPEnd */ false);
1816   // Skip the last annot_pragma_openmp_end.
1817   if (Tok.is(tok::annot_pragma_openmp_end))
1818     ConsumeAnnotationToken();
1819 }
1820 
1821 /// Parsing of declarative OpenMP directives.
1822 ///
1823 ///       threadprivate-directive:
1824 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
1825 ///         annot_pragma_openmp_end
1826 ///
1827 ///       allocate-directive:
1828 ///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
1829 ///         annot_pragma_openmp_end
1830 ///
1831 ///       declare-reduction-directive:
1832 ///        annot_pragma_openmp 'declare' 'reduction' [...]
1833 ///        annot_pragma_openmp_end
1834 ///
1835 ///       declare-mapper-directive:
1836 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1837 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1838 ///         annot_pragma_openmp_end
1839 ///
1840 ///       declare-simd-directive:
1841 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
1842 ///         annot_pragma_openmp_end
1843 ///         <function declaration/definition>
1844 ///
1845 ///       requires directive:
1846 ///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
1847 ///         annot_pragma_openmp_end
1848 ///
1849 ///       assumes directive:
1850 ///         annot_pragma_openmp 'assumes' <clause> [[[,] <clause>] ... ]
1851 ///         annot_pragma_openmp_end
1852 ///       or
1853 ///         annot_pragma_openmp 'begin assumes' <clause> [[[,] <clause>] ... ]
1854 ///         annot_pragma_openmp 'end assumes'
1855 ///         annot_pragma_openmp_end
1856 ///
ParseOpenMPDeclarativeDirectiveWithExtDecl(AccessSpecifier & AS,ParsedAttributesWithRange & Attrs,bool Delayed,DeclSpec::TST TagType,Decl * Tag)1857 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
1858     AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
1859     DeclSpec::TST TagType, Decl *Tag) {
1860   assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1861          "Not an OpenMP directive!");
1862   ParsingOpenMPDirectiveRAII DirScope(*this);
1863   ParenBraceBracketBalancer BalancerRAIIObj(*this);
1864 
1865   SourceLocation Loc;
1866   OpenMPDirectiveKind DKind;
1867   if (Delayed) {
1868     TentativeParsingAction TPA(*this);
1869     Loc = ConsumeAnnotationToken();
1870     DKind = parseOpenMPDirectiveKind(*this);
1871     if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1872       // Need to delay parsing until completion of the parent class.
1873       TPA.Revert();
1874       CachedTokens Toks;
1875       unsigned Cnt = 1;
1876       Toks.push_back(Tok);
1877       while (Cnt && Tok.isNot(tok::eof)) {
1878         (void)ConsumeAnyToken();
1879         if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
1880           ++Cnt;
1881         else if (Tok.is(tok::annot_pragma_openmp_end))
1882           --Cnt;
1883         Toks.push_back(Tok);
1884       }
1885       // Skip last annot_pragma_openmp_end.
1886       if (Cnt == 0)
1887         (void)ConsumeAnyToken();
1888       auto *LP = new LateParsedPragma(this, AS);
1889       LP->takeToks(Toks);
1890       getCurrentClass().LateParsedDeclarations.push_back(LP);
1891       return nullptr;
1892     }
1893     TPA.Commit();
1894   } else {
1895     Loc = ConsumeAnnotationToken();
1896     DKind = parseOpenMPDirectiveKind(*this);
1897   }
1898 
1899   switch (DKind) {
1900   case OMPD_threadprivate: {
1901     ConsumeToken();
1902     DeclDirectiveListParserHelper Helper(this, DKind);
1903     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1904                                   /*AllowScopeSpecifier=*/true)) {
1905       skipUntilPragmaOpenMPEnd(DKind);
1906       // Skip the last annot_pragma_openmp_end.
1907       ConsumeAnnotationToken();
1908       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
1909                                                        Helper.getIdentifiers());
1910     }
1911     break;
1912   }
1913   case OMPD_allocate: {
1914     ConsumeToken();
1915     DeclDirectiveListParserHelper Helper(this, DKind);
1916     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1917                                   /*AllowScopeSpecifier=*/true)) {
1918       SmallVector<OMPClause *, 1> Clauses;
1919       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1920         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1921                     llvm::omp::Clause_enumSize + 1>
1922             FirstClauses(llvm::omp::Clause_enumSize + 1);
1923         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1924           OpenMPClauseKind CKind =
1925               Tok.isAnnotation() ? OMPC_unknown
1926                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
1927           Actions.StartOpenMPClause(CKind);
1928           OMPClause *Clause = ParseOpenMPClause(
1929               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
1930           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1931                     StopBeforeMatch);
1932           FirstClauses[unsigned(CKind)].setInt(true);
1933           if (Clause != nullptr)
1934             Clauses.push_back(Clause);
1935           if (Tok.is(tok::annot_pragma_openmp_end)) {
1936             Actions.EndOpenMPClause();
1937             break;
1938           }
1939           // Skip ',' if any.
1940           if (Tok.is(tok::comma))
1941             ConsumeToken();
1942           Actions.EndOpenMPClause();
1943         }
1944         skipUntilPragmaOpenMPEnd(DKind);
1945       }
1946       // Skip the last annot_pragma_openmp_end.
1947       ConsumeAnnotationToken();
1948       return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
1949                                                   Clauses);
1950     }
1951     break;
1952   }
1953   case OMPD_requires: {
1954     SourceLocation StartLoc = ConsumeToken();
1955     SmallVector<OMPClause *, 5> Clauses;
1956     SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1957                 llvm::omp::Clause_enumSize + 1>
1958         FirstClauses(llvm::omp::Clause_enumSize + 1);
1959     if (Tok.is(tok::annot_pragma_openmp_end)) {
1960       Diag(Tok, diag::err_omp_expected_clause)
1961           << getOpenMPDirectiveName(OMPD_requires);
1962       break;
1963     }
1964     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1965       OpenMPClauseKind CKind = Tok.isAnnotation()
1966                                    ? OMPC_unknown
1967                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
1968       Actions.StartOpenMPClause(CKind);
1969       OMPClause *Clause = ParseOpenMPClause(
1970           OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt());
1971       SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1972                 StopBeforeMatch);
1973       FirstClauses[unsigned(CKind)].setInt(true);
1974       if (Clause != nullptr)
1975         Clauses.push_back(Clause);
1976       if (Tok.is(tok::annot_pragma_openmp_end)) {
1977         Actions.EndOpenMPClause();
1978         break;
1979       }
1980       // Skip ',' if any.
1981       if (Tok.is(tok::comma))
1982         ConsumeToken();
1983       Actions.EndOpenMPClause();
1984     }
1985     // Consume final annot_pragma_openmp_end
1986     if (Clauses.empty()) {
1987       Diag(Tok, diag::err_omp_expected_clause)
1988           << getOpenMPDirectiveName(OMPD_requires);
1989       ConsumeAnnotationToken();
1990       return nullptr;
1991     }
1992     ConsumeAnnotationToken();
1993     return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
1994   }
1995   case OMPD_assumes:
1996   case OMPD_begin_assumes:
1997     ParseOpenMPAssumesDirective(DKind, ConsumeToken());
1998     break;
1999   case OMPD_end_assumes:
2000     ParseOpenMPEndAssumesDirective(ConsumeToken());
2001     break;
2002   case OMPD_declare_reduction:
2003     ConsumeToken();
2004     if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2005       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2006       // Skip the last annot_pragma_openmp_end.
2007       ConsumeAnnotationToken();
2008       return Res;
2009     }
2010     break;
2011   case OMPD_declare_mapper: {
2012     ConsumeToken();
2013     if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2014       // Skip the last annot_pragma_openmp_end.
2015       ConsumeAnnotationToken();
2016       return Res;
2017     }
2018     break;
2019   }
2020   case OMPD_begin_declare_variant: {
2021     // The syntax is:
2022     // { #pragma omp begin declare variant clause }
2023     // <function-declaration-or-definition-sequence>
2024     // { #pragma omp end declare variant }
2025     //
2026     ConsumeToken();
2027     OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
2028     ASTContext &ASTCtx = Actions.getASTContext();
2029     OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
2030     if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI))
2031       break;
2032 
2033     // Skip last tokens.
2034     skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
2035 
2036     ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2037 
2038     VariantMatchInfo VMI;
2039     TI.getAsVariantMatchInfo(ASTCtx, VMI);
2040 
2041     std::function<void(StringRef)> DiagUnknownTrait = [this, Loc](
2042                                                           StringRef ISATrait) {
2043       // TODO Track the selector locations in a way that is accessible here to
2044       // improve the diagnostic location.
2045       Diag(Loc, diag::warn_unknown_begin_declare_variant_isa_trait) << ISATrait;
2046     };
2047     TargetOMPContext OMPCtx(ASTCtx, std::move(DiagUnknownTrait),
2048                             /* CurrentFunctionDecl */ nullptr);
2049 
2050     if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
2051       Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI);
2052       break;
2053     }
2054 
2055     // Elide all the code till the matching end declare variant was found.
2056     unsigned Nesting = 1;
2057     SourceLocation DKLoc;
2058     OpenMPDirectiveKind DK = OMPD_unknown;
2059     do {
2060       DKLoc = Tok.getLocation();
2061       DK = parseOpenMPDirectiveKind(*this);
2062       if (DK == OMPD_end_declare_variant)
2063         --Nesting;
2064       else if (DK == OMPD_begin_declare_variant)
2065         ++Nesting;
2066       if (!Nesting || isEofOrEom())
2067         break;
2068       ConsumeAnyToken();
2069     } while (true);
2070 
2071     parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
2072                          DK, Loc, DKLoc, /* SkipUntilOpenMPEnd */ true);
2073     if (isEofOrEom())
2074       return nullptr;
2075     break;
2076   }
2077   case OMPD_end_declare_variant: {
2078     if (Actions.isInOpenMPDeclareVariantScope())
2079       Actions.ActOnOpenMPEndDeclareVariant();
2080     else
2081       Diag(Loc, diag::err_expected_begin_declare_variant);
2082     ConsumeToken();
2083     break;
2084   }
2085   case OMPD_declare_variant:
2086   case OMPD_declare_simd: {
2087     // The syntax is:
2088     // { #pragma omp declare {simd|variant} }
2089     // <function-declaration-or-definition>
2090     //
2091     CachedTokens Toks;
2092     Toks.push_back(Tok);
2093     ConsumeToken();
2094     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2095       Toks.push_back(Tok);
2096       ConsumeAnyToken();
2097     }
2098     Toks.push_back(Tok);
2099     ConsumeAnyToken();
2100 
2101     DeclGroupPtrTy Ptr;
2102     if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2103       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2104                                                        TagType, Tag);
2105     } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2106       // Here we expect to see some function declaration.
2107       if (AS == AS_none) {
2108         assert(TagType == DeclSpec::TST_unspecified);
2109         MaybeParseCXX11Attributes(Attrs);
2110         ParsingDeclSpec PDS(*this);
2111         Ptr = ParseExternalDeclaration(Attrs, &PDS);
2112       } else {
2113         Ptr =
2114             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2115       }
2116     }
2117     if (!Ptr) {
2118       Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2119           << (DKind == OMPD_declare_simd ? 0 : 1);
2120       return DeclGroupPtrTy();
2121     }
2122     if (DKind == OMPD_declare_simd)
2123       return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2124     assert(DKind == OMPD_declare_variant &&
2125            "Expected declare variant directive only");
2126     ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2127     return Ptr;
2128   }
2129   case OMPD_begin_declare_target:
2130   case OMPD_declare_target: {
2131     SourceLocation DTLoc = ConsumeAnyToken();
2132     bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2133     bool HasImplicitMappings =
2134         DKind == OMPD_begin_declare_target || !HasClauses;
2135     Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2136     if (HasClauses)
2137       ParseOMPDeclareTargetClauses(DTCI);
2138 
2139     // Skip the last annot_pragma_openmp_end.
2140     ConsumeAnyToken();
2141 
2142     if (HasImplicitMappings) {
2143       Actions.ActOnStartOpenMPDeclareTargetContext(DTCI);
2144       return nullptr;
2145     }
2146 
2147     Actions.ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2148     llvm::SmallVector<Decl *, 4> Decls;
2149     for (auto &It : DTCI.ExplicitlyMapped)
2150       Decls.push_back(It.first);
2151     return Actions.BuildDeclaratorGroup(Decls);
2152   }
2153   case OMPD_end_declare_target: {
2154     if (!Actions.isInOpenMPDeclareTargetContext()) {
2155       Diag(Tok, diag::err_omp_unexpected_directive)
2156           << 1 << getOpenMPDirectiveName(DKind);
2157       break;
2158     }
2159     const Sema::DeclareTargetContextInfo &DTCI =
2160         Actions.ActOnOpenMPEndDeclareTargetDirective();
2161     ParseOMPEndDeclareTargetDirective(DTCI.Kind, DKind, DTCI.Loc);
2162     return nullptr;
2163   }
2164   case OMPD_unknown:
2165     Diag(Tok, diag::err_omp_unknown_directive);
2166     break;
2167   case OMPD_parallel:
2168   case OMPD_simd:
2169   case OMPD_tile:
2170   case OMPD_unroll:
2171   case OMPD_task:
2172   case OMPD_taskyield:
2173   case OMPD_barrier:
2174   case OMPD_taskwait:
2175   case OMPD_taskgroup:
2176   case OMPD_flush:
2177   case OMPD_depobj:
2178   case OMPD_scan:
2179   case OMPD_for:
2180   case OMPD_for_simd:
2181   case OMPD_sections:
2182   case OMPD_section:
2183   case OMPD_single:
2184   case OMPD_master:
2185   case OMPD_ordered:
2186   case OMPD_critical:
2187   case OMPD_parallel_for:
2188   case OMPD_parallel_for_simd:
2189   case OMPD_parallel_sections:
2190   case OMPD_parallel_master:
2191   case OMPD_atomic:
2192   case OMPD_target:
2193   case OMPD_teams:
2194   case OMPD_cancellation_point:
2195   case OMPD_cancel:
2196   case OMPD_target_data:
2197   case OMPD_target_enter_data:
2198   case OMPD_target_exit_data:
2199   case OMPD_target_parallel:
2200   case OMPD_target_parallel_for:
2201   case OMPD_taskloop:
2202   case OMPD_taskloop_simd:
2203   case OMPD_master_taskloop:
2204   case OMPD_master_taskloop_simd:
2205   case OMPD_parallel_master_taskloop:
2206   case OMPD_parallel_master_taskloop_simd:
2207   case OMPD_distribute:
2208   case OMPD_target_update:
2209   case OMPD_distribute_parallel_for:
2210   case OMPD_distribute_parallel_for_simd:
2211   case OMPD_distribute_simd:
2212   case OMPD_target_parallel_for_simd:
2213   case OMPD_target_simd:
2214   case OMPD_teams_distribute:
2215   case OMPD_teams_distribute_simd:
2216   case OMPD_teams_distribute_parallel_for_simd:
2217   case OMPD_teams_distribute_parallel_for:
2218   case OMPD_target_teams:
2219   case OMPD_target_teams_distribute:
2220   case OMPD_target_teams_distribute_parallel_for:
2221   case OMPD_target_teams_distribute_parallel_for_simd:
2222   case OMPD_target_teams_distribute_simd:
2223   case OMPD_dispatch:
2224   case OMPD_masked:
2225     Diag(Tok, diag::err_omp_unexpected_directive)
2226         << 1 << getOpenMPDirectiveName(DKind);
2227     break;
2228   default:
2229     break;
2230   }
2231   while (Tok.isNot(tok::annot_pragma_openmp_end))
2232     ConsumeAnyToken();
2233   ConsumeAnyToken();
2234   return nullptr;
2235 }
2236 
2237 /// Parsing of declarative or executable OpenMP directives.
2238 ///
2239 ///       threadprivate-directive:
2240 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
2241 ///         annot_pragma_openmp_end
2242 ///
2243 ///       allocate-directive:
2244 ///         annot_pragma_openmp 'allocate' simple-variable-list
2245 ///         annot_pragma_openmp_end
2246 ///
2247 ///       declare-reduction-directive:
2248 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
2249 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
2250 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
2251 ///         annot_pragma_openmp_end
2252 ///
2253 ///       declare-mapper-directive:
2254 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2255 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2256 ///         annot_pragma_openmp_end
2257 ///
2258 ///       executable-directive:
2259 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
2260 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
2261 ///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
2262 ///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
2263 ///         'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
2264 ///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
2265 ///         'master taskloop' | 'master taskloop simd' | 'parallel master
2266 ///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
2267 ///         enter data' | 'target exit data' | 'target parallel' | 'target
2268 ///         parallel for' | 'target update' | 'distribute parallel for' |
2269 ///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
2270 ///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
2271 ///         simd' | 'teams distribute parallel for simd' | 'teams distribute
2272 ///         parallel for' | 'target teams' | 'target teams distribute' | 'target
2273 ///         teams distribute parallel for' | 'target teams distribute parallel
2274 ///         for simd' | 'target teams distribute simd' | 'masked' {clause}
2275 ///         annot_pragma_openmp_end
2276 ///
2277 StmtResult
ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx)2278 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
2279   assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2280          "Not an OpenMP directive!");
2281   ParsingOpenMPDirectiveRAII DirScope(*this);
2282   ParenBraceBracketBalancer BalancerRAIIObj(*this);
2283   SmallVector<OMPClause *, 5> Clauses;
2284   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2285               llvm::omp::Clause_enumSize + 1>
2286       FirstClauses(llvm::omp::Clause_enumSize + 1);
2287   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
2288                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
2289   SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
2290   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
2291   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
2292   // Name of critical directive.
2293   DeclarationNameInfo DirName;
2294   StmtResult Directive = StmtError();
2295   bool HasAssociatedStatement = true;
2296 
2297   switch (DKind) {
2298   case OMPD_threadprivate: {
2299     // FIXME: Should this be permitted in C++?
2300     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2301         ParsedStmtContext()) {
2302       Diag(Tok, diag::err_omp_immediate_directive)
2303           << getOpenMPDirectiveName(DKind) << 0;
2304     }
2305     ConsumeToken();
2306     DeclDirectiveListParserHelper Helper(this, DKind);
2307     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2308                                   /*AllowScopeSpecifier=*/false)) {
2309       skipUntilPragmaOpenMPEnd(DKind);
2310       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
2311           Loc, Helper.getIdentifiers());
2312       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2313     }
2314     SkipUntil(tok::annot_pragma_openmp_end);
2315     break;
2316   }
2317   case OMPD_allocate: {
2318     // FIXME: Should this be permitted in C++?
2319     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2320         ParsedStmtContext()) {
2321       Diag(Tok, diag::err_omp_immediate_directive)
2322           << getOpenMPDirectiveName(DKind) << 0;
2323     }
2324     ConsumeToken();
2325     DeclDirectiveListParserHelper Helper(this, DKind);
2326     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2327                                   /*AllowScopeSpecifier=*/false)) {
2328       SmallVector<OMPClause *, 1> Clauses;
2329       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2330         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2331                     llvm::omp::Clause_enumSize + 1>
2332             FirstClauses(llvm::omp::Clause_enumSize + 1);
2333         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2334           OpenMPClauseKind CKind =
2335               Tok.isAnnotation() ? OMPC_unknown
2336                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
2337           Actions.StartOpenMPClause(CKind);
2338           OMPClause *Clause = ParseOpenMPClause(
2339               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2340           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2341                     StopBeforeMatch);
2342           FirstClauses[unsigned(CKind)].setInt(true);
2343           if (Clause != nullptr)
2344             Clauses.push_back(Clause);
2345           if (Tok.is(tok::annot_pragma_openmp_end)) {
2346             Actions.EndOpenMPClause();
2347             break;
2348           }
2349           // Skip ',' if any.
2350           if (Tok.is(tok::comma))
2351             ConsumeToken();
2352           Actions.EndOpenMPClause();
2353         }
2354         skipUntilPragmaOpenMPEnd(DKind);
2355       }
2356       DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2357           Loc, Helper.getIdentifiers(), Clauses);
2358       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2359     }
2360     SkipUntil(tok::annot_pragma_openmp_end);
2361     break;
2362   }
2363   case OMPD_declare_reduction:
2364     ConsumeToken();
2365     if (DeclGroupPtrTy Res =
2366             ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
2367       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2368       ConsumeAnyToken();
2369       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2370     } else {
2371       SkipUntil(tok::annot_pragma_openmp_end);
2372     }
2373     break;
2374   case OMPD_declare_mapper: {
2375     ConsumeToken();
2376     if (DeclGroupPtrTy Res =
2377             ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2378       // Skip the last annot_pragma_openmp_end.
2379       ConsumeAnnotationToken();
2380       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2381     } else {
2382       SkipUntil(tok::annot_pragma_openmp_end);
2383     }
2384     break;
2385   }
2386   case OMPD_flush:
2387   case OMPD_depobj:
2388   case OMPD_scan:
2389   case OMPD_taskyield:
2390   case OMPD_barrier:
2391   case OMPD_taskwait:
2392   case OMPD_cancellation_point:
2393   case OMPD_cancel:
2394   case OMPD_target_enter_data:
2395   case OMPD_target_exit_data:
2396   case OMPD_target_update:
2397   case OMPD_interop:
2398     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2399         ParsedStmtContext()) {
2400       Diag(Tok, diag::err_omp_immediate_directive)
2401           << getOpenMPDirectiveName(DKind) << 0;
2402     }
2403     HasAssociatedStatement = false;
2404     // Fall through for further analysis.
2405     LLVM_FALLTHROUGH;
2406   case OMPD_parallel:
2407   case OMPD_simd:
2408   case OMPD_tile:
2409   case OMPD_unroll:
2410   case OMPD_for:
2411   case OMPD_for_simd:
2412   case OMPD_sections:
2413   case OMPD_single:
2414   case OMPD_section:
2415   case OMPD_master:
2416   case OMPD_critical:
2417   case OMPD_parallel_for:
2418   case OMPD_parallel_for_simd:
2419   case OMPD_parallel_sections:
2420   case OMPD_parallel_master:
2421   case OMPD_task:
2422   case OMPD_ordered:
2423   case OMPD_atomic:
2424   case OMPD_target:
2425   case OMPD_teams:
2426   case OMPD_taskgroup:
2427   case OMPD_target_data:
2428   case OMPD_target_parallel:
2429   case OMPD_target_parallel_for:
2430   case OMPD_taskloop:
2431   case OMPD_taskloop_simd:
2432   case OMPD_master_taskloop:
2433   case OMPD_master_taskloop_simd:
2434   case OMPD_parallel_master_taskloop:
2435   case OMPD_parallel_master_taskloop_simd:
2436   case OMPD_distribute:
2437   case OMPD_distribute_parallel_for:
2438   case OMPD_distribute_parallel_for_simd:
2439   case OMPD_distribute_simd:
2440   case OMPD_target_parallel_for_simd:
2441   case OMPD_target_simd:
2442   case OMPD_teams_distribute:
2443   case OMPD_teams_distribute_simd:
2444   case OMPD_teams_distribute_parallel_for_simd:
2445   case OMPD_teams_distribute_parallel_for:
2446   case OMPD_target_teams:
2447   case OMPD_target_teams_distribute:
2448   case OMPD_target_teams_distribute_parallel_for:
2449   case OMPD_target_teams_distribute_parallel_for_simd:
2450   case OMPD_target_teams_distribute_simd:
2451   case OMPD_dispatch:
2452   case OMPD_masked: {
2453     // Special processing for flush and depobj clauses.
2454     Token ImplicitTok;
2455     bool ImplicitClauseAllowed = false;
2456     if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2457       ImplicitTok = Tok;
2458       ImplicitClauseAllowed = true;
2459     }
2460     ConsumeToken();
2461     // Parse directive name of the 'critical' directive if any.
2462     if (DKind == OMPD_critical) {
2463       BalancedDelimiterTracker T(*this, tok::l_paren,
2464                                  tok::annot_pragma_openmp_end);
2465       if (!T.consumeOpen()) {
2466         if (Tok.isAnyIdentifier()) {
2467           DirName =
2468               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2469           ConsumeAnyToken();
2470         } else {
2471           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2472         }
2473         T.consumeClose();
2474       }
2475     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2476       CancelRegion = parseOpenMPDirectiveKind(*this);
2477       if (Tok.isNot(tok::annot_pragma_openmp_end))
2478         ConsumeToken();
2479     }
2480 
2481     if (isOpenMPLoopDirective(DKind))
2482       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2483     if (isOpenMPSimdDirective(DKind))
2484       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2485     ParseScope OMPDirectiveScope(this, ScopeFlags);
2486     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
2487 
2488     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2489       bool HasImplicitClause = false;
2490       if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2491         HasImplicitClause = true;
2492         // Push copy of the current token back to stream to properly parse
2493         // pseudo-clause OMPFlushClause or OMPDepobjClause.
2494         PP.EnterToken(Tok, /*IsReinject*/ true);
2495         PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
2496         ConsumeAnyToken();
2497       }
2498       OpenMPClauseKind CKind = Tok.isAnnotation()
2499                                    ? OMPC_unknown
2500                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2501       if (HasImplicitClause) {
2502         assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2503         if (DKind == OMPD_flush) {
2504           CKind = OMPC_flush;
2505         } else {
2506           assert(DKind == OMPD_depobj &&
2507                  "Expected flush or depobj directives.");
2508           CKind = OMPC_depobj;
2509         }
2510       }
2511       // No more implicit clauses allowed.
2512       ImplicitClauseAllowed = false;
2513       Actions.StartOpenMPClause(CKind);
2514       HasImplicitClause = false;
2515       OMPClause *Clause = ParseOpenMPClause(
2516           DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
2517       FirstClauses[unsigned(CKind)].setInt(true);
2518       if (Clause) {
2519         FirstClauses[unsigned(CKind)].setPointer(Clause);
2520         Clauses.push_back(Clause);
2521       }
2522 
2523       // Skip ',' if any.
2524       if (Tok.is(tok::comma))
2525         ConsumeToken();
2526       Actions.EndOpenMPClause();
2527     }
2528     // End location of the directive.
2529     EndLoc = Tok.getLocation();
2530     // Consume final annot_pragma_openmp_end.
2531     ConsumeAnnotationToken();
2532 
2533     // OpenMP [2.13.8, ordered Construct, Syntax]
2534     // If the depend clause is specified, the ordered construct is a stand-alone
2535     // directive.
2536     if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) {
2537       if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2538           ParsedStmtContext()) {
2539         Diag(Loc, diag::err_omp_immediate_directive)
2540             << getOpenMPDirectiveName(DKind) << 1
2541             << getOpenMPClauseName(OMPC_depend);
2542       }
2543       HasAssociatedStatement = false;
2544     }
2545 
2546     if (DKind == OMPD_tile && !FirstClauses[unsigned(OMPC_sizes)].getInt()) {
2547       Diag(Loc, diag::err_omp_required_clause)
2548           << getOpenMPDirectiveName(OMPD_tile) << "sizes";
2549     }
2550 
2551     StmtResult AssociatedStmt;
2552     if (HasAssociatedStatement) {
2553       // The body is a block scope like in Lambdas and Blocks.
2554       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2555       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2556       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2557       // should have at least one compound statement scope within it.
2558       ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2559       {
2560         Sema::CompoundScopeRAII Scope(Actions);
2561         AssociatedStmt = ParseStatement();
2562 
2563         if (AssociatedStmt.isUsable() && isOpenMPLoopDirective(DKind) &&
2564             getLangOpts().OpenMPIRBuilder)
2565           AssociatedStmt =
2566               Actions.ActOnOpenMPCanonicalLoop(AssociatedStmt.get());
2567       }
2568       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2569     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2570                DKind == OMPD_target_exit_data) {
2571       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2572       AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2573                         Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2574                                                   /*isStmtExpr=*/false));
2575       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2576     }
2577     Directive = Actions.ActOnOpenMPExecutableDirective(
2578         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2579         EndLoc);
2580 
2581     // Exit scope.
2582     Actions.EndOpenMPDSABlock(Directive.get());
2583     OMPDirectiveScope.Exit();
2584     break;
2585   }
2586   case OMPD_declare_simd:
2587   case OMPD_declare_target:
2588   case OMPD_begin_declare_target:
2589   case OMPD_end_declare_target:
2590   case OMPD_requires:
2591   case OMPD_begin_declare_variant:
2592   case OMPD_end_declare_variant:
2593   case OMPD_declare_variant:
2594     Diag(Tok, diag::err_omp_unexpected_directive)
2595         << 1 << getOpenMPDirectiveName(DKind);
2596     SkipUntil(tok::annot_pragma_openmp_end);
2597     break;
2598   case OMPD_unknown:
2599   default:
2600     Diag(Tok, diag::err_omp_unknown_directive);
2601     SkipUntil(tok::annot_pragma_openmp_end);
2602     break;
2603   }
2604   return Directive;
2605 }
2606 
2607 // Parses simple list:
2608 //   simple-variable-list:
2609 //         '(' id-expression {, id-expression} ')'
2610 //
ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,const llvm::function_ref<void (CXXScopeSpec &,DeclarationNameInfo)> & Callback,bool AllowScopeSpecifier)2611 bool Parser::ParseOpenMPSimpleVarList(
2612     OpenMPDirectiveKind Kind,
2613     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)>
2614         &Callback,
2615     bool AllowScopeSpecifier) {
2616   // Parse '('.
2617   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2618   if (T.expectAndConsume(diag::err_expected_lparen_after,
2619                          getOpenMPDirectiveName(Kind).data()))
2620     return true;
2621   bool IsCorrect = true;
2622   bool NoIdentIsFound = true;
2623 
2624   // Read tokens while ')' or annot_pragma_openmp_end is not found.
2625   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2626     CXXScopeSpec SS;
2627     UnqualifiedId Name;
2628     // Read var name.
2629     Token PrevTok = Tok;
2630     NoIdentIsFound = false;
2631 
2632     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
2633         ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2634                                        /*ObjectHadErrors=*/false, false)) {
2635       IsCorrect = false;
2636       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2637                 StopBeforeMatch);
2638     } else if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
2639                                   /*ObjectHadErrors=*/false, false, false,
2640                                   false, false, nullptr, Name)) {
2641       IsCorrect = false;
2642       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2643                 StopBeforeMatch);
2644     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2645                Tok.isNot(tok::annot_pragma_openmp_end)) {
2646       IsCorrect = false;
2647       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2648                 StopBeforeMatch);
2649       Diag(PrevTok.getLocation(), diag::err_expected)
2650           << tok::identifier
2651           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
2652     } else {
2653       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2654     }
2655     // Consume ','.
2656     if (Tok.is(tok::comma)) {
2657       ConsumeToken();
2658     }
2659   }
2660 
2661   if (NoIdentIsFound) {
2662     Diag(Tok, diag::err_expected) << tok::identifier;
2663     IsCorrect = false;
2664   }
2665 
2666   // Parse ')'.
2667   IsCorrect = !T.consumeClose() && IsCorrect;
2668 
2669   return !IsCorrect;
2670 }
2671 
ParseOpenMPSizesClause()2672 OMPClause *Parser::ParseOpenMPSizesClause() {
2673   SourceLocation ClauseNameLoc = ConsumeToken();
2674   SmallVector<Expr *, 4> ValExprs;
2675 
2676   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2677   if (T.consumeOpen()) {
2678     Diag(Tok, diag::err_expected) << tok::l_paren;
2679     return nullptr;
2680   }
2681 
2682   while (true) {
2683     ExprResult Val = ParseConstantExpression();
2684     if (!Val.isUsable()) {
2685       T.skipToEnd();
2686       return nullptr;
2687     }
2688 
2689     ValExprs.push_back(Val.get());
2690 
2691     if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
2692       break;
2693 
2694     ExpectAndConsume(tok::comma);
2695   }
2696 
2697   T.consumeClose();
2698 
2699   return Actions.ActOnOpenMPSizesClause(
2700       ValExprs, ClauseNameLoc, T.getOpenLocation(), T.getCloseLocation());
2701 }
2702 
ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind)2703 OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
2704   SourceLocation Loc = Tok.getLocation();
2705   ConsumeAnyToken();
2706 
2707   // Parse '('.
2708   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2709   if (T.expectAndConsume(diag::err_expected_lparen_after, "uses_allocator"))
2710     return nullptr;
2711   SmallVector<Sema::UsesAllocatorsData, 4> Data;
2712   do {
2713     ExprResult Allocator =
2714         getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
2715     if (Allocator.isInvalid()) {
2716       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2717                 StopBeforeMatch);
2718       break;
2719     }
2720     Sema::UsesAllocatorsData &D = Data.emplace_back();
2721     D.Allocator = Allocator.get();
2722     if (Tok.is(tok::l_paren)) {
2723       BalancedDelimiterTracker T(*this, tok::l_paren,
2724                                  tok::annot_pragma_openmp_end);
2725       T.consumeOpen();
2726       ExprResult AllocatorTraits =
2727           getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
2728       T.consumeClose();
2729       if (AllocatorTraits.isInvalid()) {
2730         SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2731                   StopBeforeMatch);
2732         break;
2733       }
2734       D.AllocatorTraits = AllocatorTraits.get();
2735       D.LParenLoc = T.getOpenLocation();
2736       D.RParenLoc = T.getCloseLocation();
2737     }
2738     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
2739       Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;
2740     // Parse ','
2741     if (Tok.is(tok::comma))
2742       ConsumeAnyToken();
2743   } while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end));
2744   T.consumeClose();
2745   return Actions.ActOnOpenMPUsesAllocatorClause(Loc, T.getOpenLocation(),
2746                                                 T.getCloseLocation(), Data);
2747 }
2748 
2749 /// Parsing of OpenMP clauses.
2750 ///
2751 ///    clause:
2752 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
2753 ///       default-clause | private-clause | firstprivate-clause | shared-clause
2754 ///       | linear-clause | aligned-clause | collapse-clause |
2755 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
2756 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
2757 ///       mergeable-clause | flush-clause | read-clause | write-clause |
2758 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
2759 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
2760 ///       thread_limit-clause | priority-clause | grainsize-clause |
2761 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
2762 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
2763 ///       in_reduction-clause | allocator-clause | allocate-clause |
2764 ///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
2765 ///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
2766 ///       exclusive-clause | uses_allocators-clause | use_device_addr-clause
2767 ///
ParseOpenMPClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,bool FirstClause)2768 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
2769                                      OpenMPClauseKind CKind, bool FirstClause) {
2770   OMPClauseKind = CKind;
2771   OMPClause *Clause = nullptr;
2772   bool ErrorFound = false;
2773   bool WrongDirective = false;
2774   // Check if clause is allowed for the given directive.
2775   if (CKind != OMPC_unknown &&
2776       !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
2777     Diag(Tok, diag::err_omp_unexpected_clause)
2778         << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
2779     ErrorFound = true;
2780     WrongDirective = true;
2781   }
2782 
2783   switch (CKind) {
2784   case OMPC_final:
2785   case OMPC_num_threads:
2786   case OMPC_safelen:
2787   case OMPC_simdlen:
2788   case OMPC_collapse:
2789   case OMPC_ordered:
2790   case OMPC_num_teams:
2791   case OMPC_thread_limit:
2792   case OMPC_priority:
2793   case OMPC_grainsize:
2794   case OMPC_num_tasks:
2795   case OMPC_hint:
2796   case OMPC_allocator:
2797   case OMPC_depobj:
2798   case OMPC_detach:
2799   case OMPC_novariants:
2800   case OMPC_nocontext:
2801   case OMPC_filter:
2802   case OMPC_partial:
2803     // OpenMP [2.5, Restrictions]
2804     //  At most one num_threads clause can appear on the directive.
2805     // OpenMP [2.8.1, simd construct, Restrictions]
2806     //  Only one safelen  clause can appear on a simd directive.
2807     //  Only one simdlen  clause can appear on a simd directive.
2808     //  Only one collapse clause can appear on a simd directive.
2809     // OpenMP [2.11.1, task Construct, Restrictions]
2810     //  At most one if clause can appear on the directive.
2811     //  At most one final clause can appear on the directive.
2812     // OpenMP [teams Construct, Restrictions]
2813     //  At most one num_teams clause can appear on the directive.
2814     //  At most one thread_limit clause can appear on the directive.
2815     // OpenMP [2.9.1, task Construct, Restrictions]
2816     // At most one priority clause can appear on the directive.
2817     // OpenMP [2.9.2, taskloop Construct, Restrictions]
2818     // At most one grainsize clause can appear on the directive.
2819     // OpenMP [2.9.2, taskloop Construct, Restrictions]
2820     // At most one num_tasks clause can appear on the directive.
2821     // OpenMP [2.11.3, allocate Directive, Restrictions]
2822     // At most one allocator clause can appear on the directive.
2823     // OpenMP 5.0, 2.10.1 task Construct, Restrictions.
2824     // At most one detach clause can appear on the directive.
2825     // OpenMP 5.1, 2.3.6 dispatch Construct, Restrictions.
2826     // At most one novariants clause can appear on a dispatch directive.
2827     // At most one nocontext clause can appear on a dispatch directive.
2828     if (!FirstClause) {
2829       Diag(Tok, diag::err_omp_more_one_clause)
2830           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2831       ErrorFound = true;
2832     }
2833 
2834     if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
2835         PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
2836       Clause = ParseOpenMPClause(CKind, WrongDirective);
2837     else
2838       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
2839     break;
2840   case OMPC_default:
2841   case OMPC_proc_bind:
2842   case OMPC_atomic_default_mem_order:
2843   case OMPC_order:
2844     // OpenMP [2.14.3.1, Restrictions]
2845     //  Only a single default clause may be specified on a parallel, task or
2846     //  teams directive.
2847     // OpenMP [2.5, parallel Construct, Restrictions]
2848     //  At most one proc_bind clause can appear on the directive.
2849     // OpenMP [5.0, Requires directive, Restrictions]
2850     //  At most one atomic_default_mem_order clause can appear
2851     //  on the directive
2852     if (!FirstClause && CKind != OMPC_order) {
2853       Diag(Tok, diag::err_omp_more_one_clause)
2854           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2855       ErrorFound = true;
2856     }
2857 
2858     Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
2859     break;
2860   case OMPC_device:
2861   case OMPC_schedule:
2862   case OMPC_dist_schedule:
2863   case OMPC_defaultmap:
2864     // OpenMP [2.7.1, Restrictions, p. 3]
2865     //  Only one schedule clause can appear on a loop directive.
2866     // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
2867     //  At most one defaultmap clause can appear on the directive.
2868     // OpenMP 5.0 [2.12.5, target construct, Restrictions]
2869     //  At most one device clause can appear on the directive.
2870     if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
2871         !FirstClause) {
2872       Diag(Tok, diag::err_omp_more_one_clause)
2873           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2874       ErrorFound = true;
2875     }
2876     LLVM_FALLTHROUGH;
2877   case OMPC_if:
2878     Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
2879     break;
2880   case OMPC_nowait:
2881   case OMPC_untied:
2882   case OMPC_mergeable:
2883   case OMPC_read:
2884   case OMPC_write:
2885   case OMPC_capture:
2886   case OMPC_seq_cst:
2887   case OMPC_acq_rel:
2888   case OMPC_acquire:
2889   case OMPC_release:
2890   case OMPC_relaxed:
2891   case OMPC_threads:
2892   case OMPC_simd:
2893   case OMPC_nogroup:
2894   case OMPC_unified_address:
2895   case OMPC_unified_shared_memory:
2896   case OMPC_reverse_offload:
2897   case OMPC_dynamic_allocators:
2898   case OMPC_full:
2899     // OpenMP [2.7.1, Restrictions, p. 9]
2900     //  Only one ordered clause can appear on a loop directive.
2901     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
2902     //  Only one nowait clause can appear on a for directive.
2903     // OpenMP [5.0, Requires directive, Restrictions]
2904     //   Each of the requires clauses can appear at most once on the directive.
2905     if (!FirstClause) {
2906       Diag(Tok, diag::err_omp_more_one_clause)
2907           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2908       ErrorFound = true;
2909     }
2910 
2911     Clause = ParseOpenMPClause(CKind, WrongDirective);
2912     break;
2913   case OMPC_update:
2914     if (!FirstClause) {
2915       Diag(Tok, diag::err_omp_more_one_clause)
2916           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2917       ErrorFound = true;
2918     }
2919 
2920     Clause = (DKind == OMPD_depobj)
2921                  ? ParseOpenMPSimpleClause(CKind, WrongDirective)
2922                  : ParseOpenMPClause(CKind, WrongDirective);
2923     break;
2924   case OMPC_private:
2925   case OMPC_firstprivate:
2926   case OMPC_lastprivate:
2927   case OMPC_shared:
2928   case OMPC_reduction:
2929   case OMPC_task_reduction:
2930   case OMPC_in_reduction:
2931   case OMPC_linear:
2932   case OMPC_aligned:
2933   case OMPC_copyin:
2934   case OMPC_copyprivate:
2935   case OMPC_flush:
2936   case OMPC_depend:
2937   case OMPC_map:
2938   case OMPC_to:
2939   case OMPC_from:
2940   case OMPC_use_device_ptr:
2941   case OMPC_use_device_addr:
2942   case OMPC_is_device_ptr:
2943   case OMPC_allocate:
2944   case OMPC_nontemporal:
2945   case OMPC_inclusive:
2946   case OMPC_exclusive:
2947   case OMPC_affinity:
2948     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
2949     break;
2950   case OMPC_sizes:
2951     if (!FirstClause) {
2952       Diag(Tok, diag::err_omp_more_one_clause)
2953           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2954       ErrorFound = true;
2955     }
2956 
2957     Clause = ParseOpenMPSizesClause();
2958     break;
2959   case OMPC_uses_allocators:
2960     Clause = ParseOpenMPUsesAllocatorClause(DKind);
2961     break;
2962   case OMPC_destroy:
2963     if (DKind != OMPD_interop) {
2964       if (!FirstClause) {
2965         Diag(Tok, diag::err_omp_more_one_clause)
2966             << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2967         ErrorFound = true;
2968       }
2969       Clause = ParseOpenMPClause(CKind, WrongDirective);
2970       break;
2971     }
2972     LLVM_FALLTHROUGH;
2973   case OMPC_init:
2974   case OMPC_use:
2975     Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
2976     break;
2977   case OMPC_device_type:
2978   case OMPC_unknown:
2979     skipUntilPragmaOpenMPEnd(DKind);
2980     break;
2981   case OMPC_threadprivate:
2982   case OMPC_uniform:
2983   case OMPC_match:
2984     if (!WrongDirective)
2985       Diag(Tok, diag::err_omp_unexpected_clause)
2986           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
2987     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
2988     break;
2989   default:
2990     break;
2991   }
2992   return ErrorFound ? nullptr : Clause;
2993 }
2994 
2995 /// Parses simple expression in parens for single-expression clauses of OpenMP
2996 /// constructs.
2997 /// \param RLoc Returned location of right paren.
ParseOpenMPParensExpr(StringRef ClauseName,SourceLocation & RLoc,bool IsAddressOfOperand)2998 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
2999                                          SourceLocation &RLoc,
3000                                          bool IsAddressOfOperand) {
3001   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3002   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3003     return ExprError();
3004 
3005   SourceLocation ELoc = Tok.getLocation();
3006   ExprResult LHS(
3007       ParseCastExpression(AnyCastExpr, IsAddressOfOperand, NotTypeCast));
3008   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3009   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3010 
3011   // Parse ')'.
3012   RLoc = Tok.getLocation();
3013   if (!T.consumeClose())
3014     RLoc = T.getCloseLocation();
3015 
3016   return Val;
3017 }
3018 
3019 /// Parsing of OpenMP clauses with single expressions like 'final',
3020 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
3021 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
3022 /// 'detach'.
3023 ///
3024 ///    final-clause:
3025 ///      'final' '(' expression ')'
3026 ///
3027 ///    num_threads-clause:
3028 ///      'num_threads' '(' expression ')'
3029 ///
3030 ///    safelen-clause:
3031 ///      'safelen' '(' expression ')'
3032 ///
3033 ///    simdlen-clause:
3034 ///      'simdlen' '(' expression ')'
3035 ///
3036 ///    collapse-clause:
3037 ///      'collapse' '(' expression ')'
3038 ///
3039 ///    priority-clause:
3040 ///      'priority' '(' expression ')'
3041 ///
3042 ///    grainsize-clause:
3043 ///      'grainsize' '(' expression ')'
3044 ///
3045 ///    num_tasks-clause:
3046 ///      'num_tasks' '(' expression ')'
3047 ///
3048 ///    hint-clause:
3049 ///      'hint' '(' expression ')'
3050 ///
3051 ///    allocator-clause:
3052 ///      'allocator' '(' expression ')'
3053 ///
3054 ///    detach-clause:
3055 ///      'detach' '(' event-handler-expression ')'
3056 ///
ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,bool ParseOnly)3057 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
3058                                                bool ParseOnly) {
3059   SourceLocation Loc = ConsumeToken();
3060   SourceLocation LLoc = Tok.getLocation();
3061   SourceLocation RLoc;
3062 
3063   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
3064 
3065   if (Val.isInvalid())
3066     return nullptr;
3067 
3068   if (ParseOnly)
3069     return nullptr;
3070   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
3071 }
3072 
3073 /// Parsing of OpenMP clauses that use an interop-var.
3074 ///
3075 /// init-clause:
3076 ///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
3077 ///
3078 /// destroy-clause:
3079 ///   destroy(interop-var)
3080 ///
3081 /// use-clause:
3082 ///   use(interop-var)
3083 ///
3084 /// interop-modifier:
3085 ///   prefer_type(preference-list)
3086 ///
3087 /// preference-list:
3088 ///   foreign-runtime-id [, foreign-runtime-id]...
3089 ///
3090 /// foreign-runtime-id:
3091 ///   <string-literal> | <constant-integral-expression>
3092 ///
3093 /// interop-type:
3094 ///   target | targetsync
3095 ///
ParseOpenMPInteropClause(OpenMPClauseKind Kind,bool ParseOnly)3096 OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
3097                                             bool ParseOnly) {
3098   SourceLocation Loc = ConsumeToken();
3099   // Parse '('.
3100   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3101   if (T.expectAndConsume(diag::err_expected_lparen_after,
3102                          getOpenMPClauseName(Kind).data()))
3103     return nullptr;
3104 
3105   bool IsTarget = false;
3106   bool IsTargetSync = false;
3107   SmallVector<Expr *, 4> Prefs;
3108 
3109   if (Kind == OMPC_init) {
3110 
3111     // Parse optional interop-modifier.
3112     if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "prefer_type") {
3113       ConsumeToken();
3114       BalancedDelimiterTracker PT(*this, tok::l_paren,
3115                                   tok::annot_pragma_openmp_end);
3116       if (PT.expectAndConsume(diag::err_expected_lparen_after, "prefer_type"))
3117         return nullptr;
3118 
3119       while (Tok.isNot(tok::r_paren)) {
3120         SourceLocation Loc = Tok.getLocation();
3121         ExprResult LHS = ParseCastExpression(AnyCastExpr);
3122         ExprResult PTExpr = Actions.CorrectDelayedTyposInExpr(
3123             ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3124         PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc,
3125                                              /*DiscardedValue=*/false);
3126         if (PTExpr.isUsable())
3127           Prefs.push_back(PTExpr.get());
3128         else
3129           SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3130                     StopBeforeMatch);
3131 
3132         if (Tok.is(tok::comma))
3133           ConsumeToken();
3134       }
3135       PT.consumeClose();
3136     }
3137 
3138     if (!Prefs.empty()) {
3139       if (Tok.is(tok::comma))
3140         ConsumeToken();
3141       else
3142         Diag(Tok, diag::err_omp_expected_punc_after_interop_mod);
3143     }
3144 
3145     // Parse the interop-types.
3146     bool HasError = false;
3147     while (Tok.is(tok::identifier)) {
3148       if (PP.getSpelling(Tok) == "target") {
3149         // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
3150         // Each interop-type may be specified on an action-clause at most
3151         // once.
3152         if (IsTarget)
3153           Diag(Tok, diag::warn_omp_more_one_interop_type) << "target";
3154         IsTarget = true;
3155       } else if (PP.getSpelling(Tok) == "targetsync") {
3156         if (IsTargetSync)
3157           Diag(Tok, diag::warn_omp_more_one_interop_type) << "targetsync";
3158         IsTargetSync = true;
3159       } else {
3160         HasError = true;
3161         Diag(Tok, diag::err_omp_expected_interop_type);
3162       }
3163       ConsumeToken();
3164 
3165       if (!Tok.is(tok::comma))
3166         break;
3167       ConsumeToken();
3168     }
3169     if (!HasError && !IsTarget && !IsTargetSync)
3170       Diag(Tok, diag::err_omp_expected_interop_type);
3171 
3172     if (Tok.is(tok::colon))
3173       ConsumeToken();
3174     else if (IsTarget || IsTargetSync)
3175       Diag(Tok, diag::warn_pragma_expected_colon) << "interop types";
3176   }
3177 
3178   // Parse the variable.
3179   SourceLocation VarLoc = Tok.getLocation();
3180   ExprResult InteropVarExpr =
3181       Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3182   if (!InteropVarExpr.isUsable()) {
3183     SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3184               StopBeforeMatch);
3185   }
3186 
3187   // Parse ')'.
3188   SourceLocation RLoc = Tok.getLocation();
3189   if (!T.consumeClose())
3190     RLoc = T.getCloseLocation();
3191 
3192   if (ParseOnly || !InteropVarExpr.isUsable() ||
3193       (Kind == OMPC_init && !IsTarget && !IsTargetSync))
3194     return nullptr;
3195 
3196   if (Kind == OMPC_init)
3197     return Actions.ActOnOpenMPInitClause(InteropVarExpr.get(), Prefs, IsTarget,
3198                                          IsTargetSync, Loc, T.getOpenLocation(),
3199                                          VarLoc, RLoc);
3200   if (Kind == OMPC_use)
3201     return Actions.ActOnOpenMPUseClause(InteropVarExpr.get(), Loc,
3202                                         T.getOpenLocation(), VarLoc, RLoc);
3203 
3204   if (Kind == OMPC_destroy)
3205     return Actions.ActOnOpenMPDestroyClause(InteropVarExpr.get(), Loc,
3206                                             T.getOpenLocation(), VarLoc, RLoc);
3207 
3208   llvm_unreachable("Unexpected interop variable clause.");
3209 }
3210 
3211 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
3212 ///
3213 ///    default-clause:
3214 ///         'default' '(' 'none' | 'shared' | 'firstprivate' ')'
3215 ///
3216 ///    proc_bind-clause:
3217 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
3218 ///
3219 ///    update-clause:
3220 ///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
3221 ///
ParseOpenMPSimpleClause(OpenMPClauseKind Kind,bool ParseOnly)3222 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
3223                                            bool ParseOnly) {
3224   llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
3225   if (!Val || ParseOnly)
3226     return nullptr;
3227   if (getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3228       static_cast<DefaultKind>(Val.getValue().Type) ==
3229           OMP_DEFAULT_firstprivate) {
3230     Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa)
3231         << getOpenMPClauseName(OMPC_firstprivate)
3232         << getOpenMPClauseName(OMPC_default) << "5.1";
3233     return nullptr;
3234   }
3235   return Actions.ActOnOpenMPSimpleClause(
3236       Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
3237       Val.getValue().Loc, Val.getValue().RLoc);
3238 }
3239 
3240 /// Parsing of OpenMP clauses like 'ordered'.
3241 ///
3242 ///    ordered-clause:
3243 ///         'ordered'
3244 ///
3245 ///    nowait-clause:
3246 ///         'nowait'
3247 ///
3248 ///    untied-clause:
3249 ///         'untied'
3250 ///
3251 ///    mergeable-clause:
3252 ///         'mergeable'
3253 ///
3254 ///    read-clause:
3255 ///         'read'
3256 ///
3257 ///    threads-clause:
3258 ///         'threads'
3259 ///
3260 ///    simd-clause:
3261 ///         'simd'
3262 ///
3263 ///    nogroup-clause:
3264 ///         'nogroup'
3265 ///
ParseOpenMPClause(OpenMPClauseKind Kind,bool ParseOnly)3266 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
3267   SourceLocation Loc = Tok.getLocation();
3268   ConsumeAnyToken();
3269 
3270   if (ParseOnly)
3271     return nullptr;
3272   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3273 }
3274 
3275 /// Parsing of OpenMP clauses with single expressions and some additional
3276 /// argument like 'schedule' or 'dist_schedule'.
3277 ///
3278 ///    schedule-clause:
3279 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
3280 ///      ')'
3281 ///
3282 ///    if-clause:
3283 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
3284 ///
3285 ///    defaultmap:
3286 ///      'defaultmap' '(' modifier [ ':' kind ] ')'
3287 ///
3288 ///    device-clause:
3289 ///      'device' '(' [ device-modifier ':' ] expression ')'
3290 ///
ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,OpenMPClauseKind Kind,bool ParseOnly)3291 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
3292                                                       OpenMPClauseKind Kind,
3293                                                       bool ParseOnly) {
3294   SourceLocation Loc = ConsumeToken();
3295   SourceLocation DelimLoc;
3296   // Parse '('.
3297   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3298   if (T.expectAndConsume(diag::err_expected_lparen_after,
3299                          getOpenMPClauseName(Kind).data()))
3300     return nullptr;
3301 
3302   ExprResult Val;
3303   SmallVector<unsigned, 4> Arg;
3304   SmallVector<SourceLocation, 4> KLoc;
3305   if (Kind == OMPC_schedule) {
3306     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3307     Arg.resize(NumberOfElements);
3308     KLoc.resize(NumberOfElements);
3309     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
3310     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
3311     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
3312     unsigned KindModifier = getOpenMPSimpleClauseType(
3313         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3314         getLangOpts().OpenMP);
3315     if (KindModifier > OMPC_SCHEDULE_unknown) {
3316       // Parse 'modifier'
3317       Arg[Modifier1] = KindModifier;
3318       KLoc[Modifier1] = Tok.getLocation();
3319       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3320           Tok.isNot(tok::annot_pragma_openmp_end))
3321         ConsumeAnyToken();
3322       if (Tok.is(tok::comma)) {
3323         // Parse ',' 'modifier'
3324         ConsumeAnyToken();
3325         KindModifier = getOpenMPSimpleClauseType(
3326             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3327             getLangOpts().OpenMP);
3328         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
3329                              ? KindModifier
3330                              : (unsigned)OMPC_SCHEDULE_unknown;
3331         KLoc[Modifier2] = Tok.getLocation();
3332         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3333             Tok.isNot(tok::annot_pragma_openmp_end))
3334           ConsumeAnyToken();
3335       }
3336       // Parse ':'
3337       if (Tok.is(tok::colon))
3338         ConsumeAnyToken();
3339       else
3340         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
3341       KindModifier = getOpenMPSimpleClauseType(
3342           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3343           getLangOpts().OpenMP);
3344     }
3345     Arg[ScheduleKind] = KindModifier;
3346     KLoc[ScheduleKind] = Tok.getLocation();
3347     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3348         Tok.isNot(tok::annot_pragma_openmp_end))
3349       ConsumeAnyToken();
3350     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3351          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3352          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3353         Tok.is(tok::comma))
3354       DelimLoc = ConsumeAnyToken();
3355   } else if (Kind == OMPC_dist_schedule) {
3356     Arg.push_back(getOpenMPSimpleClauseType(
3357         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3358         getLangOpts().OpenMP));
3359     KLoc.push_back(Tok.getLocation());
3360     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3361         Tok.isNot(tok::annot_pragma_openmp_end))
3362       ConsumeAnyToken();
3363     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3364       DelimLoc = ConsumeAnyToken();
3365   } else if (Kind == OMPC_defaultmap) {
3366     // Get a defaultmap modifier
3367     unsigned Modifier = getOpenMPSimpleClauseType(
3368         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3369         getLangOpts().OpenMP);
3370     // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
3371     // pointer
3372     if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
3373       Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
3374     Arg.push_back(Modifier);
3375     KLoc.push_back(Tok.getLocation());
3376     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3377         Tok.isNot(tok::annot_pragma_openmp_end))
3378       ConsumeAnyToken();
3379     // Parse ':'
3380     if (Tok.is(tok::colon) || getLangOpts().OpenMP < 50) {
3381       if (Tok.is(tok::colon))
3382         ConsumeAnyToken();
3383       else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
3384         Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
3385       // Get a defaultmap kind
3386       Arg.push_back(getOpenMPSimpleClauseType(
3387           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3388           getLangOpts().OpenMP));
3389       KLoc.push_back(Tok.getLocation());
3390       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3391           Tok.isNot(tok::annot_pragma_openmp_end))
3392         ConsumeAnyToken();
3393     } else {
3394       Arg.push_back(OMPC_DEFAULTMAP_unknown);
3395       KLoc.push_back(SourceLocation());
3396     }
3397   } else if (Kind == OMPC_device) {
3398     // Only target executable directives support extended device construct.
3399     if (isOpenMPTargetExecutionDirective(DKind) && getLangOpts().OpenMP >= 50 &&
3400         NextToken().is(tok::colon)) {
3401       // Parse optional <device modifier> ':'
3402       Arg.push_back(getOpenMPSimpleClauseType(
3403           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3404           getLangOpts().OpenMP));
3405       KLoc.push_back(Tok.getLocation());
3406       ConsumeAnyToken();
3407       // Parse ':'
3408       ConsumeAnyToken();
3409     } else {
3410       Arg.push_back(OMPC_DEVICE_unknown);
3411       KLoc.emplace_back();
3412     }
3413   } else {
3414     assert(Kind == OMPC_if);
3415     KLoc.push_back(Tok.getLocation());
3416     TentativeParsingAction TPA(*this);
3417     auto DK = parseOpenMPDirectiveKind(*this);
3418     Arg.push_back(DK);
3419     if (DK != OMPD_unknown) {
3420       ConsumeToken();
3421       if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
3422         TPA.Commit();
3423         DelimLoc = ConsumeToken();
3424       } else {
3425         TPA.Revert();
3426         Arg.back() = unsigned(OMPD_unknown);
3427       }
3428     } else {
3429       TPA.Revert();
3430     }
3431   }
3432 
3433   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
3434                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
3435                           Kind == OMPC_if || Kind == OMPC_device;
3436   if (NeedAnExpression) {
3437     SourceLocation ELoc = Tok.getLocation();
3438     ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
3439     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
3440     Val =
3441         Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3442   }
3443 
3444   // Parse ')'.
3445   SourceLocation RLoc = Tok.getLocation();
3446   if (!T.consumeClose())
3447     RLoc = T.getCloseLocation();
3448 
3449   if (NeedAnExpression && Val.isInvalid())
3450     return nullptr;
3451 
3452   if (ParseOnly)
3453     return nullptr;
3454   return Actions.ActOnOpenMPSingleExprWithArgClause(
3455       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3456 }
3457 
ParseReductionId(Parser & P,CXXScopeSpec & ReductionIdScopeSpec,UnqualifiedId & ReductionId)3458 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
3459                              UnqualifiedId &ReductionId) {
3460   if (ReductionIdScopeSpec.isEmpty()) {
3461     auto OOK = OO_None;
3462     switch (P.getCurToken().getKind()) {
3463     case tok::plus:
3464       OOK = OO_Plus;
3465       break;
3466     case tok::minus:
3467       OOK = OO_Minus;
3468       break;
3469     case tok::star:
3470       OOK = OO_Star;
3471       break;
3472     case tok::amp:
3473       OOK = OO_Amp;
3474       break;
3475     case tok::pipe:
3476       OOK = OO_Pipe;
3477       break;
3478     case tok::caret:
3479       OOK = OO_Caret;
3480       break;
3481     case tok::ampamp:
3482       OOK = OO_AmpAmp;
3483       break;
3484     case tok::pipepipe:
3485       OOK = OO_PipePipe;
3486       break;
3487     default:
3488       break;
3489     }
3490     if (OOK != OO_None) {
3491       SourceLocation OpLoc = P.ConsumeToken();
3492       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
3493       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
3494       return false;
3495     }
3496   }
3497   return P.ParseUnqualifiedId(
3498       ReductionIdScopeSpec, /*ObjectType=*/nullptr,
3499       /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
3500       /*AllowDestructorName*/ false,
3501       /*AllowConstructorName*/ false,
3502       /*AllowDeductionGuide*/ false, nullptr, ReductionId);
3503 }
3504 
3505 /// Checks if the token is a valid map-type-modifier.
3506 /// FIXME: It will return an OpenMPMapClauseKind if that's what it parses.
isMapModifier(Parser & P)3507 static OpenMPMapModifierKind isMapModifier(Parser &P) {
3508   Token Tok = P.getCurToken();
3509   if (!Tok.is(tok::identifier))
3510     return OMPC_MAP_MODIFIER_unknown;
3511 
3512   Preprocessor &PP = P.getPreprocessor();
3513   OpenMPMapModifierKind TypeModifier =
3514       static_cast<OpenMPMapModifierKind>(getOpenMPSimpleClauseType(
3515           OMPC_map, PP.getSpelling(Tok), P.getLangOpts().OpenMP));
3516   return TypeModifier;
3517 }
3518 
3519 /// Parse the mapper modifier in map, to, and from clauses.
parseMapperModifier(OpenMPVarListDataTy & Data)3520 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
3521   // Parse '('.
3522   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
3523   if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
3524     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3525               StopBeforeMatch);
3526     return true;
3527   }
3528   // Parse mapper-identifier
3529   if (getLangOpts().CPlusPlus)
3530     ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3531                                    /*ObjectType=*/nullptr,
3532                                    /*ObjectHadErrors=*/false,
3533                                    /*EnteringContext=*/false);
3534   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
3535     Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
3536     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3537               StopBeforeMatch);
3538     return true;
3539   }
3540   auto &DeclNames = Actions.getASTContext().DeclarationNames;
3541   Data.ReductionOrMapperId = DeclarationNameInfo(
3542       DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
3543   ConsumeToken();
3544   // Parse ')'.
3545   return T.consumeClose();
3546 }
3547 
3548 /// Parse map-type-modifiers in map clause.
3549 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3550 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
3551 /// present
parseMapTypeModifiers(OpenMPVarListDataTy & Data)3552 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
3553   while (getCurToken().isNot(tok::colon)) {
3554     OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
3555     if (TypeModifier == OMPC_MAP_MODIFIER_always ||
3556         TypeModifier == OMPC_MAP_MODIFIER_close ||
3557         TypeModifier == OMPC_MAP_MODIFIER_present) {
3558       Data.MapTypeModifiers.push_back(TypeModifier);
3559       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3560       ConsumeToken();
3561     } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
3562       Data.MapTypeModifiers.push_back(TypeModifier);
3563       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3564       ConsumeToken();
3565       if (parseMapperModifier(Data))
3566         return true;
3567     } else {
3568       // For the case of unknown map-type-modifier or a map-type.
3569       // Map-type is followed by a colon; the function returns when it
3570       // encounters a token followed by a colon.
3571       if (Tok.is(tok::comma)) {
3572         Diag(Tok, diag::err_omp_map_type_modifier_missing);
3573         ConsumeToken();
3574         continue;
3575       }
3576       // Potential map-type token as it is followed by a colon.
3577       if (PP.LookAhead(0).is(tok::colon))
3578         return false;
3579       Diag(Tok, diag::err_omp_unknown_map_type_modifier)
3580           << (getLangOpts().OpenMP >= 51 ? 1 : 0);
3581       ConsumeToken();
3582     }
3583     if (getCurToken().is(tok::comma))
3584       ConsumeToken();
3585   }
3586   return false;
3587 }
3588 
3589 /// Checks if the token is a valid map-type.
3590 /// FIXME: It will return an OpenMPMapModifierKind if that's what it parses.
isMapType(Parser & P)3591 static OpenMPMapClauseKind isMapType(Parser &P) {
3592   Token Tok = P.getCurToken();
3593   // The map-type token can be either an identifier or the C++ delete keyword.
3594   if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
3595     return OMPC_MAP_unknown;
3596   Preprocessor &PP = P.getPreprocessor();
3597   OpenMPMapClauseKind MapType =
3598       static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
3599           OMPC_map, PP.getSpelling(Tok), P.getLangOpts().OpenMP));
3600   return MapType;
3601 }
3602 
3603 /// Parse map-type in map clause.
3604 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3605 /// where, map-type ::= to | from | tofrom | alloc | release | delete
parseMapType(Parser & P,Parser::OpenMPVarListDataTy & Data)3606 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
3607   Token Tok = P.getCurToken();
3608   if (Tok.is(tok::colon)) {
3609     P.Diag(Tok, diag::err_omp_map_type_missing);
3610     return;
3611   }
3612   Data.ExtraModifier = isMapType(P);
3613   if (Data.ExtraModifier == OMPC_MAP_unknown)
3614     P.Diag(Tok, diag::err_omp_unknown_map_type);
3615   P.ConsumeToken();
3616 }
3617 
3618 /// Parses simple expression in parens for single-expression clauses of OpenMP
3619 /// constructs.
ParseOpenMPIteratorsExpr()3620 ExprResult Parser::ParseOpenMPIteratorsExpr() {
3621   assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
3622          "Expected 'iterator' token.");
3623   SourceLocation IteratorKwLoc = ConsumeToken();
3624 
3625   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3626   if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator"))
3627     return ExprError();
3628 
3629   SourceLocation LLoc = T.getOpenLocation();
3630   SmallVector<Sema::OMPIteratorData, 4> Data;
3631   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
3632     // Check if the type parsing is required.
3633     ParsedType IteratorType;
3634     if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) {
3635       // identifier '=' is not found - parse type.
3636       TypeResult TR = ParseTypeName();
3637       if (TR.isInvalid()) {
3638         T.skipToEnd();
3639         return ExprError();
3640       }
3641       IteratorType = TR.get();
3642     }
3643 
3644     // Parse identifier.
3645     IdentifierInfo *II = nullptr;
3646     SourceLocation IdLoc;
3647     if (Tok.is(tok::identifier)) {
3648       II = Tok.getIdentifierInfo();
3649       IdLoc = ConsumeToken();
3650     } else {
3651       Diag(Tok, diag::err_expected_unqualified_id) << 0;
3652     }
3653 
3654     // Parse '='.
3655     SourceLocation AssignLoc;
3656     if (Tok.is(tok::equal))
3657       AssignLoc = ConsumeToken();
3658     else
3659       Diag(Tok, diag::err_omp_expected_equal_in_iterator);
3660 
3661     // Parse range-specification - <begin> ':' <end> [ ':' <step> ]
3662     ColonProtectionRAIIObject ColonRAII(*this);
3663     // Parse <begin>
3664     SourceLocation Loc = Tok.getLocation();
3665     ExprResult LHS = ParseCastExpression(AnyCastExpr);
3666     ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
3667         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3668     Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
3669                                         /*DiscardedValue=*/false);
3670     // Parse ':'.
3671     SourceLocation ColonLoc;
3672     if (Tok.is(tok::colon))
3673       ColonLoc = ConsumeToken();
3674 
3675     // Parse <end>
3676     Loc = Tok.getLocation();
3677     LHS = ParseCastExpression(AnyCastExpr);
3678     ExprResult End = Actions.CorrectDelayedTyposInExpr(
3679         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3680     End = Actions.ActOnFinishFullExpr(End.get(), Loc,
3681                                       /*DiscardedValue=*/false);
3682 
3683     SourceLocation SecColonLoc;
3684     ExprResult Step;
3685     // Parse optional step.
3686     if (Tok.is(tok::colon)) {
3687       // Parse ':'
3688       SecColonLoc = ConsumeToken();
3689       // Parse <step>
3690       Loc = Tok.getLocation();
3691       LHS = ParseCastExpression(AnyCastExpr);
3692       Step = Actions.CorrectDelayedTyposInExpr(
3693           ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3694       Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
3695                                          /*DiscardedValue=*/false);
3696     }
3697 
3698     // Parse ',' or ')'
3699     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
3700       Diag(Tok, diag::err_omp_expected_punc_after_iterator);
3701     if (Tok.is(tok::comma))
3702       ConsumeToken();
3703 
3704     Sema::OMPIteratorData &D = Data.emplace_back();
3705     D.DeclIdent = II;
3706     D.DeclIdentLoc = IdLoc;
3707     D.Type = IteratorType;
3708     D.AssignLoc = AssignLoc;
3709     D.ColonLoc = ColonLoc;
3710     D.SecColonLoc = SecColonLoc;
3711     D.Range.Begin = Begin.get();
3712     D.Range.End = End.get();
3713     D.Range.Step = Step.get();
3714   }
3715 
3716   // Parse ')'.
3717   SourceLocation RLoc = Tok.getLocation();
3718   if (!T.consumeClose())
3719     RLoc = T.getCloseLocation();
3720 
3721   return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc,
3722                                       Data);
3723 }
3724 
3725 /// Parses clauses with list.
ParseOpenMPVarList(OpenMPDirectiveKind DKind,OpenMPClauseKind Kind,SmallVectorImpl<Expr * > & Vars,OpenMPVarListDataTy & Data)3726 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
3727                                 OpenMPClauseKind Kind,
3728                                 SmallVectorImpl<Expr *> &Vars,
3729                                 OpenMPVarListDataTy &Data) {
3730   UnqualifiedId UnqualifiedReductionId;
3731   bool InvalidReductionId = false;
3732   bool IsInvalidMapperModifier = false;
3733 
3734   // Parse '('.
3735   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3736   if (T.expectAndConsume(diag::err_expected_lparen_after,
3737                          getOpenMPClauseName(Kind).data()))
3738     return true;
3739 
3740   bool HasIterator = false;
3741   bool NeedRParenForLinear = false;
3742   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
3743                                    tok::annot_pragma_openmp_end);
3744   // Handle reduction-identifier for reduction clause.
3745   if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
3746       Kind == OMPC_in_reduction) {
3747     Data.ExtraModifier = OMPC_REDUCTION_unknown;
3748     if (Kind == OMPC_reduction && getLangOpts().OpenMP >= 50 &&
3749         (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
3750         NextToken().is(tok::comma)) {
3751       // Parse optional reduction modifier.
3752       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3753                                                      getLangOpts().OpenMP);
3754       Data.ExtraModifierLoc = Tok.getLocation();
3755       ConsumeToken();
3756       assert(Tok.is(tok::comma) && "Expected comma.");
3757       (void)ConsumeToken();
3758     }
3759     ColonProtectionRAIIObject ColonRAII(*this);
3760     if (getLangOpts().CPlusPlus)
3761       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3762                                      /*ObjectType=*/nullptr,
3763                                      /*ObjectHadErrors=*/false,
3764                                      /*EnteringContext=*/false);
3765     InvalidReductionId = ParseReductionId(
3766         *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
3767     if (InvalidReductionId) {
3768       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3769                 StopBeforeMatch);
3770     }
3771     if (Tok.is(tok::colon))
3772       Data.ColonLoc = ConsumeToken();
3773     else
3774       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
3775     if (!InvalidReductionId)
3776       Data.ReductionOrMapperId =
3777           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
3778   } else if (Kind == OMPC_depend) {
3779     if (getLangOpts().OpenMP >= 50) {
3780       if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") {
3781         // Handle optional dependence modifier.
3782         // iterator(iterators-definition)
3783         // where iterators-definition is iterator-specifier [,
3784         // iterators-definition ]
3785         // where iterator-specifier is [ iterator-type ] identifier =
3786         // range-specification
3787         HasIterator = true;
3788         EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3789         ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
3790         Data.DepModOrTailExpr = IteratorRes.get();
3791         // Parse ','
3792         ExpectAndConsume(tok::comma);
3793       }
3794     }
3795     // Handle dependency type for depend clause.
3796     ColonProtectionRAIIObject ColonRAII(*this);
3797     Data.ExtraModifier = getOpenMPSimpleClauseType(
3798         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "",
3799         getLangOpts().OpenMP);
3800     Data.ExtraModifierLoc = Tok.getLocation();
3801     if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
3802       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3803                 StopBeforeMatch);
3804     } else {
3805       ConsumeToken();
3806       // Special processing for depend(source) clause.
3807       if (DKind == OMPD_ordered && Data.ExtraModifier == OMPC_DEPEND_source) {
3808         // Parse ')'.
3809         T.consumeClose();
3810         return false;
3811       }
3812     }
3813     if (Tok.is(tok::colon)) {
3814       Data.ColonLoc = ConsumeToken();
3815     } else {
3816       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
3817                                       : diag::warn_pragma_expected_colon)
3818           << "dependency type";
3819     }
3820   } else if (Kind == OMPC_linear) {
3821     // Try to parse modifier if any.
3822     Data.ExtraModifier = OMPC_LINEAR_val;
3823     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
3824       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3825                                                      getLangOpts().OpenMP);
3826       Data.ExtraModifierLoc = ConsumeToken();
3827       LinearT.consumeOpen();
3828       NeedRParenForLinear = true;
3829     }
3830   } else if (Kind == OMPC_lastprivate) {
3831     // Try to parse modifier if any.
3832     Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
3833     // Conditional modifier allowed only in OpenMP 5.0 and not supported in
3834     // distribute and taskloop based directives.
3835     if ((getLangOpts().OpenMP >= 50 && !isOpenMPDistributeDirective(DKind) &&
3836          !isOpenMPTaskLoopDirective(DKind)) &&
3837         Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
3838       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3839                                                      getLangOpts().OpenMP);
3840       Data.ExtraModifierLoc = Tok.getLocation();
3841       ConsumeToken();
3842       assert(Tok.is(tok::colon) && "Expected colon.");
3843       Data.ColonLoc = ConsumeToken();
3844     }
3845   } else if (Kind == OMPC_map) {
3846     // Handle map type for map clause.
3847     ColonProtectionRAIIObject ColonRAII(*this);
3848 
3849     // The first identifier may be a list item, a map-type or a
3850     // map-type-modifier. The map-type can also be delete which has the same
3851     // spelling of the C++ delete keyword.
3852     Data.ExtraModifier = OMPC_MAP_unknown;
3853     Data.ExtraModifierLoc = Tok.getLocation();
3854 
3855     // Check for presence of a colon in the map clause.
3856     TentativeParsingAction TPA(*this);
3857     bool ColonPresent = false;
3858     if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3859                   StopBeforeMatch)) {
3860       if (Tok.is(tok::colon))
3861         ColonPresent = true;
3862     }
3863     TPA.Revert();
3864     // Only parse map-type-modifier[s] and map-type if a colon is present in
3865     // the map clause.
3866     if (ColonPresent) {
3867       IsInvalidMapperModifier = parseMapTypeModifiers(Data);
3868       if (!IsInvalidMapperModifier)
3869         parseMapType(*this, Data);
3870       else
3871         SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
3872     }
3873     if (Data.ExtraModifier == OMPC_MAP_unknown) {
3874       Data.ExtraModifier = OMPC_MAP_tofrom;
3875       Data.IsMapTypeImplicit = true;
3876     }
3877 
3878     if (Tok.is(tok::colon))
3879       Data.ColonLoc = ConsumeToken();
3880   } else if (Kind == OMPC_to || Kind == OMPC_from) {
3881     while (Tok.is(tok::identifier)) {
3882       auto Modifier =
3883           static_cast<OpenMPMotionModifierKind>(getOpenMPSimpleClauseType(
3884               Kind, PP.getSpelling(Tok), getLangOpts().OpenMP));
3885       if (Modifier == OMPC_MOTION_MODIFIER_unknown)
3886         break;
3887       Data.MotionModifiers.push_back(Modifier);
3888       Data.MotionModifiersLoc.push_back(Tok.getLocation());
3889       ConsumeToken();
3890       if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
3891         IsInvalidMapperModifier = parseMapperModifier(Data);
3892         if (IsInvalidMapperModifier)
3893           break;
3894       }
3895       // OpenMP < 5.1 doesn't permit a ',' or additional modifiers.
3896       if (getLangOpts().OpenMP < 51)
3897         break;
3898       // OpenMP 5.1 accepts an optional ',' even if the next character is ':'.
3899       // TODO: Is that intentional?
3900       if (Tok.is(tok::comma))
3901         ConsumeToken();
3902     }
3903     if (!Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
3904       if (!IsInvalidMapperModifier) {
3905         if (getLangOpts().OpenMP < 51)
3906           Diag(Tok, diag::warn_pragma_expected_colon) << ")";
3907         else
3908           Diag(Tok, diag::warn_pragma_expected_colon) << "motion modifier";
3909       }
3910       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3911                 StopBeforeMatch);
3912     }
3913     // OpenMP 5.1 permits a ':' even without a preceding modifier.  TODO: Is
3914     // that intentional?
3915     if ((!Data.MotionModifiers.empty() || getLangOpts().OpenMP >= 51) &&
3916         Tok.is(tok::colon))
3917       Data.ColonLoc = ConsumeToken();
3918   } else if (Kind == OMPC_allocate ||
3919              (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
3920               PP.getSpelling(Tok) == "iterator")) {
3921     // Handle optional allocator expression followed by colon delimiter.
3922     ColonProtectionRAIIObject ColonRAII(*this);
3923     TentativeParsingAction TPA(*this);
3924     // OpenMP 5.0, 2.10.1, task Construct.
3925     // where aff-modifier is one of the following:
3926     // iterator(iterators-definition)
3927     ExprResult Tail;
3928     if (Kind == OMPC_allocate) {
3929       Tail = ParseAssignmentExpression();
3930     } else {
3931       HasIterator = true;
3932       EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3933       Tail = ParseOpenMPIteratorsExpr();
3934     }
3935     Tail = Actions.CorrectDelayedTyposInExpr(Tail);
3936     Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
3937                                        /*DiscardedValue=*/false);
3938     if (Tail.isUsable()) {
3939       if (Tok.is(tok::colon)) {
3940         Data.DepModOrTailExpr = Tail.get();
3941         Data.ColonLoc = ConsumeToken();
3942         TPA.Commit();
3943       } else {
3944         // Colon not found, parse only list of variables.
3945         TPA.Revert();
3946       }
3947     } else {
3948       // Parsing was unsuccessfull, revert and skip to the end of clause or
3949       // directive.
3950       TPA.Revert();
3951       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3952                 StopBeforeMatch);
3953     }
3954   }
3955 
3956   bool IsComma =
3957       (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
3958        Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
3959       (Kind == OMPC_reduction && !InvalidReductionId) ||
3960       (Kind == OMPC_map && Data.ExtraModifier != OMPC_MAP_unknown) ||
3961       (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown);
3962   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
3963   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
3964                      Tok.isNot(tok::annot_pragma_openmp_end))) {
3965     ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope);
3966     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
3967     // Parse variable
3968     ExprResult VarExpr =
3969         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3970     if (VarExpr.isUsable()) {
3971       Vars.push_back(VarExpr.get());
3972     } else {
3973       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3974                 StopBeforeMatch);
3975     }
3976     // Skip ',' if any
3977     IsComma = Tok.is(tok::comma);
3978     if (IsComma)
3979       ConsumeToken();
3980     else if (Tok.isNot(tok::r_paren) &&
3981              Tok.isNot(tok::annot_pragma_openmp_end) &&
3982              (!MayHaveTail || Tok.isNot(tok::colon)))
3983       Diag(Tok, diag::err_omp_expected_punc)
3984           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
3985                                    : getOpenMPClauseName(Kind))
3986           << (Kind == OMPC_flush);
3987   }
3988 
3989   // Parse ')' for linear clause with modifier.
3990   if (NeedRParenForLinear)
3991     LinearT.consumeClose();
3992 
3993   // Parse ':' linear-step (or ':' alignment).
3994   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
3995   if (MustHaveTail) {
3996     Data.ColonLoc = Tok.getLocation();
3997     SourceLocation ELoc = ConsumeToken();
3998     ExprResult Tail = ParseAssignmentExpression();
3999     Tail =
4000         Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
4001     if (Tail.isUsable())
4002       Data.DepModOrTailExpr = Tail.get();
4003     else
4004       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4005                 StopBeforeMatch);
4006   }
4007 
4008   // Parse ')'.
4009   Data.RLoc = Tok.getLocation();
4010   if (!T.consumeClose())
4011     Data.RLoc = T.getCloseLocation();
4012   // Exit from scope when the iterator is used in depend clause.
4013   if (HasIterator)
4014     ExitScope();
4015   return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
4016          (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
4017          IsInvalidMapperModifier;
4018 }
4019 
4020 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
4021 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
4022 /// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
4023 ///
4024 ///    private-clause:
4025 ///       'private' '(' list ')'
4026 ///    firstprivate-clause:
4027 ///       'firstprivate' '(' list ')'
4028 ///    lastprivate-clause:
4029 ///       'lastprivate' '(' list ')'
4030 ///    shared-clause:
4031 ///       'shared' '(' list ')'
4032 ///    linear-clause:
4033 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
4034 ///    aligned-clause:
4035 ///       'aligned' '(' list [ ':' alignment ] ')'
4036 ///    reduction-clause:
4037 ///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
4038 ///    task_reduction-clause:
4039 ///       'task_reduction' '(' reduction-identifier ':' list ')'
4040 ///    in_reduction-clause:
4041 ///       'in_reduction' '(' reduction-identifier ':' list ')'
4042 ///    copyprivate-clause:
4043 ///       'copyprivate' '(' list ')'
4044 ///    flush-clause:
4045 ///       'flush' '(' list ')'
4046 ///    depend-clause:
4047 ///       'depend' '(' in | out | inout : list | source ')'
4048 ///    map-clause:
4049 ///       'map' '(' [ [ always [,] ] [ close [,] ]
4050 ///          [ mapper '(' mapper-identifier ')' [,] ]
4051 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
4052 ///    to-clause:
4053 ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4054 ///    from-clause:
4055 ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4056 ///    use_device_ptr-clause:
4057 ///       'use_device_ptr' '(' list ')'
4058 ///    use_device_addr-clause:
4059 ///       'use_device_addr' '(' list ')'
4060 ///    is_device_ptr-clause:
4061 ///       'is_device_ptr' '(' list ')'
4062 ///    allocate-clause:
4063 ///       'allocate' '(' [ allocator ':' ] list ')'
4064 ///    nontemporal-clause:
4065 ///       'nontemporal' '(' list ')'
4066 ///    inclusive-clause:
4067 ///       'inclusive' '(' list ')'
4068 ///    exclusive-clause:
4069 ///       'exclusive' '(' list ')'
4070 ///
4071 /// For 'linear' clause linear-list may have the following forms:
4072 ///  list
4073 ///  modifier(list)
4074 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,OpenMPClauseKind Kind,bool ParseOnly)4075 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
4076                                             OpenMPClauseKind Kind,
4077                                             bool ParseOnly) {
4078   SourceLocation Loc = Tok.getLocation();
4079   SourceLocation LOpen = ConsumeToken();
4080   SmallVector<Expr *, 4> Vars;
4081   OpenMPVarListDataTy Data;
4082 
4083   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
4084     return nullptr;
4085 
4086   if (ParseOnly)
4087     return nullptr;
4088   OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
4089   return Actions.ActOnOpenMPVarListClause(
4090       Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc,
4091       Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
4092       Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
4093       Data.IsMapTypeImplicit, Data.ExtraModifierLoc, Data.MotionModifiers,
4094       Data.MotionModifiersLoc);
4095 }
4096