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__anond65602ef0111::OpenMPDirectiveKindExWrapper62   OpenMPDirectiveKindExWrapper(unsigned Value) : Value(Value) {}
OpenMPDirectiveKindExWrapper__anond65602ef0111::OpenMPDirectiveKindExWrapper63   OpenMPDirectiveKindExWrapper(OpenMPDirectiveKind DK) : Value(unsigned(DK)) {}
operator ==__anond65602ef0111::OpenMPDirectiveKindExWrapper64   bool operator==(OpenMPDirectiveKindExWrapper V) const {
65     return Value == V.Value;
66   }
operator !=__anond65602ef0111::OpenMPDirectiveKindExWrapper67   bool operator!=(OpenMPDirectiveKindExWrapper V) const {
68     return Value != V.Value;
69   }
operator ==__anond65602ef0111::OpenMPDirectiveKindExWrapper70   bool operator==(OpenMPDirectiveKind V) const { return Value == unsigned(V); }
operator !=__anond65602ef0111::OpenMPDirectiveKindExWrapper71   bool operator!=(OpenMPDirectiveKind V) const { return Value != unsigned(V); }
operator <__anond65602ef0111::OpenMPDirectiveKindExWrapper72   bool operator<(OpenMPDirectiveKind V) const { return Value < unsigned(V); }
operator unsigned__anond65602ef0111::OpenMPDirectiveKindExWrapper73   operator unsigned() const { return Value; }
operator OpenMPDirectiveKind__anond65602ef0111::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__anond65602ef0c11::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.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1861   ParsingOpenMPDirectiveRAII DirScope(*this);
1862   ParenBraceBracketBalancer BalancerRAIIObj(*this);
1863 
1864   SourceLocation Loc;
1865   OpenMPDirectiveKind DKind;
1866   if (Delayed) {
1867     TentativeParsingAction TPA(*this);
1868     Loc = ConsumeAnnotationToken();
1869     DKind = parseOpenMPDirectiveKind(*this);
1870     if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1871       // Need to delay parsing until completion of the parent class.
1872       TPA.Revert();
1873       CachedTokens Toks;
1874       unsigned Cnt = 1;
1875       Toks.push_back(Tok);
1876       while (Cnt && Tok.isNot(tok::eof)) {
1877         (void)ConsumeAnyToken();
1878         if (Tok.is(tok::annot_pragma_openmp))
1879           ++Cnt;
1880         else if (Tok.is(tok::annot_pragma_openmp_end))
1881           --Cnt;
1882         Toks.push_back(Tok);
1883       }
1884       // Skip last annot_pragma_openmp_end.
1885       if (Cnt == 0)
1886         (void)ConsumeAnyToken();
1887       auto *LP = new LateParsedPragma(this, AS);
1888       LP->takeToks(Toks);
1889       getCurrentClass().LateParsedDeclarations.push_back(LP);
1890       return nullptr;
1891     }
1892     TPA.Commit();
1893   } else {
1894     Loc = ConsumeAnnotationToken();
1895     DKind = parseOpenMPDirectiveKind(*this);
1896   }
1897 
1898   switch (DKind) {
1899   case OMPD_threadprivate: {
1900     ConsumeToken();
1901     DeclDirectiveListParserHelper Helper(this, DKind);
1902     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1903                                   /*AllowScopeSpecifier=*/true)) {
1904       skipUntilPragmaOpenMPEnd(DKind);
1905       // Skip the last annot_pragma_openmp_end.
1906       ConsumeAnnotationToken();
1907       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
1908                                                        Helper.getIdentifiers());
1909     }
1910     break;
1911   }
1912   case OMPD_allocate: {
1913     ConsumeToken();
1914     DeclDirectiveListParserHelper Helper(this, DKind);
1915     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1916                                   /*AllowScopeSpecifier=*/true)) {
1917       SmallVector<OMPClause *, 1> Clauses;
1918       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1919         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1920                     llvm::omp::Clause_enumSize + 1>
1921             FirstClauses(llvm::omp::Clause_enumSize + 1);
1922         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1923           OpenMPClauseKind CKind =
1924               Tok.isAnnotation() ? OMPC_unknown
1925                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
1926           Actions.StartOpenMPClause(CKind);
1927           OMPClause *Clause = ParseOpenMPClause(
1928               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
1929           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1930                     StopBeforeMatch);
1931           FirstClauses[unsigned(CKind)].setInt(true);
1932           if (Clause != nullptr)
1933             Clauses.push_back(Clause);
1934           if (Tok.is(tok::annot_pragma_openmp_end)) {
1935             Actions.EndOpenMPClause();
1936             break;
1937           }
1938           // Skip ',' if any.
1939           if (Tok.is(tok::comma))
1940             ConsumeToken();
1941           Actions.EndOpenMPClause();
1942         }
1943         skipUntilPragmaOpenMPEnd(DKind);
1944       }
1945       // Skip the last annot_pragma_openmp_end.
1946       ConsumeAnnotationToken();
1947       return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
1948                                                   Clauses);
1949     }
1950     break;
1951   }
1952   case OMPD_requires: {
1953     SourceLocation StartLoc = ConsumeToken();
1954     SmallVector<OMPClause *, 5> Clauses;
1955     SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1956                 llvm::omp::Clause_enumSize + 1>
1957         FirstClauses(llvm::omp::Clause_enumSize + 1);
1958     if (Tok.is(tok::annot_pragma_openmp_end)) {
1959       Diag(Tok, diag::err_omp_expected_clause)
1960           << getOpenMPDirectiveName(OMPD_requires);
1961       break;
1962     }
1963     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1964       OpenMPClauseKind CKind = Tok.isAnnotation()
1965                                    ? OMPC_unknown
1966                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
1967       Actions.StartOpenMPClause(CKind);
1968       OMPClause *Clause = ParseOpenMPClause(
1969           OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt());
1970       SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1971                 StopBeforeMatch);
1972       FirstClauses[unsigned(CKind)].setInt(true);
1973       if (Clause != nullptr)
1974         Clauses.push_back(Clause);
1975       if (Tok.is(tok::annot_pragma_openmp_end)) {
1976         Actions.EndOpenMPClause();
1977         break;
1978       }
1979       // Skip ',' if any.
1980       if (Tok.is(tok::comma))
1981         ConsumeToken();
1982       Actions.EndOpenMPClause();
1983     }
1984     // Consume final annot_pragma_openmp_end
1985     if (Clauses.empty()) {
1986       Diag(Tok, diag::err_omp_expected_clause)
1987           << getOpenMPDirectiveName(OMPD_requires);
1988       ConsumeAnnotationToken();
1989       return nullptr;
1990     }
1991     ConsumeAnnotationToken();
1992     return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
1993   }
1994   case OMPD_assumes:
1995   case OMPD_begin_assumes:
1996     ParseOpenMPAssumesDirective(DKind, ConsumeToken());
1997     break;
1998   case OMPD_end_assumes:
1999     ParseOpenMPEndAssumesDirective(ConsumeToken());
2000     break;
2001   case OMPD_declare_reduction:
2002     ConsumeToken();
2003     if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2004       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2005       // Skip the last annot_pragma_openmp_end.
2006       ConsumeAnnotationToken();
2007       return Res;
2008     }
2009     break;
2010   case OMPD_declare_mapper: {
2011     ConsumeToken();
2012     if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2013       // Skip the last annot_pragma_openmp_end.
2014       ConsumeAnnotationToken();
2015       return Res;
2016     }
2017     break;
2018   }
2019   case OMPD_begin_declare_variant: {
2020     // The syntax is:
2021     // { #pragma omp begin declare variant clause }
2022     // <function-declaration-or-definition-sequence>
2023     // { #pragma omp end declare variant }
2024     //
2025     ConsumeToken();
2026     OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
2027     ASTContext &ASTCtx = Actions.getASTContext();
2028     OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
2029     if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI))
2030       break;
2031 
2032     // Skip last tokens.
2033     skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
2034 
2035     ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2036 
2037     VariantMatchInfo VMI;
2038     TI.getAsVariantMatchInfo(ASTCtx, VMI);
2039 
2040     std::function<void(StringRef)> DiagUnknownTrait = [this, Loc](
2041                                                           StringRef ISATrait) {
2042       // TODO Track the selector locations in a way that is accessible here to
2043       // improve the diagnostic location.
2044       Diag(Loc, diag::warn_unknown_begin_declare_variant_isa_trait) << ISATrait;
2045     };
2046     TargetOMPContext OMPCtx(ASTCtx, std::move(DiagUnknownTrait),
2047                             /* CurrentFunctionDecl */ nullptr);
2048 
2049     if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
2050       Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI);
2051       break;
2052     }
2053 
2054     // Elide all the code till the matching end declare variant was found.
2055     unsigned Nesting = 1;
2056     SourceLocation DKLoc;
2057     OpenMPDirectiveKind DK = OMPD_unknown;
2058     do {
2059       DKLoc = Tok.getLocation();
2060       DK = parseOpenMPDirectiveKind(*this);
2061       if (DK == OMPD_end_declare_variant)
2062         --Nesting;
2063       else if (DK == OMPD_begin_declare_variant)
2064         ++Nesting;
2065       if (!Nesting || isEofOrEom())
2066         break;
2067       ConsumeAnyToken();
2068     } while (true);
2069 
2070     parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
2071                          DK, Loc, DKLoc, /* SkipUntilOpenMPEnd */ true);
2072     if (isEofOrEom())
2073       return nullptr;
2074     break;
2075   }
2076   case OMPD_end_declare_variant: {
2077     if (Actions.isInOpenMPDeclareVariantScope())
2078       Actions.ActOnOpenMPEndDeclareVariant();
2079     else
2080       Diag(Loc, diag::err_expected_begin_declare_variant);
2081     ConsumeToken();
2082     break;
2083   }
2084   case OMPD_declare_variant:
2085   case OMPD_declare_simd: {
2086     // The syntax is:
2087     // { #pragma omp declare {simd|variant} }
2088     // <function-declaration-or-definition>
2089     //
2090     CachedTokens Toks;
2091     Toks.push_back(Tok);
2092     ConsumeToken();
2093     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2094       Toks.push_back(Tok);
2095       ConsumeAnyToken();
2096     }
2097     Toks.push_back(Tok);
2098     ConsumeAnyToken();
2099 
2100     DeclGroupPtrTy Ptr;
2101     if (Tok.is(tok::annot_pragma_openmp)) {
2102       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2103                                                        TagType, Tag);
2104     } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2105       // Here we expect to see some function declaration.
2106       if (AS == AS_none) {
2107         assert(TagType == DeclSpec::TST_unspecified);
2108         MaybeParseCXX11Attributes(Attrs);
2109         ParsingDeclSpec PDS(*this);
2110         Ptr = ParseExternalDeclaration(Attrs, &PDS);
2111       } else {
2112         Ptr =
2113             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2114       }
2115     }
2116     if (!Ptr) {
2117       Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2118           << (DKind == OMPD_declare_simd ? 0 : 1);
2119       return DeclGroupPtrTy();
2120     }
2121     if (DKind == OMPD_declare_simd)
2122       return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2123     assert(DKind == OMPD_declare_variant &&
2124            "Expected declare variant directive only");
2125     ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2126     return Ptr;
2127   }
2128   case OMPD_begin_declare_target:
2129   case OMPD_declare_target: {
2130     SourceLocation DTLoc = ConsumeAnyToken();
2131     bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2132     bool HasImplicitMappings =
2133         DKind == OMPD_begin_declare_target || !HasClauses;
2134     Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2135     if (HasClauses)
2136       ParseOMPDeclareTargetClauses(DTCI);
2137 
2138     // Skip the last annot_pragma_openmp_end.
2139     ConsumeAnyToken();
2140 
2141     if (HasImplicitMappings) {
2142       Actions.ActOnStartOpenMPDeclareTargetContext(DTCI);
2143       return nullptr;
2144     }
2145 
2146     Actions.ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2147     llvm::SmallVector<Decl *, 4> Decls;
2148     for (auto &It : DTCI.ExplicitlyMapped)
2149       Decls.push_back(It.first);
2150     return Actions.BuildDeclaratorGroup(Decls);
2151   }
2152   case OMPD_end_declare_target: {
2153     if (!Actions.isInOpenMPDeclareTargetContext()) {
2154       Diag(Tok, diag::err_omp_unexpected_directive)
2155           << 1 << getOpenMPDirectiveName(DKind);
2156       break;
2157     }
2158     const Sema::DeclareTargetContextInfo &DTCI =
2159         Actions.ActOnOpenMPEndDeclareTargetDirective();
2160     ParseOMPEndDeclareTargetDirective(DTCI.Kind, DKind, DTCI.Loc);
2161     return nullptr;
2162   }
2163   case OMPD_unknown:
2164     Diag(Tok, diag::err_omp_unknown_directive);
2165     break;
2166   case OMPD_parallel:
2167   case OMPD_simd:
2168   case OMPD_tile:
2169   case OMPD_task:
2170   case OMPD_taskyield:
2171   case OMPD_barrier:
2172   case OMPD_taskwait:
2173   case OMPD_taskgroup:
2174   case OMPD_flush:
2175   case OMPD_depobj:
2176   case OMPD_scan:
2177   case OMPD_for:
2178   case OMPD_for_simd:
2179   case OMPD_sections:
2180   case OMPD_section:
2181   case OMPD_single:
2182   case OMPD_master:
2183   case OMPD_ordered:
2184   case OMPD_critical:
2185   case OMPD_parallel_for:
2186   case OMPD_parallel_for_simd:
2187   case OMPD_parallel_sections:
2188   case OMPD_parallel_master:
2189   case OMPD_atomic:
2190   case OMPD_target:
2191   case OMPD_teams:
2192   case OMPD_cancellation_point:
2193   case OMPD_cancel:
2194   case OMPD_target_data:
2195   case OMPD_target_enter_data:
2196   case OMPD_target_exit_data:
2197   case OMPD_target_parallel:
2198   case OMPD_target_parallel_for:
2199   case OMPD_taskloop:
2200   case OMPD_taskloop_simd:
2201   case OMPD_master_taskloop:
2202   case OMPD_master_taskloop_simd:
2203   case OMPD_parallel_master_taskloop:
2204   case OMPD_parallel_master_taskloop_simd:
2205   case OMPD_distribute:
2206   case OMPD_target_update:
2207   case OMPD_distribute_parallel_for:
2208   case OMPD_distribute_parallel_for_simd:
2209   case OMPD_distribute_simd:
2210   case OMPD_target_parallel_for_simd:
2211   case OMPD_target_simd:
2212   case OMPD_teams_distribute:
2213   case OMPD_teams_distribute_simd:
2214   case OMPD_teams_distribute_parallel_for_simd:
2215   case OMPD_teams_distribute_parallel_for:
2216   case OMPD_target_teams:
2217   case OMPD_target_teams_distribute:
2218   case OMPD_target_teams_distribute_parallel_for:
2219   case OMPD_target_teams_distribute_parallel_for_simd:
2220   case OMPD_target_teams_distribute_simd:
2221   case OMPD_dispatch:
2222   case OMPD_masked:
2223     Diag(Tok, diag::err_omp_unexpected_directive)
2224         << 1 << getOpenMPDirectiveName(DKind);
2225     break;
2226   default:
2227     break;
2228   }
2229   while (Tok.isNot(tok::annot_pragma_openmp_end))
2230     ConsumeAnyToken();
2231   ConsumeAnyToken();
2232   return nullptr;
2233 }
2234 
2235 /// Parsing of declarative or executable OpenMP directives.
2236 ///
2237 ///       threadprivate-directive:
2238 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
2239 ///         annot_pragma_openmp_end
2240 ///
2241 ///       allocate-directive:
2242 ///         annot_pragma_openmp 'allocate' simple-variable-list
2243 ///         annot_pragma_openmp_end
2244 ///
2245 ///       declare-reduction-directive:
2246 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
2247 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
2248 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
2249 ///         annot_pragma_openmp_end
2250 ///
2251 ///       declare-mapper-directive:
2252 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2253 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2254 ///         annot_pragma_openmp_end
2255 ///
2256 ///       executable-directive:
2257 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
2258 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
2259 ///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
2260 ///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
2261 ///         'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
2262 ///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
2263 ///         'master taskloop' | 'master taskloop simd' | 'parallel master
2264 ///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
2265 ///         enter data' | 'target exit data' | 'target parallel' | 'target
2266 ///         parallel for' | 'target update' | 'distribute parallel for' |
2267 ///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
2268 ///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
2269 ///         simd' | 'teams distribute parallel for simd' | 'teams distribute
2270 ///         parallel for' | 'target teams' | 'target teams distribute' | 'target
2271 ///         teams distribute parallel for' | 'target teams distribute parallel
2272 ///         for simd' | 'target teams distribute simd' | 'masked' {clause}
2273 ///         annot_pragma_openmp_end
2274 ///
2275 StmtResult
ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx)2276 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
2277   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
2278   ParsingOpenMPDirectiveRAII DirScope(*this);
2279   ParenBraceBracketBalancer BalancerRAIIObj(*this);
2280   SmallVector<OMPClause *, 5> Clauses;
2281   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2282               llvm::omp::Clause_enumSize + 1>
2283       FirstClauses(llvm::omp::Clause_enumSize + 1);
2284   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
2285                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
2286   SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
2287   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
2288   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
2289   // Name of critical directive.
2290   DeclarationNameInfo DirName;
2291   StmtResult Directive = StmtError();
2292   bool HasAssociatedStatement = true;
2293 
2294   switch (DKind) {
2295   case OMPD_threadprivate: {
2296     // FIXME: Should this be permitted in C++?
2297     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2298         ParsedStmtContext()) {
2299       Diag(Tok, diag::err_omp_immediate_directive)
2300           << getOpenMPDirectiveName(DKind) << 0;
2301     }
2302     ConsumeToken();
2303     DeclDirectiveListParserHelper Helper(this, DKind);
2304     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2305                                   /*AllowScopeSpecifier=*/false)) {
2306       skipUntilPragmaOpenMPEnd(DKind);
2307       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
2308           Loc, Helper.getIdentifiers());
2309       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2310     }
2311     SkipUntil(tok::annot_pragma_openmp_end);
2312     break;
2313   }
2314   case OMPD_allocate: {
2315     // FIXME: Should this be permitted in C++?
2316     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2317         ParsedStmtContext()) {
2318       Diag(Tok, diag::err_omp_immediate_directive)
2319           << getOpenMPDirectiveName(DKind) << 0;
2320     }
2321     ConsumeToken();
2322     DeclDirectiveListParserHelper Helper(this, DKind);
2323     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2324                                   /*AllowScopeSpecifier=*/false)) {
2325       SmallVector<OMPClause *, 1> Clauses;
2326       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2327         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2328                     llvm::omp::Clause_enumSize + 1>
2329             FirstClauses(llvm::omp::Clause_enumSize + 1);
2330         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2331           OpenMPClauseKind CKind =
2332               Tok.isAnnotation() ? OMPC_unknown
2333                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
2334           Actions.StartOpenMPClause(CKind);
2335           OMPClause *Clause = ParseOpenMPClause(
2336               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2337           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2338                     StopBeforeMatch);
2339           FirstClauses[unsigned(CKind)].setInt(true);
2340           if (Clause != nullptr)
2341             Clauses.push_back(Clause);
2342           if (Tok.is(tok::annot_pragma_openmp_end)) {
2343             Actions.EndOpenMPClause();
2344             break;
2345           }
2346           // Skip ',' if any.
2347           if (Tok.is(tok::comma))
2348             ConsumeToken();
2349           Actions.EndOpenMPClause();
2350         }
2351         skipUntilPragmaOpenMPEnd(DKind);
2352       }
2353       DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2354           Loc, Helper.getIdentifiers(), Clauses);
2355       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2356     }
2357     SkipUntil(tok::annot_pragma_openmp_end);
2358     break;
2359   }
2360   case OMPD_declare_reduction:
2361     ConsumeToken();
2362     if (DeclGroupPtrTy Res =
2363             ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
2364       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2365       ConsumeAnyToken();
2366       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2367     } else {
2368       SkipUntil(tok::annot_pragma_openmp_end);
2369     }
2370     break;
2371   case OMPD_declare_mapper: {
2372     ConsumeToken();
2373     if (DeclGroupPtrTy Res =
2374             ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2375       // Skip the last annot_pragma_openmp_end.
2376       ConsumeAnnotationToken();
2377       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2378     } else {
2379       SkipUntil(tok::annot_pragma_openmp_end);
2380     }
2381     break;
2382   }
2383   case OMPD_flush:
2384   case OMPD_depobj:
2385   case OMPD_scan:
2386   case OMPD_taskyield:
2387   case OMPD_barrier:
2388   case OMPD_taskwait:
2389   case OMPD_cancellation_point:
2390   case OMPD_cancel:
2391   case OMPD_target_enter_data:
2392   case OMPD_target_exit_data:
2393   case OMPD_target_update:
2394   case OMPD_interop:
2395     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2396         ParsedStmtContext()) {
2397       Diag(Tok, diag::err_omp_immediate_directive)
2398           << getOpenMPDirectiveName(DKind) << 0;
2399     }
2400     HasAssociatedStatement = false;
2401     // Fall through for further analysis.
2402     LLVM_FALLTHROUGH;
2403   case OMPD_parallel:
2404   case OMPD_simd:
2405   case OMPD_tile:
2406   case OMPD_for:
2407   case OMPD_for_simd:
2408   case OMPD_sections:
2409   case OMPD_single:
2410   case OMPD_section:
2411   case OMPD_master:
2412   case OMPD_critical:
2413   case OMPD_parallel_for:
2414   case OMPD_parallel_for_simd:
2415   case OMPD_parallel_sections:
2416   case OMPD_parallel_master:
2417   case OMPD_task:
2418   case OMPD_ordered:
2419   case OMPD_atomic:
2420   case OMPD_target:
2421   case OMPD_teams:
2422   case OMPD_taskgroup:
2423   case OMPD_target_data:
2424   case OMPD_target_parallel:
2425   case OMPD_target_parallel_for:
2426   case OMPD_taskloop:
2427   case OMPD_taskloop_simd:
2428   case OMPD_master_taskloop:
2429   case OMPD_master_taskloop_simd:
2430   case OMPD_parallel_master_taskloop:
2431   case OMPD_parallel_master_taskloop_simd:
2432   case OMPD_distribute:
2433   case OMPD_distribute_parallel_for:
2434   case OMPD_distribute_parallel_for_simd:
2435   case OMPD_distribute_simd:
2436   case OMPD_target_parallel_for_simd:
2437   case OMPD_target_simd:
2438   case OMPD_teams_distribute:
2439   case OMPD_teams_distribute_simd:
2440   case OMPD_teams_distribute_parallel_for_simd:
2441   case OMPD_teams_distribute_parallel_for:
2442   case OMPD_target_teams:
2443   case OMPD_target_teams_distribute:
2444   case OMPD_target_teams_distribute_parallel_for:
2445   case OMPD_target_teams_distribute_parallel_for_simd:
2446   case OMPD_target_teams_distribute_simd:
2447   case OMPD_dispatch:
2448   case OMPD_masked: {
2449     // Special processing for flush and depobj clauses.
2450     Token ImplicitTok;
2451     bool ImplicitClauseAllowed = false;
2452     if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2453       ImplicitTok = Tok;
2454       ImplicitClauseAllowed = true;
2455     }
2456     ConsumeToken();
2457     // Parse directive name of the 'critical' directive if any.
2458     if (DKind == OMPD_critical) {
2459       BalancedDelimiterTracker T(*this, tok::l_paren,
2460                                  tok::annot_pragma_openmp_end);
2461       if (!T.consumeOpen()) {
2462         if (Tok.isAnyIdentifier()) {
2463           DirName =
2464               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2465           ConsumeAnyToken();
2466         } else {
2467           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2468         }
2469         T.consumeClose();
2470       }
2471     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2472       CancelRegion = parseOpenMPDirectiveKind(*this);
2473       if (Tok.isNot(tok::annot_pragma_openmp_end))
2474         ConsumeToken();
2475     }
2476 
2477     if (isOpenMPLoopDirective(DKind))
2478       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2479     if (isOpenMPSimdDirective(DKind))
2480       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2481     ParseScope OMPDirectiveScope(this, ScopeFlags);
2482     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
2483 
2484     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2485       bool HasImplicitClause = false;
2486       if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2487         HasImplicitClause = true;
2488         // Push copy of the current token back to stream to properly parse
2489         // pseudo-clause OMPFlushClause or OMPDepobjClause.
2490         PP.EnterToken(Tok, /*IsReinject*/ true);
2491         PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
2492         ConsumeAnyToken();
2493       }
2494       OpenMPClauseKind CKind = Tok.isAnnotation()
2495                                    ? OMPC_unknown
2496                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2497       if (HasImplicitClause) {
2498         assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2499         if (DKind == OMPD_flush) {
2500           CKind = OMPC_flush;
2501         } else {
2502           assert(DKind == OMPD_depobj &&
2503                  "Expected flush or depobj directives.");
2504           CKind = OMPC_depobj;
2505         }
2506       }
2507       // No more implicit clauses allowed.
2508       ImplicitClauseAllowed = false;
2509       Actions.StartOpenMPClause(CKind);
2510       HasImplicitClause = false;
2511       OMPClause *Clause = ParseOpenMPClause(
2512           DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
2513       FirstClauses[unsigned(CKind)].setInt(true);
2514       if (Clause) {
2515         FirstClauses[unsigned(CKind)].setPointer(Clause);
2516         Clauses.push_back(Clause);
2517       }
2518 
2519       // Skip ',' if any.
2520       if (Tok.is(tok::comma))
2521         ConsumeToken();
2522       Actions.EndOpenMPClause();
2523     }
2524     // End location of the directive.
2525     EndLoc = Tok.getLocation();
2526     // Consume final annot_pragma_openmp_end.
2527     ConsumeAnnotationToken();
2528 
2529     // OpenMP [2.13.8, ordered Construct, Syntax]
2530     // If the depend clause is specified, the ordered construct is a stand-alone
2531     // directive.
2532     if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) {
2533       if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2534           ParsedStmtContext()) {
2535         Diag(Loc, diag::err_omp_immediate_directive)
2536             << getOpenMPDirectiveName(DKind) << 1
2537             << getOpenMPClauseName(OMPC_depend);
2538       }
2539       HasAssociatedStatement = false;
2540     }
2541 
2542     if (DKind == OMPD_tile && !FirstClauses[unsigned(OMPC_sizes)].getInt()) {
2543       Diag(Loc, diag::err_omp_required_clause)
2544           << getOpenMPDirectiveName(OMPD_tile) << "sizes";
2545     }
2546 
2547     StmtResult AssociatedStmt;
2548     if (HasAssociatedStatement) {
2549       // The body is a block scope like in Lambdas and Blocks.
2550       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2551       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2552       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2553       // should have at least one compound statement scope within it.
2554       ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2555       {
2556         Sema::CompoundScopeRAII Scope(Actions);
2557         AssociatedStmt = ParseStatement();
2558 
2559         if (AssociatedStmt.isUsable() && isOpenMPLoopDirective(DKind) &&
2560             getLangOpts().OpenMPIRBuilder)
2561           AssociatedStmt =
2562               Actions.ActOnOpenMPCanonicalLoop(AssociatedStmt.get());
2563       }
2564       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2565     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2566                DKind == OMPD_target_exit_data) {
2567       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2568       AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2569                         Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2570                                                   /*isStmtExpr=*/false));
2571       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2572     }
2573     Directive = Actions.ActOnOpenMPExecutableDirective(
2574         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2575         EndLoc);
2576 
2577     // Exit scope.
2578     Actions.EndOpenMPDSABlock(Directive.get());
2579     OMPDirectiveScope.Exit();
2580     break;
2581   }
2582   case OMPD_declare_simd:
2583   case OMPD_declare_target:
2584   case OMPD_begin_declare_target:
2585   case OMPD_end_declare_target:
2586   case OMPD_requires:
2587   case OMPD_begin_declare_variant:
2588   case OMPD_end_declare_variant:
2589   case OMPD_declare_variant:
2590     Diag(Tok, diag::err_omp_unexpected_directive)
2591         << 1 << getOpenMPDirectiveName(DKind);
2592     SkipUntil(tok::annot_pragma_openmp_end);
2593     break;
2594   case OMPD_unknown:
2595   default:
2596     Diag(Tok, diag::err_omp_unknown_directive);
2597     SkipUntil(tok::annot_pragma_openmp_end);
2598     break;
2599   }
2600   return Directive;
2601 }
2602 
2603 // Parses simple list:
2604 //   simple-variable-list:
2605 //         '(' id-expression {, id-expression} ')'
2606 //
ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,const llvm::function_ref<void (CXXScopeSpec &,DeclarationNameInfo)> & Callback,bool AllowScopeSpecifier)2607 bool Parser::ParseOpenMPSimpleVarList(
2608     OpenMPDirectiveKind Kind,
2609     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)>
2610         &Callback,
2611     bool AllowScopeSpecifier) {
2612   // Parse '('.
2613   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2614   if (T.expectAndConsume(diag::err_expected_lparen_after,
2615                          getOpenMPDirectiveName(Kind).data()))
2616     return true;
2617   bool IsCorrect = true;
2618   bool NoIdentIsFound = true;
2619 
2620   // Read tokens while ')' or annot_pragma_openmp_end is not found.
2621   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2622     CXXScopeSpec SS;
2623     UnqualifiedId Name;
2624     // Read var name.
2625     Token PrevTok = Tok;
2626     NoIdentIsFound = false;
2627 
2628     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
2629         ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2630                                        /*ObjectHadErrors=*/false, false)) {
2631       IsCorrect = false;
2632       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2633                 StopBeforeMatch);
2634     } else if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
2635                                   /*ObjectHadErrors=*/false, false, false,
2636                                   false, false, nullptr, Name)) {
2637       IsCorrect = false;
2638       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2639                 StopBeforeMatch);
2640     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2641                Tok.isNot(tok::annot_pragma_openmp_end)) {
2642       IsCorrect = false;
2643       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2644                 StopBeforeMatch);
2645       Diag(PrevTok.getLocation(), diag::err_expected)
2646           << tok::identifier
2647           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
2648     } else {
2649       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2650     }
2651     // Consume ','.
2652     if (Tok.is(tok::comma)) {
2653       ConsumeToken();
2654     }
2655   }
2656 
2657   if (NoIdentIsFound) {
2658     Diag(Tok, diag::err_expected) << tok::identifier;
2659     IsCorrect = false;
2660   }
2661 
2662   // Parse ')'.
2663   IsCorrect = !T.consumeClose() && IsCorrect;
2664 
2665   return !IsCorrect;
2666 }
2667 
ParseOpenMPSizesClause()2668 OMPClause *Parser::ParseOpenMPSizesClause() {
2669   SourceLocation ClauseNameLoc = ConsumeToken();
2670   SmallVector<Expr *, 4> ValExprs;
2671 
2672   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2673   if (T.consumeOpen()) {
2674     Diag(Tok, diag::err_expected) << tok::l_paren;
2675     return nullptr;
2676   }
2677 
2678   while (true) {
2679     ExprResult Val = ParseConstantExpression();
2680     if (!Val.isUsable()) {
2681       T.skipToEnd();
2682       return nullptr;
2683     }
2684 
2685     ValExprs.push_back(Val.get());
2686 
2687     if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
2688       break;
2689 
2690     ExpectAndConsume(tok::comma);
2691   }
2692 
2693   T.consumeClose();
2694 
2695   return Actions.ActOnOpenMPSizesClause(
2696       ValExprs, ClauseNameLoc, T.getOpenLocation(), T.getCloseLocation());
2697 }
2698 
ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind)2699 OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
2700   SourceLocation Loc = Tok.getLocation();
2701   ConsumeAnyToken();
2702 
2703   // Parse '('.
2704   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2705   if (T.expectAndConsume(diag::err_expected_lparen_after, "uses_allocator"))
2706     return nullptr;
2707   SmallVector<Sema::UsesAllocatorsData, 4> Data;
2708   do {
2709     ExprResult Allocator = ParseCXXIdExpression();
2710     if (Allocator.isInvalid()) {
2711       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2712                 StopBeforeMatch);
2713       break;
2714     }
2715     Sema::UsesAllocatorsData &D = Data.emplace_back();
2716     D.Allocator = Allocator.get();
2717     if (Tok.is(tok::l_paren)) {
2718       BalancedDelimiterTracker T(*this, tok::l_paren,
2719                                  tok::annot_pragma_openmp_end);
2720       T.consumeOpen();
2721       ExprResult AllocatorTraits = ParseCXXIdExpression();
2722       T.consumeClose();
2723       if (AllocatorTraits.isInvalid()) {
2724         SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2725                   StopBeforeMatch);
2726         break;
2727       }
2728       D.AllocatorTraits = AllocatorTraits.get();
2729       D.LParenLoc = T.getOpenLocation();
2730       D.RParenLoc = T.getCloseLocation();
2731     }
2732     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
2733       Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;
2734     // Parse ','
2735     if (Tok.is(tok::comma))
2736       ConsumeAnyToken();
2737   } while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end));
2738   T.consumeClose();
2739   return Actions.ActOnOpenMPUsesAllocatorClause(Loc, T.getOpenLocation(),
2740                                                 T.getCloseLocation(), Data);
2741 }
2742 
2743 /// Parsing of OpenMP clauses.
2744 ///
2745 ///    clause:
2746 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
2747 ///       default-clause | private-clause | firstprivate-clause | shared-clause
2748 ///       | linear-clause | aligned-clause | collapse-clause |
2749 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
2750 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
2751 ///       mergeable-clause | flush-clause | read-clause | write-clause |
2752 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
2753 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
2754 ///       thread_limit-clause | priority-clause | grainsize-clause |
2755 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
2756 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
2757 ///       in_reduction-clause | allocator-clause | allocate-clause |
2758 ///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
2759 ///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
2760 ///       exclusive-clause | uses_allocators-clause | use_device_addr-clause
2761 ///
ParseOpenMPClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,bool FirstClause)2762 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
2763                                      OpenMPClauseKind CKind, bool FirstClause) {
2764   OMPClauseKind = CKind;
2765   OMPClause *Clause = nullptr;
2766   bool ErrorFound = false;
2767   bool WrongDirective = false;
2768   // Check if clause is allowed for the given directive.
2769   if (CKind != OMPC_unknown &&
2770       !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
2771     Diag(Tok, diag::err_omp_unexpected_clause)
2772         << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
2773     ErrorFound = true;
2774     WrongDirective = true;
2775   }
2776 
2777   switch (CKind) {
2778   case OMPC_final:
2779   case OMPC_num_threads:
2780   case OMPC_safelen:
2781   case OMPC_simdlen:
2782   case OMPC_collapse:
2783   case OMPC_ordered:
2784   case OMPC_num_teams:
2785   case OMPC_thread_limit:
2786   case OMPC_priority:
2787   case OMPC_grainsize:
2788   case OMPC_num_tasks:
2789   case OMPC_hint:
2790   case OMPC_allocator:
2791   case OMPC_depobj:
2792   case OMPC_detach:
2793   case OMPC_novariants:
2794   case OMPC_nocontext:
2795   case OMPC_filter:
2796     // OpenMP [2.5, Restrictions]
2797     //  At most one num_threads clause can appear on the directive.
2798     // OpenMP [2.8.1, simd construct, Restrictions]
2799     //  Only one safelen  clause can appear on a simd directive.
2800     //  Only one simdlen  clause can appear on a simd directive.
2801     //  Only one collapse clause can appear on a simd directive.
2802     // OpenMP [2.11.1, task Construct, Restrictions]
2803     //  At most one if clause can appear on the directive.
2804     //  At most one final clause can appear on the directive.
2805     // OpenMP [teams Construct, Restrictions]
2806     //  At most one num_teams clause can appear on the directive.
2807     //  At most one thread_limit clause can appear on the directive.
2808     // OpenMP [2.9.1, task Construct, Restrictions]
2809     // At most one priority clause can appear on the directive.
2810     // OpenMP [2.9.2, taskloop Construct, Restrictions]
2811     // At most one grainsize clause can appear on the directive.
2812     // OpenMP [2.9.2, taskloop Construct, Restrictions]
2813     // At most one num_tasks clause can appear on the directive.
2814     // OpenMP [2.11.3, allocate Directive, Restrictions]
2815     // At most one allocator clause can appear on the directive.
2816     // OpenMP 5.0, 2.10.1 task Construct, Restrictions.
2817     // At most one detach clause can appear on the directive.
2818     // OpenMP 5.1, 2.3.6 dispatch Construct, Restrictions.
2819     // At most one novariants clause can appear on a dispatch directive.
2820     // At most one nocontext clause can appear on a dispatch directive.
2821     if (!FirstClause) {
2822       Diag(Tok, diag::err_omp_more_one_clause)
2823           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2824       ErrorFound = true;
2825     }
2826 
2827     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
2828       Clause = ParseOpenMPClause(CKind, WrongDirective);
2829     else
2830       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
2831     break;
2832   case OMPC_default:
2833   case OMPC_proc_bind:
2834   case OMPC_atomic_default_mem_order:
2835   case OMPC_order:
2836     // OpenMP [2.14.3.1, Restrictions]
2837     //  Only a single default clause may be specified on a parallel, task or
2838     //  teams directive.
2839     // OpenMP [2.5, parallel Construct, Restrictions]
2840     //  At most one proc_bind clause can appear on the directive.
2841     // OpenMP [5.0, Requires directive, Restrictions]
2842     //  At most one atomic_default_mem_order clause can appear
2843     //  on the directive
2844     if (!FirstClause && CKind != OMPC_order) {
2845       Diag(Tok, diag::err_omp_more_one_clause)
2846           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2847       ErrorFound = true;
2848     }
2849 
2850     Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
2851     break;
2852   case OMPC_device:
2853   case OMPC_schedule:
2854   case OMPC_dist_schedule:
2855   case OMPC_defaultmap:
2856     // OpenMP [2.7.1, Restrictions, p. 3]
2857     //  Only one schedule clause can appear on a loop directive.
2858     // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
2859     //  At most one defaultmap clause can appear on the directive.
2860     // OpenMP 5.0 [2.12.5, target construct, Restrictions]
2861     //  At most one device clause can appear on the directive.
2862     if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
2863         !FirstClause) {
2864       Diag(Tok, diag::err_omp_more_one_clause)
2865           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2866       ErrorFound = true;
2867     }
2868     LLVM_FALLTHROUGH;
2869   case OMPC_if:
2870     Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
2871     break;
2872   case OMPC_nowait:
2873   case OMPC_untied:
2874   case OMPC_mergeable:
2875   case OMPC_read:
2876   case OMPC_write:
2877   case OMPC_capture:
2878   case OMPC_seq_cst:
2879   case OMPC_acq_rel:
2880   case OMPC_acquire:
2881   case OMPC_release:
2882   case OMPC_relaxed:
2883   case OMPC_threads:
2884   case OMPC_simd:
2885   case OMPC_nogroup:
2886   case OMPC_unified_address:
2887   case OMPC_unified_shared_memory:
2888   case OMPC_reverse_offload:
2889   case OMPC_dynamic_allocators:
2890     // OpenMP [2.7.1, Restrictions, p. 9]
2891     //  Only one ordered clause can appear on a loop directive.
2892     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
2893     //  Only one nowait clause can appear on a for directive.
2894     // OpenMP [5.0, Requires directive, Restrictions]
2895     //   Each of the requires clauses can appear at most once on the directive.
2896     if (!FirstClause) {
2897       Diag(Tok, diag::err_omp_more_one_clause)
2898           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2899       ErrorFound = true;
2900     }
2901 
2902     Clause = ParseOpenMPClause(CKind, WrongDirective);
2903     break;
2904   case OMPC_update:
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 = (DKind == OMPD_depobj)
2912                  ? ParseOpenMPSimpleClause(CKind, WrongDirective)
2913                  : ParseOpenMPClause(CKind, WrongDirective);
2914     break;
2915   case OMPC_private:
2916   case OMPC_firstprivate:
2917   case OMPC_lastprivate:
2918   case OMPC_shared:
2919   case OMPC_reduction:
2920   case OMPC_task_reduction:
2921   case OMPC_in_reduction:
2922   case OMPC_linear:
2923   case OMPC_aligned:
2924   case OMPC_copyin:
2925   case OMPC_copyprivate:
2926   case OMPC_flush:
2927   case OMPC_depend:
2928   case OMPC_map:
2929   case OMPC_to:
2930   case OMPC_from:
2931   case OMPC_use_device_ptr:
2932   case OMPC_use_device_addr:
2933   case OMPC_is_device_ptr:
2934   case OMPC_allocate:
2935   case OMPC_nontemporal:
2936   case OMPC_inclusive:
2937   case OMPC_exclusive:
2938   case OMPC_affinity:
2939     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
2940     break;
2941   case OMPC_sizes:
2942     if (!FirstClause) {
2943       Diag(Tok, diag::err_omp_more_one_clause)
2944           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2945       ErrorFound = true;
2946     }
2947 
2948     Clause = ParseOpenMPSizesClause();
2949     break;
2950   case OMPC_uses_allocators:
2951     Clause = ParseOpenMPUsesAllocatorClause(DKind);
2952     break;
2953   case OMPC_destroy:
2954     if (DKind != OMPD_interop) {
2955       if (!FirstClause) {
2956         Diag(Tok, diag::err_omp_more_one_clause)
2957             << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2958         ErrorFound = true;
2959       }
2960       Clause = ParseOpenMPClause(CKind, WrongDirective);
2961       break;
2962     }
2963     LLVM_FALLTHROUGH;
2964   case OMPC_init:
2965   case OMPC_use:
2966     Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
2967     break;
2968   case OMPC_device_type:
2969   case OMPC_unknown:
2970     skipUntilPragmaOpenMPEnd(DKind);
2971     break;
2972   case OMPC_threadprivate:
2973   case OMPC_uniform:
2974   case OMPC_match:
2975     if (!WrongDirective)
2976       Diag(Tok, diag::err_omp_unexpected_clause)
2977           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
2978     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
2979     break;
2980   default:
2981     break;
2982   }
2983   return ErrorFound ? nullptr : Clause;
2984 }
2985 
2986 /// Parses simple expression in parens for single-expression clauses of OpenMP
2987 /// constructs.
2988 /// \param RLoc Returned location of right paren.
ParseOpenMPParensExpr(StringRef ClauseName,SourceLocation & RLoc,bool IsAddressOfOperand)2989 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
2990                                          SourceLocation &RLoc,
2991                                          bool IsAddressOfOperand) {
2992   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2993   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
2994     return ExprError();
2995 
2996   SourceLocation ELoc = Tok.getLocation();
2997   ExprResult LHS(
2998       ParseCastExpression(AnyCastExpr, IsAddressOfOperand, NotTypeCast));
2999   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3000   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3001 
3002   // Parse ')'.
3003   RLoc = Tok.getLocation();
3004   if (!T.consumeClose())
3005     RLoc = T.getCloseLocation();
3006 
3007   return Val;
3008 }
3009 
3010 /// Parsing of OpenMP clauses with single expressions like 'final',
3011 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
3012 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
3013 /// 'detach'.
3014 ///
3015 ///    final-clause:
3016 ///      'final' '(' expression ')'
3017 ///
3018 ///    num_threads-clause:
3019 ///      'num_threads' '(' expression ')'
3020 ///
3021 ///    safelen-clause:
3022 ///      'safelen' '(' expression ')'
3023 ///
3024 ///    simdlen-clause:
3025 ///      'simdlen' '(' expression ')'
3026 ///
3027 ///    collapse-clause:
3028 ///      'collapse' '(' expression ')'
3029 ///
3030 ///    priority-clause:
3031 ///      'priority' '(' expression ')'
3032 ///
3033 ///    grainsize-clause:
3034 ///      'grainsize' '(' expression ')'
3035 ///
3036 ///    num_tasks-clause:
3037 ///      'num_tasks' '(' expression ')'
3038 ///
3039 ///    hint-clause:
3040 ///      'hint' '(' expression ')'
3041 ///
3042 ///    allocator-clause:
3043 ///      'allocator' '(' expression ')'
3044 ///
3045 ///    detach-clause:
3046 ///      'detach' '(' event-handler-expression ')'
3047 ///
ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,bool ParseOnly)3048 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
3049                                                bool ParseOnly) {
3050   SourceLocation Loc = ConsumeToken();
3051   SourceLocation LLoc = Tok.getLocation();
3052   SourceLocation RLoc;
3053 
3054   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
3055 
3056   if (Val.isInvalid())
3057     return nullptr;
3058 
3059   if (ParseOnly)
3060     return nullptr;
3061   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
3062 }
3063 
3064 /// Parsing of OpenMP clauses that use an interop-var.
3065 ///
3066 /// init-clause:
3067 ///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
3068 ///
3069 /// destroy-clause:
3070 ///   destroy(interop-var)
3071 ///
3072 /// use-clause:
3073 ///   use(interop-var)
3074 ///
3075 /// interop-modifier:
3076 ///   prefer_type(preference-list)
3077 ///
3078 /// preference-list:
3079 ///   foreign-runtime-id [, foreign-runtime-id]...
3080 ///
3081 /// foreign-runtime-id:
3082 ///   <string-literal> | <constant-integral-expression>
3083 ///
3084 /// interop-type:
3085 ///   target | targetsync
3086 ///
ParseOpenMPInteropClause(OpenMPClauseKind Kind,bool ParseOnly)3087 OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
3088                                             bool ParseOnly) {
3089   SourceLocation Loc = ConsumeToken();
3090   // Parse '('.
3091   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3092   if (T.expectAndConsume(diag::err_expected_lparen_after,
3093                          getOpenMPClauseName(Kind).data()))
3094     return nullptr;
3095 
3096   bool IsTarget = false;
3097   bool IsTargetSync = false;
3098   SmallVector<Expr *, 4> Prefs;
3099 
3100   if (Kind == OMPC_init) {
3101 
3102     // Parse optional interop-modifier.
3103     if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "prefer_type") {
3104       ConsumeToken();
3105       BalancedDelimiterTracker PT(*this, tok::l_paren,
3106                                   tok::annot_pragma_openmp_end);
3107       if (PT.expectAndConsume(diag::err_expected_lparen_after, "prefer_type"))
3108         return nullptr;
3109 
3110       while (Tok.isNot(tok::r_paren)) {
3111         SourceLocation Loc = Tok.getLocation();
3112         ExprResult LHS = ParseCastExpression(AnyCastExpr);
3113         ExprResult PTExpr = Actions.CorrectDelayedTyposInExpr(
3114             ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3115         PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc,
3116                                              /*DiscardedValue=*/false);
3117         if (PTExpr.isUsable())
3118           Prefs.push_back(PTExpr.get());
3119         else
3120           SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3121                     StopBeforeMatch);
3122 
3123         if (Tok.is(tok::comma))
3124           ConsumeToken();
3125       }
3126       PT.consumeClose();
3127     }
3128 
3129     if (!Prefs.empty()) {
3130       if (Tok.is(tok::comma))
3131         ConsumeToken();
3132       else
3133         Diag(Tok, diag::err_omp_expected_punc_after_interop_mod);
3134     }
3135 
3136     // Parse the interop-types.
3137     bool HasError = false;
3138     while (Tok.is(tok::identifier)) {
3139       if (PP.getSpelling(Tok) == "target") {
3140         // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
3141         // Each interop-type may be specified on an action-clause at most
3142         // once.
3143         if (IsTarget)
3144           Diag(Tok, diag::warn_omp_more_one_interop_type) << "target";
3145         IsTarget = true;
3146       } else if (PP.getSpelling(Tok) == "targetsync") {
3147         if (IsTargetSync)
3148           Diag(Tok, diag::warn_omp_more_one_interop_type) << "targetsync";
3149         IsTargetSync = true;
3150       } else {
3151         HasError = true;
3152         Diag(Tok, diag::err_omp_expected_interop_type);
3153       }
3154       ConsumeToken();
3155 
3156       if (!Tok.is(tok::comma))
3157         break;
3158       ConsumeToken();
3159     }
3160     if (!HasError && !IsTarget && !IsTargetSync)
3161       Diag(Tok, diag::err_omp_expected_interop_type);
3162 
3163     if (Tok.is(tok::colon))
3164       ConsumeToken();
3165     else if (IsTarget || IsTargetSync)
3166       Diag(Tok, diag::warn_pragma_expected_colon) << "interop types";
3167   }
3168 
3169   // Parse the variable.
3170   SourceLocation VarLoc = Tok.getLocation();
3171   ExprResult InteropVarExpr =
3172       Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3173   if (!InteropVarExpr.isUsable()) {
3174     SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3175               StopBeforeMatch);
3176   }
3177 
3178   // Parse ')'.
3179   SourceLocation RLoc = Tok.getLocation();
3180   if (!T.consumeClose())
3181     RLoc = T.getCloseLocation();
3182 
3183   if (ParseOnly || !InteropVarExpr.isUsable() ||
3184       (Kind == OMPC_init && !IsTarget && !IsTargetSync))
3185     return nullptr;
3186 
3187   if (Kind == OMPC_init)
3188     return Actions.ActOnOpenMPInitClause(InteropVarExpr.get(), Prefs, IsTarget,
3189                                          IsTargetSync, Loc, T.getOpenLocation(),
3190                                          VarLoc, RLoc);
3191   if (Kind == OMPC_use)
3192     return Actions.ActOnOpenMPUseClause(InteropVarExpr.get(), Loc,
3193                                         T.getOpenLocation(), VarLoc, RLoc);
3194 
3195   if (Kind == OMPC_destroy)
3196     return Actions.ActOnOpenMPDestroyClause(InteropVarExpr.get(), Loc,
3197                                             T.getOpenLocation(), VarLoc, RLoc);
3198 
3199   llvm_unreachable("Unexpected interop variable clause.");
3200 }
3201 
3202 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
3203 ///
3204 ///    default-clause:
3205 ///         'default' '(' 'none' | 'shared' | 'firstprivate' ')'
3206 ///
3207 ///    proc_bind-clause:
3208 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
3209 ///
3210 ///    update-clause:
3211 ///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
3212 ///
ParseOpenMPSimpleClause(OpenMPClauseKind Kind,bool ParseOnly)3213 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
3214                                            bool ParseOnly) {
3215   llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
3216   if (!Val || ParseOnly)
3217     return nullptr;
3218   if (getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3219       static_cast<DefaultKind>(Val.getValue().Type) ==
3220           OMP_DEFAULT_firstprivate) {
3221     Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa)
3222         << getOpenMPClauseName(OMPC_firstprivate)
3223         << getOpenMPClauseName(OMPC_default) << "5.1";
3224     return nullptr;
3225   }
3226   return Actions.ActOnOpenMPSimpleClause(
3227       Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
3228       Val.getValue().Loc, Val.getValue().RLoc);
3229 }
3230 
3231 /// Parsing of OpenMP clauses like 'ordered'.
3232 ///
3233 ///    ordered-clause:
3234 ///         'ordered'
3235 ///
3236 ///    nowait-clause:
3237 ///         'nowait'
3238 ///
3239 ///    untied-clause:
3240 ///         'untied'
3241 ///
3242 ///    mergeable-clause:
3243 ///         'mergeable'
3244 ///
3245 ///    read-clause:
3246 ///         'read'
3247 ///
3248 ///    threads-clause:
3249 ///         'threads'
3250 ///
3251 ///    simd-clause:
3252 ///         'simd'
3253 ///
3254 ///    nogroup-clause:
3255 ///         'nogroup'
3256 ///
ParseOpenMPClause(OpenMPClauseKind Kind,bool ParseOnly)3257 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
3258   SourceLocation Loc = Tok.getLocation();
3259   ConsumeAnyToken();
3260 
3261   if (ParseOnly)
3262     return nullptr;
3263   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3264 }
3265 
3266 /// Parsing of OpenMP clauses with single expressions and some additional
3267 /// argument like 'schedule' or 'dist_schedule'.
3268 ///
3269 ///    schedule-clause:
3270 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
3271 ///      ')'
3272 ///
3273 ///    if-clause:
3274 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
3275 ///
3276 ///    defaultmap:
3277 ///      'defaultmap' '(' modifier [ ':' kind ] ')'
3278 ///
3279 ///    device-clause:
3280 ///      'device' '(' [ device-modifier ':' ] expression ')'
3281 ///
ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,OpenMPClauseKind Kind,bool ParseOnly)3282 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
3283                                                       OpenMPClauseKind Kind,
3284                                                       bool ParseOnly) {
3285   SourceLocation Loc = ConsumeToken();
3286   SourceLocation DelimLoc;
3287   // Parse '('.
3288   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3289   if (T.expectAndConsume(diag::err_expected_lparen_after,
3290                          getOpenMPClauseName(Kind).data()))
3291     return nullptr;
3292 
3293   ExprResult Val;
3294   SmallVector<unsigned, 4> Arg;
3295   SmallVector<SourceLocation, 4> KLoc;
3296   if (Kind == OMPC_schedule) {
3297     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3298     Arg.resize(NumberOfElements);
3299     KLoc.resize(NumberOfElements);
3300     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
3301     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
3302     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
3303     unsigned KindModifier = getOpenMPSimpleClauseType(
3304         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3305         getLangOpts().OpenMP);
3306     if (KindModifier > OMPC_SCHEDULE_unknown) {
3307       // Parse 'modifier'
3308       Arg[Modifier1] = KindModifier;
3309       KLoc[Modifier1] = Tok.getLocation();
3310       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3311           Tok.isNot(tok::annot_pragma_openmp_end))
3312         ConsumeAnyToken();
3313       if (Tok.is(tok::comma)) {
3314         // Parse ',' 'modifier'
3315         ConsumeAnyToken();
3316         KindModifier = getOpenMPSimpleClauseType(
3317             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3318             getLangOpts().OpenMP);
3319         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
3320                              ? KindModifier
3321                              : (unsigned)OMPC_SCHEDULE_unknown;
3322         KLoc[Modifier2] = Tok.getLocation();
3323         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3324             Tok.isNot(tok::annot_pragma_openmp_end))
3325           ConsumeAnyToken();
3326       }
3327       // Parse ':'
3328       if (Tok.is(tok::colon))
3329         ConsumeAnyToken();
3330       else
3331         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
3332       KindModifier = getOpenMPSimpleClauseType(
3333           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3334           getLangOpts().OpenMP);
3335     }
3336     Arg[ScheduleKind] = KindModifier;
3337     KLoc[ScheduleKind] = Tok.getLocation();
3338     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3339         Tok.isNot(tok::annot_pragma_openmp_end))
3340       ConsumeAnyToken();
3341     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3342          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3343          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3344         Tok.is(tok::comma))
3345       DelimLoc = ConsumeAnyToken();
3346   } else if (Kind == OMPC_dist_schedule) {
3347     Arg.push_back(getOpenMPSimpleClauseType(
3348         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3349         getLangOpts().OpenMP));
3350     KLoc.push_back(Tok.getLocation());
3351     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3352         Tok.isNot(tok::annot_pragma_openmp_end))
3353       ConsumeAnyToken();
3354     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3355       DelimLoc = ConsumeAnyToken();
3356   } else if (Kind == OMPC_defaultmap) {
3357     // Get a defaultmap modifier
3358     unsigned Modifier = getOpenMPSimpleClauseType(
3359         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3360         getLangOpts().OpenMP);
3361     // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
3362     // pointer
3363     if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
3364       Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
3365     Arg.push_back(Modifier);
3366     KLoc.push_back(Tok.getLocation());
3367     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3368         Tok.isNot(tok::annot_pragma_openmp_end))
3369       ConsumeAnyToken();
3370     // Parse ':'
3371     if (Tok.is(tok::colon) || getLangOpts().OpenMP < 50) {
3372       if (Tok.is(tok::colon))
3373         ConsumeAnyToken();
3374       else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
3375         Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
3376       // Get a defaultmap kind
3377       Arg.push_back(getOpenMPSimpleClauseType(
3378           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3379           getLangOpts().OpenMP));
3380       KLoc.push_back(Tok.getLocation());
3381       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3382           Tok.isNot(tok::annot_pragma_openmp_end))
3383         ConsumeAnyToken();
3384     } else {
3385       Arg.push_back(OMPC_DEFAULTMAP_unknown);
3386       KLoc.push_back(SourceLocation());
3387     }
3388   } else if (Kind == OMPC_device) {
3389     // Only target executable directives support extended device construct.
3390     if (isOpenMPTargetExecutionDirective(DKind) && getLangOpts().OpenMP >= 50 &&
3391         NextToken().is(tok::colon)) {
3392       // Parse optional <device modifier> ':'
3393       Arg.push_back(getOpenMPSimpleClauseType(
3394           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3395           getLangOpts().OpenMP));
3396       KLoc.push_back(Tok.getLocation());
3397       ConsumeAnyToken();
3398       // Parse ':'
3399       ConsumeAnyToken();
3400     } else {
3401       Arg.push_back(OMPC_DEVICE_unknown);
3402       KLoc.emplace_back();
3403     }
3404   } else {
3405     assert(Kind == OMPC_if);
3406     KLoc.push_back(Tok.getLocation());
3407     TentativeParsingAction TPA(*this);
3408     auto DK = parseOpenMPDirectiveKind(*this);
3409     Arg.push_back(DK);
3410     if (DK != OMPD_unknown) {
3411       ConsumeToken();
3412       if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
3413         TPA.Commit();
3414         DelimLoc = ConsumeToken();
3415       } else {
3416         TPA.Revert();
3417         Arg.back() = unsigned(OMPD_unknown);
3418       }
3419     } else {
3420       TPA.Revert();
3421     }
3422   }
3423 
3424   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
3425                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
3426                           Kind == OMPC_if || Kind == OMPC_device;
3427   if (NeedAnExpression) {
3428     SourceLocation ELoc = Tok.getLocation();
3429     ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
3430     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
3431     Val =
3432         Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3433   }
3434 
3435   // Parse ')'.
3436   SourceLocation RLoc = Tok.getLocation();
3437   if (!T.consumeClose())
3438     RLoc = T.getCloseLocation();
3439 
3440   if (NeedAnExpression && Val.isInvalid())
3441     return nullptr;
3442 
3443   if (ParseOnly)
3444     return nullptr;
3445   return Actions.ActOnOpenMPSingleExprWithArgClause(
3446       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3447 }
3448 
ParseReductionId(Parser & P,CXXScopeSpec & ReductionIdScopeSpec,UnqualifiedId & ReductionId)3449 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
3450                              UnqualifiedId &ReductionId) {
3451   if (ReductionIdScopeSpec.isEmpty()) {
3452     auto OOK = OO_None;
3453     switch (P.getCurToken().getKind()) {
3454     case tok::plus:
3455       OOK = OO_Plus;
3456       break;
3457     case tok::minus:
3458       OOK = OO_Minus;
3459       break;
3460     case tok::star:
3461       OOK = OO_Star;
3462       break;
3463     case tok::amp:
3464       OOK = OO_Amp;
3465       break;
3466     case tok::pipe:
3467       OOK = OO_Pipe;
3468       break;
3469     case tok::caret:
3470       OOK = OO_Caret;
3471       break;
3472     case tok::ampamp:
3473       OOK = OO_AmpAmp;
3474       break;
3475     case tok::pipepipe:
3476       OOK = OO_PipePipe;
3477       break;
3478     default:
3479       break;
3480     }
3481     if (OOK != OO_None) {
3482       SourceLocation OpLoc = P.ConsumeToken();
3483       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
3484       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
3485       return false;
3486     }
3487   }
3488   return P.ParseUnqualifiedId(
3489       ReductionIdScopeSpec, /*ObjectType=*/nullptr,
3490       /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
3491       /*AllowDestructorName*/ false,
3492       /*AllowConstructorName*/ false,
3493       /*AllowDeductionGuide*/ false, nullptr, ReductionId);
3494 }
3495 
3496 /// Checks if the token is a valid map-type-modifier.
3497 /// FIXME: It will return an OpenMPMapClauseKind if that's what it parses.
isMapModifier(Parser & P)3498 static OpenMPMapModifierKind isMapModifier(Parser &P) {
3499   Token Tok = P.getCurToken();
3500   if (!Tok.is(tok::identifier))
3501     return OMPC_MAP_MODIFIER_unknown;
3502 
3503   Preprocessor &PP = P.getPreprocessor();
3504   OpenMPMapModifierKind TypeModifier =
3505       static_cast<OpenMPMapModifierKind>(getOpenMPSimpleClauseType(
3506           OMPC_map, PP.getSpelling(Tok), P.getLangOpts().OpenMP));
3507   return TypeModifier;
3508 }
3509 
3510 /// Parse the mapper modifier in map, to, and from clauses.
parseMapperModifier(OpenMPVarListDataTy & Data)3511 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
3512   // Parse '('.
3513   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
3514   if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
3515     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3516               StopBeforeMatch);
3517     return true;
3518   }
3519   // Parse mapper-identifier
3520   if (getLangOpts().CPlusPlus)
3521     ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3522                                    /*ObjectType=*/nullptr,
3523                                    /*ObjectHadErrors=*/false,
3524                                    /*EnteringContext=*/false);
3525   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
3526     Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
3527     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3528               StopBeforeMatch);
3529     return true;
3530   }
3531   auto &DeclNames = Actions.getASTContext().DeclarationNames;
3532   Data.ReductionOrMapperId = DeclarationNameInfo(
3533       DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
3534   ConsumeToken();
3535   // Parse ')'.
3536   return T.consumeClose();
3537 }
3538 
3539 /// Parse map-type-modifiers in map clause.
3540 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3541 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
3542 /// present
parseMapTypeModifiers(OpenMPVarListDataTy & Data)3543 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
3544   while (getCurToken().isNot(tok::colon)) {
3545     OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
3546     if (TypeModifier == OMPC_MAP_MODIFIER_always ||
3547         TypeModifier == OMPC_MAP_MODIFIER_close ||
3548         TypeModifier == OMPC_MAP_MODIFIER_present) {
3549       Data.MapTypeModifiers.push_back(TypeModifier);
3550       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3551       ConsumeToken();
3552     } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
3553       Data.MapTypeModifiers.push_back(TypeModifier);
3554       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3555       ConsumeToken();
3556       if (parseMapperModifier(Data))
3557         return true;
3558     } else {
3559       // For the case of unknown map-type-modifier or a map-type.
3560       // Map-type is followed by a colon; the function returns when it
3561       // encounters a token followed by a colon.
3562       if (Tok.is(tok::comma)) {
3563         Diag(Tok, diag::err_omp_map_type_modifier_missing);
3564         ConsumeToken();
3565         continue;
3566       }
3567       // Potential map-type token as it is followed by a colon.
3568       if (PP.LookAhead(0).is(tok::colon))
3569         return false;
3570       Diag(Tok, diag::err_omp_unknown_map_type_modifier)
3571           << (getLangOpts().OpenMP >= 51 ? 1 : 0);
3572       ConsumeToken();
3573     }
3574     if (getCurToken().is(tok::comma))
3575       ConsumeToken();
3576   }
3577   return false;
3578 }
3579 
3580 /// Checks if the token is a valid map-type.
3581 /// FIXME: It will return an OpenMPMapModifierKind if that's what it parses.
isMapType(Parser & P)3582 static OpenMPMapClauseKind isMapType(Parser &P) {
3583   Token Tok = P.getCurToken();
3584   // The map-type token can be either an identifier or the C++ delete keyword.
3585   if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
3586     return OMPC_MAP_unknown;
3587   Preprocessor &PP = P.getPreprocessor();
3588   OpenMPMapClauseKind MapType =
3589       static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
3590           OMPC_map, PP.getSpelling(Tok), P.getLangOpts().OpenMP));
3591   return MapType;
3592 }
3593 
3594 /// Parse map-type in map clause.
3595 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3596 /// where, map-type ::= to | from | tofrom | alloc | release | delete
parseMapType(Parser & P,Parser::OpenMPVarListDataTy & Data)3597 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
3598   Token Tok = P.getCurToken();
3599   if (Tok.is(tok::colon)) {
3600     P.Diag(Tok, diag::err_omp_map_type_missing);
3601     return;
3602   }
3603   Data.ExtraModifier = isMapType(P);
3604   if (Data.ExtraModifier == OMPC_MAP_unknown)
3605     P.Diag(Tok, diag::err_omp_unknown_map_type);
3606   P.ConsumeToken();
3607 }
3608 
3609 /// Parses simple expression in parens for single-expression clauses of OpenMP
3610 /// constructs.
ParseOpenMPIteratorsExpr()3611 ExprResult Parser::ParseOpenMPIteratorsExpr() {
3612   assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
3613          "Expected 'iterator' token.");
3614   SourceLocation IteratorKwLoc = ConsumeToken();
3615 
3616   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3617   if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator"))
3618     return ExprError();
3619 
3620   SourceLocation LLoc = T.getOpenLocation();
3621   SmallVector<Sema::OMPIteratorData, 4> Data;
3622   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
3623     // Check if the type parsing is required.
3624     ParsedType IteratorType;
3625     if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) {
3626       // identifier '=' is not found - parse type.
3627       TypeResult TR = ParseTypeName();
3628       if (TR.isInvalid()) {
3629         T.skipToEnd();
3630         return ExprError();
3631       }
3632       IteratorType = TR.get();
3633     }
3634 
3635     // Parse identifier.
3636     IdentifierInfo *II = nullptr;
3637     SourceLocation IdLoc;
3638     if (Tok.is(tok::identifier)) {
3639       II = Tok.getIdentifierInfo();
3640       IdLoc = ConsumeToken();
3641     } else {
3642       Diag(Tok, diag::err_expected_unqualified_id) << 0;
3643     }
3644 
3645     // Parse '='.
3646     SourceLocation AssignLoc;
3647     if (Tok.is(tok::equal))
3648       AssignLoc = ConsumeToken();
3649     else
3650       Diag(Tok, diag::err_omp_expected_equal_in_iterator);
3651 
3652     // Parse range-specification - <begin> ':' <end> [ ':' <step> ]
3653     ColonProtectionRAIIObject ColonRAII(*this);
3654     // Parse <begin>
3655     SourceLocation Loc = Tok.getLocation();
3656     ExprResult LHS = ParseCastExpression(AnyCastExpr);
3657     ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
3658         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3659     Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
3660                                         /*DiscardedValue=*/false);
3661     // Parse ':'.
3662     SourceLocation ColonLoc;
3663     if (Tok.is(tok::colon))
3664       ColonLoc = ConsumeToken();
3665 
3666     // Parse <end>
3667     Loc = Tok.getLocation();
3668     LHS = ParseCastExpression(AnyCastExpr);
3669     ExprResult End = Actions.CorrectDelayedTyposInExpr(
3670         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3671     End = Actions.ActOnFinishFullExpr(End.get(), Loc,
3672                                       /*DiscardedValue=*/false);
3673 
3674     SourceLocation SecColonLoc;
3675     ExprResult Step;
3676     // Parse optional step.
3677     if (Tok.is(tok::colon)) {
3678       // Parse ':'
3679       SecColonLoc = ConsumeToken();
3680       // Parse <step>
3681       Loc = Tok.getLocation();
3682       LHS = ParseCastExpression(AnyCastExpr);
3683       Step = Actions.CorrectDelayedTyposInExpr(
3684           ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3685       Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
3686                                          /*DiscardedValue=*/false);
3687     }
3688 
3689     // Parse ',' or ')'
3690     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
3691       Diag(Tok, diag::err_omp_expected_punc_after_iterator);
3692     if (Tok.is(tok::comma))
3693       ConsumeToken();
3694 
3695     Sema::OMPIteratorData &D = Data.emplace_back();
3696     D.DeclIdent = II;
3697     D.DeclIdentLoc = IdLoc;
3698     D.Type = IteratorType;
3699     D.AssignLoc = AssignLoc;
3700     D.ColonLoc = ColonLoc;
3701     D.SecColonLoc = SecColonLoc;
3702     D.Range.Begin = Begin.get();
3703     D.Range.End = End.get();
3704     D.Range.Step = Step.get();
3705   }
3706 
3707   // Parse ')'.
3708   SourceLocation RLoc = Tok.getLocation();
3709   if (!T.consumeClose())
3710     RLoc = T.getCloseLocation();
3711 
3712   return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc,
3713                                       Data);
3714 }
3715 
3716 /// Parses clauses with list.
ParseOpenMPVarList(OpenMPDirectiveKind DKind,OpenMPClauseKind Kind,SmallVectorImpl<Expr * > & Vars,OpenMPVarListDataTy & Data)3717 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
3718                                 OpenMPClauseKind Kind,
3719                                 SmallVectorImpl<Expr *> &Vars,
3720                                 OpenMPVarListDataTy &Data) {
3721   UnqualifiedId UnqualifiedReductionId;
3722   bool InvalidReductionId = false;
3723   bool IsInvalidMapperModifier = false;
3724 
3725   // Parse '('.
3726   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3727   if (T.expectAndConsume(diag::err_expected_lparen_after,
3728                          getOpenMPClauseName(Kind).data()))
3729     return true;
3730 
3731   bool HasIterator = false;
3732   bool NeedRParenForLinear = false;
3733   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
3734                                    tok::annot_pragma_openmp_end);
3735   // Handle reduction-identifier for reduction clause.
3736   if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
3737       Kind == OMPC_in_reduction) {
3738     Data.ExtraModifier = OMPC_REDUCTION_unknown;
3739     if (Kind == OMPC_reduction && getLangOpts().OpenMP >= 50 &&
3740         (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
3741         NextToken().is(tok::comma)) {
3742       // Parse optional reduction modifier.
3743       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3744                                                      getLangOpts().OpenMP);
3745       Data.ExtraModifierLoc = Tok.getLocation();
3746       ConsumeToken();
3747       assert(Tok.is(tok::comma) && "Expected comma.");
3748       (void)ConsumeToken();
3749     }
3750     ColonProtectionRAIIObject ColonRAII(*this);
3751     if (getLangOpts().CPlusPlus)
3752       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3753                                      /*ObjectType=*/nullptr,
3754                                      /*ObjectHadErrors=*/false,
3755                                      /*EnteringContext=*/false);
3756     InvalidReductionId = ParseReductionId(
3757         *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
3758     if (InvalidReductionId) {
3759       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3760                 StopBeforeMatch);
3761     }
3762     if (Tok.is(tok::colon))
3763       Data.ColonLoc = ConsumeToken();
3764     else
3765       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
3766     if (!InvalidReductionId)
3767       Data.ReductionOrMapperId =
3768           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
3769   } else if (Kind == OMPC_depend) {
3770     if (getLangOpts().OpenMP >= 50) {
3771       if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") {
3772         // Handle optional dependence modifier.
3773         // iterator(iterators-definition)
3774         // where iterators-definition is iterator-specifier [,
3775         // iterators-definition ]
3776         // where iterator-specifier is [ iterator-type ] identifier =
3777         // range-specification
3778         HasIterator = true;
3779         EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3780         ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
3781         Data.DepModOrTailExpr = IteratorRes.get();
3782         // Parse ','
3783         ExpectAndConsume(tok::comma);
3784       }
3785     }
3786     // Handle dependency type for depend clause.
3787     ColonProtectionRAIIObject ColonRAII(*this);
3788     Data.ExtraModifier = getOpenMPSimpleClauseType(
3789         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "",
3790         getLangOpts().OpenMP);
3791     Data.ExtraModifierLoc = Tok.getLocation();
3792     if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
3793       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3794                 StopBeforeMatch);
3795     } else {
3796       ConsumeToken();
3797       // Special processing for depend(source) clause.
3798       if (DKind == OMPD_ordered && Data.ExtraModifier == OMPC_DEPEND_source) {
3799         // Parse ')'.
3800         T.consumeClose();
3801         return false;
3802       }
3803     }
3804     if (Tok.is(tok::colon)) {
3805       Data.ColonLoc = ConsumeToken();
3806     } else {
3807       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
3808                                       : diag::warn_pragma_expected_colon)
3809           << "dependency type";
3810     }
3811   } else if (Kind == OMPC_linear) {
3812     // Try to parse modifier if any.
3813     Data.ExtraModifier = OMPC_LINEAR_val;
3814     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
3815       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3816                                                      getLangOpts().OpenMP);
3817       Data.ExtraModifierLoc = ConsumeToken();
3818       LinearT.consumeOpen();
3819       NeedRParenForLinear = true;
3820     }
3821   } else if (Kind == OMPC_lastprivate) {
3822     // Try to parse modifier if any.
3823     Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
3824     // Conditional modifier allowed only in OpenMP 5.0 and not supported in
3825     // distribute and taskloop based directives.
3826     if ((getLangOpts().OpenMP >= 50 && !isOpenMPDistributeDirective(DKind) &&
3827          !isOpenMPTaskLoopDirective(DKind)) &&
3828         Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
3829       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3830                                                      getLangOpts().OpenMP);
3831       Data.ExtraModifierLoc = Tok.getLocation();
3832       ConsumeToken();
3833       assert(Tok.is(tok::colon) && "Expected colon.");
3834       Data.ColonLoc = ConsumeToken();
3835     }
3836   } else if (Kind == OMPC_map) {
3837     // Handle map type for map clause.
3838     ColonProtectionRAIIObject ColonRAII(*this);
3839 
3840     // The first identifier may be a list item, a map-type or a
3841     // map-type-modifier. The map-type can also be delete which has the same
3842     // spelling of the C++ delete keyword.
3843     Data.ExtraModifier = OMPC_MAP_unknown;
3844     Data.ExtraModifierLoc = Tok.getLocation();
3845 
3846     // Check for presence of a colon in the map clause.
3847     TentativeParsingAction TPA(*this);
3848     bool ColonPresent = false;
3849     if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3850                   StopBeforeMatch)) {
3851       if (Tok.is(tok::colon))
3852         ColonPresent = true;
3853     }
3854     TPA.Revert();
3855     // Only parse map-type-modifier[s] and map-type if a colon is present in
3856     // the map clause.
3857     if (ColonPresent) {
3858       IsInvalidMapperModifier = parseMapTypeModifiers(Data);
3859       if (!IsInvalidMapperModifier)
3860         parseMapType(*this, Data);
3861       else
3862         SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
3863     }
3864     if (Data.ExtraModifier == OMPC_MAP_unknown) {
3865       Data.ExtraModifier = OMPC_MAP_tofrom;
3866       Data.IsMapTypeImplicit = true;
3867     }
3868 
3869     if (Tok.is(tok::colon))
3870       Data.ColonLoc = ConsumeToken();
3871   } else if (Kind == OMPC_to || Kind == OMPC_from) {
3872     while (Tok.is(tok::identifier)) {
3873       auto Modifier =
3874           static_cast<OpenMPMotionModifierKind>(getOpenMPSimpleClauseType(
3875               Kind, PP.getSpelling(Tok), getLangOpts().OpenMP));
3876       if (Modifier == OMPC_MOTION_MODIFIER_unknown)
3877         break;
3878       Data.MotionModifiers.push_back(Modifier);
3879       Data.MotionModifiersLoc.push_back(Tok.getLocation());
3880       ConsumeToken();
3881       if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
3882         IsInvalidMapperModifier = parseMapperModifier(Data);
3883         if (IsInvalidMapperModifier)
3884           break;
3885       }
3886       // OpenMP < 5.1 doesn't permit a ',' or additional modifiers.
3887       if (getLangOpts().OpenMP < 51)
3888         break;
3889       // OpenMP 5.1 accepts an optional ',' even if the next character is ':'.
3890       // TODO: Is that intentional?
3891       if (Tok.is(tok::comma))
3892         ConsumeToken();
3893     }
3894     if (!Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
3895       if (!IsInvalidMapperModifier) {
3896         if (getLangOpts().OpenMP < 51)
3897           Diag(Tok, diag::warn_pragma_expected_colon) << ")";
3898         else
3899           Diag(Tok, diag::warn_pragma_expected_colon) << "motion modifier";
3900       }
3901       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3902                 StopBeforeMatch);
3903     }
3904     // OpenMP 5.1 permits a ':' even without a preceding modifier.  TODO: Is
3905     // that intentional?
3906     if ((!Data.MotionModifiers.empty() || getLangOpts().OpenMP >= 51) &&
3907         Tok.is(tok::colon))
3908       Data.ColonLoc = ConsumeToken();
3909   } else if (Kind == OMPC_allocate ||
3910              (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
3911               PP.getSpelling(Tok) == "iterator")) {
3912     // Handle optional allocator expression followed by colon delimiter.
3913     ColonProtectionRAIIObject ColonRAII(*this);
3914     TentativeParsingAction TPA(*this);
3915     // OpenMP 5.0, 2.10.1, task Construct.
3916     // where aff-modifier is one of the following:
3917     // iterator(iterators-definition)
3918     ExprResult Tail;
3919     if (Kind == OMPC_allocate) {
3920       Tail = ParseAssignmentExpression();
3921     } else {
3922       HasIterator = true;
3923       EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3924       Tail = ParseOpenMPIteratorsExpr();
3925     }
3926     Tail = Actions.CorrectDelayedTyposInExpr(Tail);
3927     Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
3928                                        /*DiscardedValue=*/false);
3929     if (Tail.isUsable()) {
3930       if (Tok.is(tok::colon)) {
3931         Data.DepModOrTailExpr = Tail.get();
3932         Data.ColonLoc = ConsumeToken();
3933         TPA.Commit();
3934       } else {
3935         // Colon not found, parse only list of variables.
3936         TPA.Revert();
3937       }
3938     } else {
3939       // Parsing was unsuccessfull, revert and skip to the end of clause or
3940       // directive.
3941       TPA.Revert();
3942       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3943                 StopBeforeMatch);
3944     }
3945   }
3946 
3947   bool IsComma =
3948       (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
3949        Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
3950       (Kind == OMPC_reduction && !InvalidReductionId) ||
3951       (Kind == OMPC_map && Data.ExtraModifier != OMPC_MAP_unknown) ||
3952       (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown);
3953   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
3954   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
3955                      Tok.isNot(tok::annot_pragma_openmp_end))) {
3956     ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope);
3957     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
3958     // Parse variable
3959     ExprResult VarExpr =
3960         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3961     if (VarExpr.isUsable()) {
3962       Vars.push_back(VarExpr.get());
3963     } else {
3964       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3965                 StopBeforeMatch);
3966     }
3967     // Skip ',' if any
3968     IsComma = Tok.is(tok::comma);
3969     if (IsComma)
3970       ConsumeToken();
3971     else if (Tok.isNot(tok::r_paren) &&
3972              Tok.isNot(tok::annot_pragma_openmp_end) &&
3973              (!MayHaveTail || Tok.isNot(tok::colon)))
3974       Diag(Tok, diag::err_omp_expected_punc)
3975           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
3976                                    : getOpenMPClauseName(Kind))
3977           << (Kind == OMPC_flush);
3978   }
3979 
3980   // Parse ')' for linear clause with modifier.
3981   if (NeedRParenForLinear)
3982     LinearT.consumeClose();
3983 
3984   // Parse ':' linear-step (or ':' alignment).
3985   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
3986   if (MustHaveTail) {
3987     Data.ColonLoc = Tok.getLocation();
3988     SourceLocation ELoc = ConsumeToken();
3989     ExprResult Tail = ParseAssignmentExpression();
3990     Tail =
3991         Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
3992     if (Tail.isUsable())
3993       Data.DepModOrTailExpr = Tail.get();
3994     else
3995       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3996                 StopBeforeMatch);
3997   }
3998 
3999   // Parse ')'.
4000   Data.RLoc = Tok.getLocation();
4001   if (!T.consumeClose())
4002     Data.RLoc = T.getCloseLocation();
4003   // Exit from scope when the iterator is used in depend clause.
4004   if (HasIterator)
4005     ExitScope();
4006   return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
4007          (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
4008          IsInvalidMapperModifier;
4009 }
4010 
4011 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
4012 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
4013 /// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
4014 ///
4015 ///    private-clause:
4016 ///       'private' '(' list ')'
4017 ///    firstprivate-clause:
4018 ///       'firstprivate' '(' list ')'
4019 ///    lastprivate-clause:
4020 ///       'lastprivate' '(' list ')'
4021 ///    shared-clause:
4022 ///       'shared' '(' list ')'
4023 ///    linear-clause:
4024 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
4025 ///    aligned-clause:
4026 ///       'aligned' '(' list [ ':' alignment ] ')'
4027 ///    reduction-clause:
4028 ///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
4029 ///    task_reduction-clause:
4030 ///       'task_reduction' '(' reduction-identifier ':' list ')'
4031 ///    in_reduction-clause:
4032 ///       'in_reduction' '(' reduction-identifier ':' list ')'
4033 ///    copyprivate-clause:
4034 ///       'copyprivate' '(' list ')'
4035 ///    flush-clause:
4036 ///       'flush' '(' list ')'
4037 ///    depend-clause:
4038 ///       'depend' '(' in | out | inout : list | source ')'
4039 ///    map-clause:
4040 ///       'map' '(' [ [ always [,] ] [ close [,] ]
4041 ///          [ mapper '(' mapper-identifier ')' [,] ]
4042 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
4043 ///    to-clause:
4044 ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4045 ///    from-clause:
4046 ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4047 ///    use_device_ptr-clause:
4048 ///       'use_device_ptr' '(' list ')'
4049 ///    use_device_addr-clause:
4050 ///       'use_device_addr' '(' list ')'
4051 ///    is_device_ptr-clause:
4052 ///       'is_device_ptr' '(' list ')'
4053 ///    allocate-clause:
4054 ///       'allocate' '(' [ allocator ':' ] list ')'
4055 ///    nontemporal-clause:
4056 ///       'nontemporal' '(' list ')'
4057 ///    inclusive-clause:
4058 ///       'inclusive' '(' list ')'
4059 ///    exclusive-clause:
4060 ///       'exclusive' '(' list ')'
4061 ///
4062 /// For 'linear' clause linear-list may have the following forms:
4063 ///  list
4064 ///  modifier(list)
4065 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,OpenMPClauseKind Kind,bool ParseOnly)4066 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
4067                                             OpenMPClauseKind Kind,
4068                                             bool ParseOnly) {
4069   SourceLocation Loc = Tok.getLocation();
4070   SourceLocation LOpen = ConsumeToken();
4071   SmallVector<Expr *, 4> Vars;
4072   OpenMPVarListDataTy Data;
4073 
4074   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
4075     return nullptr;
4076 
4077   if (ParseOnly)
4078     return nullptr;
4079   OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
4080   return Actions.ActOnOpenMPVarListClause(
4081       Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc,
4082       Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
4083       Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
4084       Data.IsMapTypeImplicit, Data.ExtraModifierLoc, Data.MotionModifiers,
4085       Data.MotionModifiersLoc);
4086 }
4087