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