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/Parse/ParseDiagnostic.h"
16 #include "clang/Parse/Parser.h"
17 #include "clang/Parse/RAIIObjectsForParser.h"
18 #include "clang/Sema/Scope.h"
19 #include "llvm/ADT/PointerIntPair.h"
20 
21 using namespace clang;
22 
23 //===----------------------------------------------------------------------===//
24 // OpenMP declarative directives.
25 //===----------------------------------------------------------------------===//
26 
27 namespace {
28 enum OpenMPDirectiveKindEx {
29   OMPD_cancellation = OMPD_unknown + 1,
30   OMPD_data,
31   OMPD_declare,
32   OMPD_end,
33   OMPD_end_declare,
34   OMPD_enter,
35   OMPD_exit,
36   OMPD_point,
37   OMPD_reduction,
38   OMPD_target_enter,
39   OMPD_target_exit,
40   OMPD_update,
41   OMPD_distribute_parallel,
42   OMPD_teams_distribute_parallel,
43   OMPD_target_teams_distribute_parallel,
44   OMPD_mapper,
45 };
46 
47 class DeclDirectiveListParserHelper final {
48   SmallVector<Expr *, 4> Identifiers;
49   Parser *P;
50   OpenMPDirectiveKind Kind;
51 
52 public:
DeclDirectiveListParserHelper(Parser * P,OpenMPDirectiveKind Kind)53   DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
54       : P(P), Kind(Kind) {}
operator ()(CXXScopeSpec & SS,DeclarationNameInfo NameInfo)55   void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
56     ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
57         P->getCurScope(), SS, NameInfo, Kind);
58     if (Res.isUsable())
59       Identifiers.push_back(Res.get());
60   }
getIdentifiers() const61   llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
62 };
63 } // namespace
64 
65 // Map token string to extended OMP token kind that are
66 // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
getOpenMPDirectiveKindEx(StringRef S)67 static unsigned getOpenMPDirectiveKindEx(StringRef S) {
68   auto DKind = getOpenMPDirectiveKind(S);
69   if (DKind != OMPD_unknown)
70     return DKind;
71 
72   return llvm::StringSwitch<unsigned>(S)
73       .Case("cancellation", OMPD_cancellation)
74       .Case("data", OMPD_data)
75       .Case("declare", OMPD_declare)
76       .Case("end", OMPD_end)
77       .Case("enter", OMPD_enter)
78       .Case("exit", OMPD_exit)
79       .Case("point", OMPD_point)
80       .Case("reduction", OMPD_reduction)
81       .Case("update", OMPD_update)
82       .Case("mapper", OMPD_mapper)
83       .Default(OMPD_unknown);
84 }
85 
parseOpenMPDirectiveKind(Parser & P)86 static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
87   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
88   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
89   // TODO: add other combined directives in topological order.
90   static const unsigned F[][3] = {
91       {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
92       {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
93       {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
94       {OMPD_declare, OMPD_simd, OMPD_declare_simd},
95       {OMPD_declare, OMPD_target, OMPD_declare_target},
96       {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
97       {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
98       {OMPD_distribute_parallel_for, OMPD_simd,
99        OMPD_distribute_parallel_for_simd},
100       {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
101       {OMPD_end, OMPD_declare, OMPD_end_declare},
102       {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
103       {OMPD_target, OMPD_data, OMPD_target_data},
104       {OMPD_target, OMPD_enter, OMPD_target_enter},
105       {OMPD_target, OMPD_exit, OMPD_target_exit},
106       {OMPD_target, OMPD_update, OMPD_target_update},
107       {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
108       {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
109       {OMPD_for, OMPD_simd, OMPD_for_simd},
110       {OMPD_parallel, OMPD_for, OMPD_parallel_for},
111       {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
112       {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
113       {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
114       {OMPD_target, OMPD_parallel, OMPD_target_parallel},
115       {OMPD_target, OMPD_simd, OMPD_target_simd},
116       {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
117       {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
118       {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
119       {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
120       {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
121       {OMPD_teams_distribute_parallel, OMPD_for,
122        OMPD_teams_distribute_parallel_for},
123       {OMPD_teams_distribute_parallel_for, OMPD_simd,
124        OMPD_teams_distribute_parallel_for_simd},
125       {OMPD_target, OMPD_teams, OMPD_target_teams},
126       {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
127       {OMPD_target_teams_distribute, OMPD_parallel,
128        OMPD_target_teams_distribute_parallel},
129       {OMPD_target_teams_distribute, OMPD_simd,
130        OMPD_target_teams_distribute_simd},
131       {OMPD_target_teams_distribute_parallel, OMPD_for,
132        OMPD_target_teams_distribute_parallel_for},
133       {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
134        OMPD_target_teams_distribute_parallel_for_simd}};
135   enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
136   Token Tok = P.getCurToken();
137   unsigned DKind =
138       Tok.isAnnotation()
139           ? static_cast<unsigned>(OMPD_unknown)
140           : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
141   if (DKind == OMPD_unknown)
142     return OMPD_unknown;
143 
144   for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
145     if (DKind != F[I][0])
146       continue;
147 
148     Tok = P.getPreprocessor().LookAhead(0);
149     unsigned SDKind =
150         Tok.isAnnotation()
151             ? static_cast<unsigned>(OMPD_unknown)
152             : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
153     if (SDKind == OMPD_unknown)
154       continue;
155 
156     if (SDKind == F[I][1]) {
157       P.ConsumeToken();
158       DKind = F[I][2];
159     }
160   }
161   return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
162                               : OMPD_unknown;
163 }
164 
parseOpenMPReductionId(Parser & P)165 static DeclarationName parseOpenMPReductionId(Parser &P) {
166   Token Tok = P.getCurToken();
167   Sema &Actions = P.getActions();
168   OverloadedOperatorKind OOK = OO_None;
169   // Allow to use 'operator' keyword for C++ operators
170   bool WithOperator = false;
171   if (Tok.is(tok::kw_operator)) {
172     P.ConsumeToken();
173     Tok = P.getCurToken();
174     WithOperator = true;
175   }
176   switch (Tok.getKind()) {
177   case tok::plus: // '+'
178     OOK = OO_Plus;
179     break;
180   case tok::minus: // '-'
181     OOK = OO_Minus;
182     break;
183   case tok::star: // '*'
184     OOK = OO_Star;
185     break;
186   case tok::amp: // '&'
187     OOK = OO_Amp;
188     break;
189   case tok::pipe: // '|'
190     OOK = OO_Pipe;
191     break;
192   case tok::caret: // '^'
193     OOK = OO_Caret;
194     break;
195   case tok::ampamp: // '&&'
196     OOK = OO_AmpAmp;
197     break;
198   case tok::pipepipe: // '||'
199     OOK = OO_PipePipe;
200     break;
201   case tok::identifier: // identifier
202     if (!WithOperator)
203       break;
204     LLVM_FALLTHROUGH;
205   default:
206     P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
207     P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
208                 Parser::StopBeforeMatch);
209     return DeclarationName();
210   }
211   P.ConsumeToken();
212   auto &DeclNames = Actions.getASTContext().DeclarationNames;
213   return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
214                         : DeclNames.getCXXOperatorName(OOK);
215 }
216 
217 /// Parse 'omp declare reduction' construct.
218 ///
219 ///       declare-reduction-directive:
220 ///        annot_pragma_openmp 'declare' 'reduction'
221 ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
222 ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
223 ///        annot_pragma_openmp_end
224 /// <reduction_id> is either a base language identifier or one of the following
225 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
226 ///
227 Parser::DeclGroupPtrTy
ParseOpenMPDeclareReductionDirective(AccessSpecifier AS)228 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
229   // Parse '('.
230   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
231   if (T.expectAndConsume(diag::err_expected_lparen_after,
232                          getOpenMPDirectiveName(OMPD_declare_reduction))) {
233     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
234     return DeclGroupPtrTy();
235   }
236 
237   DeclarationName Name = parseOpenMPReductionId(*this);
238   if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
239     return DeclGroupPtrTy();
240 
241   // Consume ':'.
242   bool IsCorrect = !ExpectAndConsume(tok::colon);
243 
244   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
245     return DeclGroupPtrTy();
246 
247   IsCorrect = IsCorrect && !Name.isEmpty();
248 
249   if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
250     Diag(Tok.getLocation(), diag::err_expected_type);
251     IsCorrect = false;
252   }
253 
254   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
255     return DeclGroupPtrTy();
256 
257   SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
258   // Parse list of types until ':' token.
259   do {
260     ColonProtectionRAIIObject ColonRAII(*this);
261     SourceRange Range;
262     TypeResult TR =
263         ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
264     if (TR.isUsable()) {
265       QualType ReductionType =
266           Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
267       if (!ReductionType.isNull()) {
268         ReductionTypes.push_back(
269             std::make_pair(ReductionType, Range.getBegin()));
270       }
271     } else {
272       SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
273                 StopBeforeMatch);
274     }
275 
276     if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
277       break;
278 
279     // Consume ','.
280     if (ExpectAndConsume(tok::comma)) {
281       IsCorrect = false;
282       if (Tok.is(tok::annot_pragma_openmp_end)) {
283         Diag(Tok.getLocation(), diag::err_expected_type);
284         return DeclGroupPtrTy();
285       }
286     }
287   } while (Tok.isNot(tok::annot_pragma_openmp_end));
288 
289   if (ReductionTypes.empty()) {
290     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
291     return DeclGroupPtrTy();
292   }
293 
294   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
295     return DeclGroupPtrTy();
296 
297   // Consume ':'.
298   if (ExpectAndConsume(tok::colon))
299     IsCorrect = false;
300 
301   if (Tok.is(tok::annot_pragma_openmp_end)) {
302     Diag(Tok.getLocation(), diag::err_expected_expression);
303     return DeclGroupPtrTy();
304   }
305 
306   DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
307       getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
308 
309   // Parse <combiner> expression and then parse initializer if any for each
310   // correct type.
311   unsigned I = 0, E = ReductionTypes.size();
312   for (Decl *D : DRD.get()) {
313     TentativeParsingAction TPA(*this);
314     ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
315                                     Scope::CompoundStmtScope |
316                                     Scope::OpenMPDirectiveScope);
317     // Parse <combiner> expression.
318     Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
319     ExprResult CombinerResult =
320         Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
321                                     D->getLocation(), /*DiscardedValue*/ false);
322     Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
323 
324     if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
325         Tok.isNot(tok::annot_pragma_openmp_end)) {
326       TPA.Commit();
327       IsCorrect = false;
328       break;
329     }
330     IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
331     ExprResult InitializerResult;
332     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
333       // Parse <initializer> expression.
334       if (Tok.is(tok::identifier) &&
335           Tok.getIdentifierInfo()->isStr("initializer")) {
336         ConsumeToken();
337       } else {
338         Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
339         TPA.Commit();
340         IsCorrect = false;
341         break;
342       }
343       // Parse '('.
344       BalancedDelimiterTracker T(*this, tok::l_paren,
345                                  tok::annot_pragma_openmp_end);
346       IsCorrect =
347           !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
348           IsCorrect;
349       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
350         ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
351                                         Scope::CompoundStmtScope |
352                                         Scope::OpenMPDirectiveScope);
353         // Parse expression.
354         VarDecl *OmpPrivParm =
355             Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
356                                                                 D);
357         // Check if initializer is omp_priv <init_expr> or something else.
358         if (Tok.is(tok::identifier) &&
359             Tok.getIdentifierInfo()->isStr("omp_priv")) {
360           if (Actions.getLangOpts().CPlusPlus) {
361             InitializerResult = Actions.ActOnFinishFullExpr(
362                 ParseAssignmentExpression().get(), D->getLocation(),
363                 /*DiscardedValue*/ false);
364           } else {
365             ConsumeToken();
366             ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
367           }
368         } else {
369           InitializerResult = Actions.ActOnFinishFullExpr(
370               ParseAssignmentExpression().get(), D->getLocation(),
371               /*DiscardedValue*/ false);
372         }
373         Actions.ActOnOpenMPDeclareReductionInitializerEnd(
374             D, InitializerResult.get(), OmpPrivParm);
375         if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
376             Tok.isNot(tok::annot_pragma_openmp_end)) {
377           TPA.Commit();
378           IsCorrect = false;
379           break;
380         }
381         IsCorrect =
382             !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
383       }
384     }
385 
386     ++I;
387     // Revert parsing if not the last type, otherwise accept it, we're done with
388     // parsing.
389     if (I != E)
390       TPA.Revert();
391     else
392       TPA.Commit();
393   }
394   return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
395                                                          IsCorrect);
396 }
397 
ParseOpenMPReductionInitializerForDecl(VarDecl * OmpPrivParm)398 void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
399   // Parse declarator '=' initializer.
400   // If a '==' or '+=' is found, suggest a fixit to '='.
401   if (isTokenEqualOrEqualTypo()) {
402     ConsumeToken();
403 
404     if (Tok.is(tok::code_completion)) {
405       Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
406       Actions.FinalizeDeclaration(OmpPrivParm);
407       cutOffParsing();
408       return;
409     }
410 
411     ExprResult Init(ParseInitializer());
412 
413     if (Init.isInvalid()) {
414       SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
415       Actions.ActOnInitializerError(OmpPrivParm);
416     } else {
417       Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
418                                    /*DirectInit=*/false);
419     }
420   } else if (Tok.is(tok::l_paren)) {
421     // Parse C++ direct initializer: '(' expression-list ')'
422     BalancedDelimiterTracker T(*this, tok::l_paren);
423     T.consumeOpen();
424 
425     ExprVector Exprs;
426     CommaLocsTy CommaLocs;
427 
428     SourceLocation LParLoc = T.getOpenLocation();
429     auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
430       QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
431           getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
432           OmpPrivParm->getLocation(), Exprs, LParLoc);
433       CalledSignatureHelp = true;
434       return PreferredType;
435     };
436     if (ParseExpressionList(Exprs, CommaLocs, [&] {
437           PreferredType.enterFunctionArgument(Tok.getLocation(),
438                                               RunSignatureHelp);
439         })) {
440       if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
441         RunSignatureHelp();
442       Actions.ActOnInitializerError(OmpPrivParm);
443       SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
444     } else {
445       // Match the ')'.
446       SourceLocation RLoc = Tok.getLocation();
447       if (!T.consumeClose())
448         RLoc = T.getCloseLocation();
449 
450       assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
451              "Unexpected number of commas!");
452 
453       ExprResult Initializer =
454           Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
455       Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
456                                    /*DirectInit=*/true);
457     }
458   } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
459     // Parse C++0x braced-init-list.
460     Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
461 
462     ExprResult Init(ParseBraceInitializer());
463 
464     if (Init.isInvalid()) {
465       Actions.ActOnInitializerError(OmpPrivParm);
466     } else {
467       Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
468                                    /*DirectInit=*/true);
469     }
470   } else {
471     Actions.ActOnUninitializedDecl(OmpPrivParm);
472   }
473 }
474 
475 /// Parses 'omp declare mapper' directive.
476 ///
477 ///       declare-mapper-directive:
478 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
479 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
480 ///         annot_pragma_openmp_end
481 /// <mapper-identifier> and <var> are base language identifiers.
482 ///
483 Parser::DeclGroupPtrTy
ParseOpenMPDeclareMapperDirective(AccessSpecifier AS)484 Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
485   bool IsCorrect = true;
486   // Parse '('
487   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
488   if (T.expectAndConsume(diag::err_expected_lparen_after,
489                          getOpenMPDirectiveName(OMPD_declare_mapper))) {
490     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
491     return DeclGroupPtrTy();
492   }
493 
494   // Parse <mapper-identifier>
495   auto &DeclNames = Actions.getASTContext().DeclarationNames;
496   DeclarationName MapperId;
497   if (PP.LookAhead(0).is(tok::colon)) {
498     if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
499       Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
500       IsCorrect = false;
501     } else {
502       MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
503     }
504     ConsumeToken();
505     // Consume ':'.
506     ExpectAndConsume(tok::colon);
507   } else {
508     // If no mapper identifier is provided, its name is "default" by default
509     MapperId =
510         DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
511   }
512 
513   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
514     return DeclGroupPtrTy();
515 
516   // Parse <type> <var>
517   DeclarationName VName;
518   QualType MapperType;
519   SourceRange Range;
520   TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
521   if (ParsedType.isUsable())
522     MapperType =
523         Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
524   if (MapperType.isNull())
525     IsCorrect = false;
526   if (!IsCorrect) {
527     SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
528     return DeclGroupPtrTy();
529   }
530 
531   // Consume ')'.
532   IsCorrect &= !T.consumeClose();
533   if (!IsCorrect) {
534     SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
535     return DeclGroupPtrTy();
536   }
537 
538   // Enter scope.
539   OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
540       getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
541       Range.getBegin(), VName, AS);
542   DeclarationNameInfo DirName;
543   SourceLocation Loc = Tok.getLocation();
544   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
545                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
546   ParseScope OMPDirectiveScope(this, ScopeFlags);
547   Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
548 
549   // Add the mapper variable declaration.
550   Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
551       DMD, getCurScope(), MapperType, Range.getBegin(), VName);
552 
553   // Parse map clauses.
554   SmallVector<OMPClause *, 6> Clauses;
555   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
556     OpenMPClauseKind CKind = Tok.isAnnotation()
557                                  ? OMPC_unknown
558                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
559     Actions.StartOpenMPClause(CKind);
560     OMPClause *Clause =
561         ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
562     if (Clause)
563       Clauses.push_back(Clause);
564     else
565       IsCorrect = false;
566     // Skip ',' if any.
567     if (Tok.is(tok::comma))
568       ConsumeToken();
569     Actions.EndOpenMPClause();
570   }
571   if (Clauses.empty()) {
572     Diag(Tok, diag::err_omp_expected_clause)
573         << getOpenMPDirectiveName(OMPD_declare_mapper);
574     IsCorrect = false;
575   }
576 
577   // Exit scope.
578   Actions.EndOpenMPDSABlock(nullptr);
579   OMPDirectiveScope.Exit();
580 
581   DeclGroupPtrTy DGP =
582       Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
583   if (!IsCorrect)
584     return DeclGroupPtrTy();
585   return DGP;
586 }
587 
parseOpenMPDeclareMapperVarDecl(SourceRange & Range,DeclarationName & Name,AccessSpecifier AS)588 TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
589                                                    DeclarationName &Name,
590                                                    AccessSpecifier AS) {
591   // Parse the common declaration-specifiers piece.
592   Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
593   DeclSpec DS(AttrFactory);
594   ParseSpecifierQualifierList(DS, AS, DSC);
595 
596   // Parse the declarator.
597   DeclaratorContext Context = DeclaratorContext::PrototypeContext;
598   Declarator DeclaratorInfo(DS, Context);
599   ParseDeclarator(DeclaratorInfo);
600   Range = DeclaratorInfo.getSourceRange();
601   if (DeclaratorInfo.getIdentifier() == nullptr) {
602     Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
603     return true;
604   }
605   Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
606 
607   return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
608 }
609 
610 namespace {
611 /// RAII that recreates function context for correct parsing of clauses of
612 /// 'declare simd' construct.
613 /// OpenMP, 2.8.2 declare simd Construct
614 /// The expressions appearing in the clauses of this directive are evaluated in
615 /// the scope of the arguments of the function declaration or definition.
616 class FNContextRAII final {
617   Parser &P;
618   Sema::CXXThisScopeRAII *ThisScope;
619   Parser::ParseScope *TempScope;
620   Parser::ParseScope *FnScope;
621   bool HasTemplateScope = false;
622   bool HasFunScope = false;
623   FNContextRAII() = delete;
624   FNContextRAII(const FNContextRAII &) = delete;
625   FNContextRAII &operator=(const FNContextRAII &) = delete;
626 
627 public:
FNContextRAII(Parser & P,Parser::DeclGroupPtrTy Ptr)628   FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
629     Decl *D = *Ptr.get().begin();
630     NamedDecl *ND = dyn_cast<NamedDecl>(D);
631     RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
632     Sema &Actions = P.getActions();
633 
634     // Allow 'this' within late-parsed attributes.
635     ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
636                                            ND && ND->isCXXInstanceMember());
637 
638     // If the Decl is templatized, add template parameters to scope.
639     HasTemplateScope = D->isTemplateDecl();
640     TempScope =
641         new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
642     if (HasTemplateScope)
643       Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
644 
645     // If the Decl is on a function, add function parameters to the scope.
646     HasFunScope = D->isFunctionOrFunctionTemplate();
647     FnScope = new Parser::ParseScope(
648         &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
649         HasFunScope);
650     if (HasFunScope)
651       Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
652   }
~FNContextRAII()653   ~FNContextRAII() {
654     if (HasFunScope) {
655       P.getActions().ActOnExitFunctionContext();
656       FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
657     }
658     if (HasTemplateScope)
659       TempScope->Exit();
660     delete FnScope;
661     delete TempScope;
662     delete ThisScope;
663   }
664 };
665 } // namespace
666 
667 /// Parses clauses for 'declare simd' directive.
668 ///    clause:
669 ///      'inbranch' | 'notinbranch'
670 ///      'simdlen' '(' <expr> ')'
671 ///      { 'uniform' '(' <argument_list> ')' }
672 ///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
673 ///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
parseDeclareSimdClauses(Parser & P,OMPDeclareSimdDeclAttr::BranchStateTy & BS,ExprResult & SimdLen,SmallVectorImpl<Expr * > & Uniforms,SmallVectorImpl<Expr * > & Aligneds,SmallVectorImpl<Expr * > & Alignments,SmallVectorImpl<Expr * > & Linears,SmallVectorImpl<unsigned> & LinModifiers,SmallVectorImpl<Expr * > & Steps)674 static bool parseDeclareSimdClauses(
675     Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
676     SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
677     SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
678     SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
679   SourceRange BSRange;
680   const Token &Tok = P.getCurToken();
681   bool IsError = false;
682   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
683     if (Tok.isNot(tok::identifier))
684       break;
685     OMPDeclareSimdDeclAttr::BranchStateTy Out;
686     IdentifierInfo *II = Tok.getIdentifierInfo();
687     StringRef ClauseName = II->getName();
688     // Parse 'inranch|notinbranch' clauses.
689     if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
690       if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
691         P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
692             << ClauseName
693             << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
694         IsError = true;
695       }
696       BS = Out;
697       BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
698       P.ConsumeToken();
699     } else if (ClauseName.equals("simdlen")) {
700       if (SimdLen.isUsable()) {
701         P.Diag(Tok, diag::err_omp_more_one_clause)
702             << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
703         IsError = true;
704       }
705       P.ConsumeToken();
706       SourceLocation RLoc;
707       SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
708       if (SimdLen.isInvalid())
709         IsError = true;
710     } else {
711       OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
712       if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
713           CKind == OMPC_linear) {
714         Parser::OpenMPVarListDataTy Data;
715         SmallVectorImpl<Expr *> *Vars = &Uniforms;
716         if (CKind == OMPC_aligned)
717           Vars = &Aligneds;
718         else if (CKind == OMPC_linear)
719           Vars = &Linears;
720 
721         P.ConsumeToken();
722         if (P.ParseOpenMPVarList(OMPD_declare_simd,
723                                  getOpenMPClauseKind(ClauseName), *Vars, Data))
724           IsError = true;
725         if (CKind == OMPC_aligned) {
726           Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
727         } else if (CKind == OMPC_linear) {
728           if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
729                                                        Data.DepLinMapLoc))
730             Data.LinKind = OMPC_LINEAR_val;
731           LinModifiers.append(Linears.size() - LinModifiers.size(),
732                               Data.LinKind);
733           Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
734         }
735       } else
736         // TODO: add parsing of other clauses.
737         break;
738     }
739     // Skip ',' if any.
740     if (Tok.is(tok::comma))
741       P.ConsumeToken();
742   }
743   return IsError;
744 }
745 
746 /// Parse clauses for '#pragma omp declare simd'.
747 Parser::DeclGroupPtrTy
ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,CachedTokens & Toks,SourceLocation Loc)748 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
749                                    CachedTokens &Toks, SourceLocation Loc) {
750   PP.EnterToken(Tok, /*IsReinject*/ true);
751   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
752                       /*IsReinject*/ true);
753   // Consume the previously pushed token.
754   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
755 
756   FNContextRAII FnContext(*this, Ptr);
757   OMPDeclareSimdDeclAttr::BranchStateTy BS =
758       OMPDeclareSimdDeclAttr::BS_Undefined;
759   ExprResult Simdlen;
760   SmallVector<Expr *, 4> Uniforms;
761   SmallVector<Expr *, 4> Aligneds;
762   SmallVector<Expr *, 4> Alignments;
763   SmallVector<Expr *, 4> Linears;
764   SmallVector<unsigned, 4> LinModifiers;
765   SmallVector<Expr *, 4> Steps;
766   bool IsError =
767       parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
768                               Alignments, Linears, LinModifiers, Steps);
769   // Need to check for extra tokens.
770   if (Tok.isNot(tok::annot_pragma_openmp_end)) {
771     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
772         << getOpenMPDirectiveName(OMPD_declare_simd);
773     while (Tok.isNot(tok::annot_pragma_openmp_end))
774       ConsumeAnyToken();
775   }
776   // Skip the last annot_pragma_openmp_end.
777   SourceLocation EndLoc = ConsumeAnnotationToken();
778   if (IsError)
779     return Ptr;
780   return Actions.ActOnOpenMPDeclareSimdDirective(
781       Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
782       LinModifiers, Steps, SourceRange(Loc, EndLoc));
783 }
784 
ParseOMPDeclareTargetClauses()785 Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
786   // OpenMP 4.5 syntax with list of entities.
787   Sema::NamedDeclSetType SameDirectiveDecls;
788   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
789     OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
790     if (Tok.is(tok::identifier)) {
791       IdentifierInfo *II = Tok.getIdentifierInfo();
792       StringRef ClauseName = II->getName();
793       // Parse 'to|link' clauses.
794       if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT)) {
795         Diag(Tok, diag::err_omp_declare_target_unexpected_clause) << ClauseName;
796         break;
797       }
798       ConsumeToken();
799     }
800     auto &&Callback = [this, MT, &SameDirectiveDecls](
801         CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
802       Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
803                                            SameDirectiveDecls);
804     };
805     if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
806                                  /*AllowScopeSpecifier=*/true))
807       break;
808 
809     // Consume optional ','.
810     if (Tok.is(tok::comma))
811       ConsumeToken();
812   }
813   SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
814   ConsumeAnyToken();
815   SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
816                                SameDirectiveDecls.end());
817   if (Decls.empty())
818     return DeclGroupPtrTy();
819   return Actions.BuildDeclaratorGroup(Decls);
820 }
821 
ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,SourceLocation DTLoc)822 void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
823                                                SourceLocation DTLoc) {
824   if (DKind != OMPD_end_declare_target) {
825     Diag(Tok, diag::err_expected_end_declare_target);
826     Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
827     return;
828   }
829   ConsumeAnyToken();
830   if (Tok.isNot(tok::annot_pragma_openmp_end)) {
831     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
832         << getOpenMPDirectiveName(OMPD_end_declare_target);
833     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
834   }
835   // Skip the last annot_pragma_openmp_end.
836   ConsumeAnyToken();
837 }
838 
839 /// Parsing of declarative OpenMP directives.
840 ///
841 ///       threadprivate-directive:
842 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
843 ///         annot_pragma_openmp_end
844 ///
845 ///       allocate-directive:
846 ///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
847 ///         annot_pragma_openmp_end
848 ///
849 ///       declare-reduction-directive:
850 ///        annot_pragma_openmp 'declare' 'reduction' [...]
851 ///        annot_pragma_openmp_end
852 ///
853 ///       declare-mapper-directive:
854 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
855 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
856 ///         annot_pragma_openmp_end
857 ///
858 ///       declare-simd-directive:
859 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
860 ///         annot_pragma_openmp_end
861 ///         <function declaration/definition>
862 ///
863 ///       requires directive:
864 ///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
865 ///         annot_pragma_openmp_end
866 ///
ParseOpenMPDeclarativeDirectiveWithExtDecl(AccessSpecifier & AS,ParsedAttributesWithRange & Attrs,DeclSpec::TST TagType,Decl * Tag)867 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
868     AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
869     DeclSpec::TST TagType, Decl *Tag) {
870   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
871   ParenBraceBracketBalancer BalancerRAIIObj(*this);
872 
873   SourceLocation Loc = ConsumeAnnotationToken();
874   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
875 
876   switch (DKind) {
877   case OMPD_threadprivate: {
878     ConsumeToken();
879     DeclDirectiveListParserHelper Helper(this, DKind);
880     if (!ParseOpenMPSimpleVarList(DKind, Helper,
881                                   /*AllowScopeSpecifier=*/true)) {
882       // The last seen token is annot_pragma_openmp_end - need to check for
883       // extra tokens.
884       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
885         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
886             << getOpenMPDirectiveName(DKind);
887         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
888       }
889       // Skip the last annot_pragma_openmp_end.
890       ConsumeAnnotationToken();
891       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
892                                                        Helper.getIdentifiers());
893     }
894     break;
895   }
896   case OMPD_allocate: {
897     ConsumeToken();
898     DeclDirectiveListParserHelper Helper(this, DKind);
899     if (!ParseOpenMPSimpleVarList(DKind, Helper,
900                                   /*AllowScopeSpecifier=*/true)) {
901       SmallVector<OMPClause *, 1> Clauses;
902       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
903         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
904                     OMPC_unknown + 1>
905             FirstClauses(OMPC_unknown + 1);
906         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
907           OpenMPClauseKind CKind =
908               Tok.isAnnotation() ? OMPC_unknown
909                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
910           Actions.StartOpenMPClause(CKind);
911           OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
912                                                 !FirstClauses[CKind].getInt());
913           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
914                     StopBeforeMatch);
915           FirstClauses[CKind].setInt(true);
916           if (Clause != nullptr)
917             Clauses.push_back(Clause);
918           if (Tok.is(tok::annot_pragma_openmp_end)) {
919             Actions.EndOpenMPClause();
920             break;
921           }
922           // Skip ',' if any.
923           if (Tok.is(tok::comma))
924             ConsumeToken();
925           Actions.EndOpenMPClause();
926         }
927         // The last seen token is annot_pragma_openmp_end - need to check for
928         // extra tokens.
929         if (Tok.isNot(tok::annot_pragma_openmp_end)) {
930           Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
931               << getOpenMPDirectiveName(DKind);
932           SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
933         }
934       }
935       // Skip the last annot_pragma_openmp_end.
936       ConsumeAnnotationToken();
937       return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
938                                                   Clauses);
939     }
940     break;
941   }
942   case OMPD_requires: {
943     SourceLocation StartLoc = ConsumeToken();
944     SmallVector<OMPClause *, 5> Clauses;
945     SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
946     FirstClauses(OMPC_unknown + 1);
947     if (Tok.is(tok::annot_pragma_openmp_end)) {
948       Diag(Tok, diag::err_omp_expected_clause)
949           << getOpenMPDirectiveName(OMPD_requires);
950       break;
951     }
952     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
953       OpenMPClauseKind CKind = Tok.isAnnotation()
954                                    ? OMPC_unknown
955                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
956       Actions.StartOpenMPClause(CKind);
957       OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
958                                             !FirstClauses[CKind].getInt());
959       SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
960                 StopBeforeMatch);
961       FirstClauses[CKind].setInt(true);
962       if (Clause != nullptr)
963         Clauses.push_back(Clause);
964       if (Tok.is(tok::annot_pragma_openmp_end)) {
965         Actions.EndOpenMPClause();
966         break;
967       }
968       // Skip ',' if any.
969       if (Tok.is(tok::comma))
970         ConsumeToken();
971       Actions.EndOpenMPClause();
972     }
973     // Consume final annot_pragma_openmp_end
974     if (Clauses.size() == 0) {
975       Diag(Tok, diag::err_omp_expected_clause)
976           << getOpenMPDirectiveName(OMPD_requires);
977       ConsumeAnnotationToken();
978       return nullptr;
979     }
980     ConsumeAnnotationToken();
981     return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
982   }
983   case OMPD_declare_reduction:
984     ConsumeToken();
985     if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
986       // The last seen token is annot_pragma_openmp_end - need to check for
987       // extra tokens.
988       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
989         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
990             << getOpenMPDirectiveName(OMPD_declare_reduction);
991         while (Tok.isNot(tok::annot_pragma_openmp_end))
992           ConsumeAnyToken();
993       }
994       // Skip the last annot_pragma_openmp_end.
995       ConsumeAnnotationToken();
996       return Res;
997     }
998     break;
999   case OMPD_declare_mapper: {
1000     ConsumeToken();
1001     if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1002       // Skip the last annot_pragma_openmp_end.
1003       ConsumeAnnotationToken();
1004       return Res;
1005     }
1006     break;
1007   }
1008   case OMPD_declare_simd: {
1009     // The syntax is:
1010     // { #pragma omp declare simd }
1011     // <function-declaration-or-definition>
1012     //
1013     ConsumeToken();
1014     CachedTokens Toks;
1015     while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1016       Toks.push_back(Tok);
1017       ConsumeAnyToken();
1018     }
1019     Toks.push_back(Tok);
1020     ConsumeAnyToken();
1021 
1022     DeclGroupPtrTy Ptr;
1023     if (Tok.is(tok::annot_pragma_openmp)) {
1024       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
1025     } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1026       // Here we expect to see some function declaration.
1027       if (AS == AS_none) {
1028         assert(TagType == DeclSpec::TST_unspecified);
1029         MaybeParseCXX11Attributes(Attrs);
1030         ParsingDeclSpec PDS(*this);
1031         Ptr = ParseExternalDeclaration(Attrs, &PDS);
1032       } else {
1033         Ptr =
1034             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1035       }
1036     }
1037     if (!Ptr) {
1038       Diag(Loc, diag::err_omp_decl_in_declare_simd);
1039       return DeclGroupPtrTy();
1040     }
1041     return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1042   }
1043   case OMPD_declare_target: {
1044     SourceLocation DTLoc = ConsumeAnyToken();
1045     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1046       return ParseOMPDeclareTargetClauses();
1047     }
1048 
1049     // Skip the last annot_pragma_openmp_end.
1050     ConsumeAnyToken();
1051 
1052     if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1053       return DeclGroupPtrTy();
1054 
1055     llvm::SmallVector<Decl *, 4>  Decls;
1056     DKind = parseOpenMPDirectiveKind(*this);
1057     while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
1058            Tok.isNot(tok::r_brace)) {
1059       DeclGroupPtrTy Ptr;
1060       // Here we expect to see some function declaration.
1061       if (AS == AS_none) {
1062         assert(TagType == DeclSpec::TST_unspecified);
1063         MaybeParseCXX11Attributes(Attrs);
1064         ParsingDeclSpec PDS(*this);
1065         Ptr = ParseExternalDeclaration(Attrs, &PDS);
1066       } else {
1067         Ptr =
1068             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1069       }
1070       if (Ptr) {
1071         DeclGroupRef Ref = Ptr.get();
1072         Decls.append(Ref.begin(), Ref.end());
1073       }
1074       if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
1075         TentativeParsingAction TPA(*this);
1076         ConsumeAnnotationToken();
1077         DKind = parseOpenMPDirectiveKind(*this);
1078         if (DKind != OMPD_end_declare_target)
1079           TPA.Revert();
1080         else
1081           TPA.Commit();
1082       }
1083     }
1084 
1085     ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
1086     Actions.ActOnFinishOpenMPDeclareTargetDirective();
1087     return Actions.BuildDeclaratorGroup(Decls);
1088   }
1089   case OMPD_unknown:
1090     Diag(Tok, diag::err_omp_unknown_directive);
1091     break;
1092   case OMPD_parallel:
1093   case OMPD_simd:
1094   case OMPD_task:
1095   case OMPD_taskyield:
1096   case OMPD_barrier:
1097   case OMPD_taskwait:
1098   case OMPD_taskgroup:
1099   case OMPD_flush:
1100   case OMPD_for:
1101   case OMPD_for_simd:
1102   case OMPD_sections:
1103   case OMPD_section:
1104   case OMPD_single:
1105   case OMPD_master:
1106   case OMPD_ordered:
1107   case OMPD_critical:
1108   case OMPD_parallel_for:
1109   case OMPD_parallel_for_simd:
1110   case OMPD_parallel_sections:
1111   case OMPD_atomic:
1112   case OMPD_target:
1113   case OMPD_teams:
1114   case OMPD_cancellation_point:
1115   case OMPD_cancel:
1116   case OMPD_target_data:
1117   case OMPD_target_enter_data:
1118   case OMPD_target_exit_data:
1119   case OMPD_target_parallel:
1120   case OMPD_target_parallel_for:
1121   case OMPD_taskloop:
1122   case OMPD_taskloop_simd:
1123   case OMPD_distribute:
1124   case OMPD_end_declare_target:
1125   case OMPD_target_update:
1126   case OMPD_distribute_parallel_for:
1127   case OMPD_distribute_parallel_for_simd:
1128   case OMPD_distribute_simd:
1129   case OMPD_target_parallel_for_simd:
1130   case OMPD_target_simd:
1131   case OMPD_teams_distribute:
1132   case OMPD_teams_distribute_simd:
1133   case OMPD_teams_distribute_parallel_for_simd:
1134   case OMPD_teams_distribute_parallel_for:
1135   case OMPD_target_teams:
1136   case OMPD_target_teams_distribute:
1137   case OMPD_target_teams_distribute_parallel_for:
1138   case OMPD_target_teams_distribute_parallel_for_simd:
1139   case OMPD_target_teams_distribute_simd:
1140     Diag(Tok, diag::err_omp_unexpected_directive)
1141         << 1 << getOpenMPDirectiveName(DKind);
1142     break;
1143   }
1144   while (Tok.isNot(tok::annot_pragma_openmp_end))
1145     ConsumeAnyToken();
1146   ConsumeAnyToken();
1147   return nullptr;
1148 }
1149 
1150 /// Parsing of declarative or executable OpenMP directives.
1151 ///
1152 ///       threadprivate-directive:
1153 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
1154 ///         annot_pragma_openmp_end
1155 ///
1156 ///       allocate-directive:
1157 ///         annot_pragma_openmp 'allocate' simple-variable-list
1158 ///         annot_pragma_openmp_end
1159 ///
1160 ///       declare-reduction-directive:
1161 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
1162 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
1163 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
1164 ///         annot_pragma_openmp_end
1165 ///
1166 ///       declare-mapper-directive:
1167 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1168 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1169 ///         annot_pragma_openmp_end
1170 ///
1171 ///       executable-directive:
1172 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
1173 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
1174 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
1175 ///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
1176 ///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
1177 ///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
1178 ///         'distribute' | 'target enter data' | 'target exit data' |
1179 ///         'target parallel' | 'target parallel for' |
1180 ///         'target update' | 'distribute parallel for' |
1181 ///         'distribute paralle for simd' | 'distribute simd' |
1182 ///         'target parallel for simd' | 'target simd' |
1183 ///         'teams distribute' | 'teams distribute simd' |
1184 ///         'teams distribute parallel for simd' |
1185 ///         'teams distribute parallel for' | 'target teams' |
1186 ///         'target teams distribute' |
1187 ///         'target teams distribute parallel for' |
1188 ///         'target teams distribute parallel for simd' |
1189 ///         'target teams distribute simd' {clause}
1190 ///         annot_pragma_openmp_end
1191 ///
1192 StmtResult
ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx)1193 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
1194   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1195   ParenBraceBracketBalancer BalancerRAIIObj(*this);
1196   SmallVector<OMPClause *, 5> Clauses;
1197   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
1198   FirstClauses(OMPC_unknown + 1);
1199   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
1200                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
1201   SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
1202   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
1203   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
1204   // Name of critical directive.
1205   DeclarationNameInfo DirName;
1206   StmtResult Directive = StmtError();
1207   bool HasAssociatedStatement = true;
1208   bool FlushHasClause = false;
1209 
1210   switch (DKind) {
1211   case OMPD_threadprivate: {
1212     // FIXME: Should this be permitted in C++?
1213     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1214         ParsedStmtContext()) {
1215       Diag(Tok, diag::err_omp_immediate_directive)
1216           << getOpenMPDirectiveName(DKind) << 0;
1217     }
1218     ConsumeToken();
1219     DeclDirectiveListParserHelper Helper(this, DKind);
1220     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1221                                   /*AllowScopeSpecifier=*/false)) {
1222       // The last seen token is annot_pragma_openmp_end - need to check for
1223       // extra tokens.
1224       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1225         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1226             << getOpenMPDirectiveName(DKind);
1227         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1228       }
1229       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1230           Loc, Helper.getIdentifiers());
1231       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1232     }
1233     SkipUntil(tok::annot_pragma_openmp_end);
1234     break;
1235   }
1236   case OMPD_allocate: {
1237     // FIXME: Should this be permitted in C++?
1238     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1239         ParsedStmtContext()) {
1240       Diag(Tok, diag::err_omp_immediate_directive)
1241           << getOpenMPDirectiveName(DKind) << 0;
1242     }
1243     ConsumeToken();
1244     DeclDirectiveListParserHelper Helper(this, DKind);
1245     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1246                                   /*AllowScopeSpecifier=*/false)) {
1247       SmallVector<OMPClause *, 1> Clauses;
1248       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1249         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1250                     OMPC_unknown + 1>
1251             FirstClauses(OMPC_unknown + 1);
1252         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1253           OpenMPClauseKind CKind =
1254               Tok.isAnnotation() ? OMPC_unknown
1255                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
1256           Actions.StartOpenMPClause(CKind);
1257           OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
1258                                                 !FirstClauses[CKind].getInt());
1259           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1260                     StopBeforeMatch);
1261           FirstClauses[CKind].setInt(true);
1262           if (Clause != nullptr)
1263             Clauses.push_back(Clause);
1264           if (Tok.is(tok::annot_pragma_openmp_end)) {
1265             Actions.EndOpenMPClause();
1266             break;
1267           }
1268           // Skip ',' if any.
1269           if (Tok.is(tok::comma))
1270             ConsumeToken();
1271           Actions.EndOpenMPClause();
1272         }
1273         // The last seen token is annot_pragma_openmp_end - need to check for
1274         // extra tokens.
1275         if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1276           Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1277               << getOpenMPDirectiveName(DKind);
1278           SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1279         }
1280       }
1281       DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
1282           Loc, Helper.getIdentifiers(), Clauses);
1283       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1284     }
1285     SkipUntil(tok::annot_pragma_openmp_end);
1286     break;
1287   }
1288   case OMPD_declare_reduction:
1289     ConsumeToken();
1290     if (DeclGroupPtrTy Res =
1291             ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
1292       // The last seen token is annot_pragma_openmp_end - need to check for
1293       // extra tokens.
1294       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1295         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1296             << getOpenMPDirectiveName(OMPD_declare_reduction);
1297         while (Tok.isNot(tok::annot_pragma_openmp_end))
1298           ConsumeAnyToken();
1299       }
1300       ConsumeAnyToken();
1301       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1302     } else {
1303       SkipUntil(tok::annot_pragma_openmp_end);
1304     }
1305     break;
1306   case OMPD_declare_mapper: {
1307     ConsumeToken();
1308     if (DeclGroupPtrTy Res =
1309             ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
1310       // Skip the last annot_pragma_openmp_end.
1311       ConsumeAnnotationToken();
1312       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1313     } else {
1314       SkipUntil(tok::annot_pragma_openmp_end);
1315     }
1316     break;
1317   }
1318   case OMPD_flush:
1319     if (PP.LookAhead(0).is(tok::l_paren)) {
1320       FlushHasClause = true;
1321       // Push copy of the current token back to stream to properly parse
1322       // pseudo-clause OMPFlushClause.
1323       PP.EnterToken(Tok, /*IsReinject*/ true);
1324     }
1325     LLVM_FALLTHROUGH;
1326   case OMPD_taskyield:
1327   case OMPD_barrier:
1328   case OMPD_taskwait:
1329   case OMPD_cancellation_point:
1330   case OMPD_cancel:
1331   case OMPD_target_enter_data:
1332   case OMPD_target_exit_data:
1333   case OMPD_target_update:
1334     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1335         ParsedStmtContext()) {
1336       Diag(Tok, diag::err_omp_immediate_directive)
1337           << getOpenMPDirectiveName(DKind) << 0;
1338     }
1339     HasAssociatedStatement = false;
1340     // Fall through for further analysis.
1341     LLVM_FALLTHROUGH;
1342   case OMPD_parallel:
1343   case OMPD_simd:
1344   case OMPD_for:
1345   case OMPD_for_simd:
1346   case OMPD_sections:
1347   case OMPD_single:
1348   case OMPD_section:
1349   case OMPD_master:
1350   case OMPD_critical:
1351   case OMPD_parallel_for:
1352   case OMPD_parallel_for_simd:
1353   case OMPD_parallel_sections:
1354   case OMPD_task:
1355   case OMPD_ordered:
1356   case OMPD_atomic:
1357   case OMPD_target:
1358   case OMPD_teams:
1359   case OMPD_taskgroup:
1360   case OMPD_target_data:
1361   case OMPD_target_parallel:
1362   case OMPD_target_parallel_for:
1363   case OMPD_taskloop:
1364   case OMPD_taskloop_simd:
1365   case OMPD_distribute:
1366   case OMPD_distribute_parallel_for:
1367   case OMPD_distribute_parallel_for_simd:
1368   case OMPD_distribute_simd:
1369   case OMPD_target_parallel_for_simd:
1370   case OMPD_target_simd:
1371   case OMPD_teams_distribute:
1372   case OMPD_teams_distribute_simd:
1373   case OMPD_teams_distribute_parallel_for_simd:
1374   case OMPD_teams_distribute_parallel_for:
1375   case OMPD_target_teams:
1376   case OMPD_target_teams_distribute:
1377   case OMPD_target_teams_distribute_parallel_for:
1378   case OMPD_target_teams_distribute_parallel_for_simd:
1379   case OMPD_target_teams_distribute_simd: {
1380     ConsumeToken();
1381     // Parse directive name of the 'critical' directive if any.
1382     if (DKind == OMPD_critical) {
1383       BalancedDelimiterTracker T(*this, tok::l_paren,
1384                                  tok::annot_pragma_openmp_end);
1385       if (!T.consumeOpen()) {
1386         if (Tok.isAnyIdentifier()) {
1387           DirName =
1388               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
1389           ConsumeAnyToken();
1390         } else {
1391           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
1392         }
1393         T.consumeClose();
1394       }
1395     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
1396       CancelRegion = parseOpenMPDirectiveKind(*this);
1397       if (Tok.isNot(tok::annot_pragma_openmp_end))
1398         ConsumeToken();
1399     }
1400 
1401     if (isOpenMPLoopDirective(DKind))
1402       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
1403     if (isOpenMPSimdDirective(DKind))
1404       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
1405     ParseScope OMPDirectiveScope(this, ScopeFlags);
1406     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
1407 
1408     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1409       OpenMPClauseKind CKind =
1410           Tok.isAnnotation()
1411               ? OMPC_unknown
1412               : FlushHasClause ? OMPC_flush
1413                                : getOpenMPClauseKind(PP.getSpelling(Tok));
1414       Actions.StartOpenMPClause(CKind);
1415       FlushHasClause = false;
1416       OMPClause *Clause =
1417           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1418       FirstClauses[CKind].setInt(true);
1419       if (Clause) {
1420         FirstClauses[CKind].setPointer(Clause);
1421         Clauses.push_back(Clause);
1422       }
1423 
1424       // Skip ',' if any.
1425       if (Tok.is(tok::comma))
1426         ConsumeToken();
1427       Actions.EndOpenMPClause();
1428     }
1429     // End location of the directive.
1430     EndLoc = Tok.getLocation();
1431     // Consume final annot_pragma_openmp_end.
1432     ConsumeAnnotationToken();
1433 
1434     // OpenMP [2.13.8, ordered Construct, Syntax]
1435     // If the depend clause is specified, the ordered construct is a stand-alone
1436     // directive.
1437     if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
1438       if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1439           ParsedStmtContext()) {
1440         Diag(Loc, diag::err_omp_immediate_directive)
1441             << getOpenMPDirectiveName(DKind) << 1
1442             << getOpenMPClauseName(OMPC_depend);
1443       }
1444       HasAssociatedStatement = false;
1445     }
1446 
1447     StmtResult AssociatedStmt;
1448     if (HasAssociatedStatement) {
1449       // The body is a block scope like in Lambdas and Blocks.
1450       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1451       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
1452       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
1453       // should have at least one compound statement scope within it.
1454       AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
1455       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1456     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
1457                DKind == OMPD_target_exit_data) {
1458       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1459       AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
1460                         Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
1461                                                   /*isStmtExpr=*/false));
1462       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1463     }
1464     Directive = Actions.ActOnOpenMPExecutableDirective(
1465         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1466         EndLoc);
1467 
1468     // Exit scope.
1469     Actions.EndOpenMPDSABlock(Directive.get());
1470     OMPDirectiveScope.Exit();
1471     break;
1472   }
1473   case OMPD_declare_simd:
1474   case OMPD_declare_target:
1475   case OMPD_end_declare_target:
1476   case OMPD_requires:
1477     Diag(Tok, diag::err_omp_unexpected_directive)
1478         << 1 << getOpenMPDirectiveName(DKind);
1479     SkipUntil(tok::annot_pragma_openmp_end);
1480     break;
1481   case OMPD_unknown:
1482     Diag(Tok, diag::err_omp_unknown_directive);
1483     SkipUntil(tok::annot_pragma_openmp_end);
1484     break;
1485   }
1486   return Directive;
1487 }
1488 
1489 // Parses simple list:
1490 //   simple-variable-list:
1491 //         '(' id-expression {, id-expression} ')'
1492 //
ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,const llvm::function_ref<void (CXXScopeSpec &,DeclarationNameInfo)> & Callback,bool AllowScopeSpecifier)1493 bool Parser::ParseOpenMPSimpleVarList(
1494     OpenMPDirectiveKind Kind,
1495     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
1496         Callback,
1497     bool AllowScopeSpecifier) {
1498   // Parse '('.
1499   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1500   if (T.expectAndConsume(diag::err_expected_lparen_after,
1501                          getOpenMPDirectiveName(Kind)))
1502     return true;
1503   bool IsCorrect = true;
1504   bool NoIdentIsFound = true;
1505 
1506   // Read tokens while ')' or annot_pragma_openmp_end is not found.
1507   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
1508     CXXScopeSpec SS;
1509     UnqualifiedId Name;
1510     // Read var name.
1511     Token PrevTok = Tok;
1512     NoIdentIsFound = false;
1513 
1514     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
1515         ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
1516       IsCorrect = false;
1517       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1518                 StopBeforeMatch);
1519     } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
1520                                   nullptr, Name)) {
1521       IsCorrect = false;
1522       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1523                 StopBeforeMatch);
1524     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
1525                Tok.isNot(tok::annot_pragma_openmp_end)) {
1526       IsCorrect = false;
1527       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1528                 StopBeforeMatch);
1529       Diag(PrevTok.getLocation(), diag::err_expected)
1530           << tok::identifier
1531           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
1532     } else {
1533       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1534     }
1535     // Consume ','.
1536     if (Tok.is(tok::comma)) {
1537       ConsumeToken();
1538     }
1539   }
1540 
1541   if (NoIdentIsFound) {
1542     Diag(Tok, diag::err_expected) << tok::identifier;
1543     IsCorrect = false;
1544   }
1545 
1546   // Parse ')'.
1547   IsCorrect = !T.consumeClose() && IsCorrect;
1548 
1549   return !IsCorrect;
1550 }
1551 
1552 /// Parsing of OpenMP clauses.
1553 ///
1554 ///    clause:
1555 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
1556 ///       default-clause | private-clause | firstprivate-clause | shared-clause
1557 ///       | linear-clause | aligned-clause | collapse-clause |
1558 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
1559 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
1560 ///       mergeable-clause | flush-clause | read-clause | write-clause |
1561 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
1562 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
1563 ///       thread_limit-clause | priority-clause | grainsize-clause |
1564 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
1565 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
1566 ///       in_reduction-clause | allocator-clause | allocate-clause
1567 ///
ParseOpenMPClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,bool FirstClause)1568 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
1569                                      OpenMPClauseKind CKind, bool FirstClause) {
1570   OMPClause *Clause = nullptr;
1571   bool ErrorFound = false;
1572   bool WrongDirective = false;
1573   // Check if clause is allowed for the given directive.
1574   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
1575     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1576                                                << getOpenMPDirectiveName(DKind);
1577     ErrorFound = true;
1578     WrongDirective = true;
1579   }
1580 
1581   switch (CKind) {
1582   case OMPC_final:
1583   case OMPC_num_threads:
1584   case OMPC_safelen:
1585   case OMPC_simdlen:
1586   case OMPC_collapse:
1587   case OMPC_ordered:
1588   case OMPC_device:
1589   case OMPC_num_teams:
1590   case OMPC_thread_limit:
1591   case OMPC_priority:
1592   case OMPC_grainsize:
1593   case OMPC_num_tasks:
1594   case OMPC_hint:
1595   case OMPC_allocator:
1596     // OpenMP [2.5, Restrictions]
1597     //  At most one num_threads clause can appear on the directive.
1598     // OpenMP [2.8.1, simd construct, Restrictions]
1599     //  Only one safelen  clause can appear on a simd directive.
1600     //  Only one simdlen  clause can appear on a simd directive.
1601     //  Only one collapse clause can appear on a simd directive.
1602     // OpenMP [2.9.1, target data construct, Restrictions]
1603     //  At most one device clause can appear on the directive.
1604     // OpenMP [2.11.1, task Construct, Restrictions]
1605     //  At most one if clause can appear on the directive.
1606     //  At most one final clause can appear on the directive.
1607     // OpenMP [teams Construct, Restrictions]
1608     //  At most one num_teams clause can appear on the directive.
1609     //  At most one thread_limit clause can appear on the directive.
1610     // OpenMP [2.9.1, task Construct, Restrictions]
1611     // At most one priority clause can appear on the directive.
1612     // OpenMP [2.9.2, taskloop Construct, Restrictions]
1613     // At most one grainsize clause can appear on the directive.
1614     // OpenMP [2.9.2, taskloop Construct, Restrictions]
1615     // At most one num_tasks clause can appear on the directive.
1616     // OpenMP [2.11.3, allocate Directive, Restrictions]
1617     // At most one allocator clause can appear on the directive.
1618     if (!FirstClause) {
1619       Diag(Tok, diag::err_omp_more_one_clause)
1620           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1621       ErrorFound = true;
1622     }
1623 
1624     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
1625       Clause = ParseOpenMPClause(CKind, WrongDirective);
1626     else
1627       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
1628     break;
1629   case OMPC_default:
1630   case OMPC_proc_bind:
1631   case OMPC_atomic_default_mem_order:
1632     // OpenMP [2.14.3.1, Restrictions]
1633     //  Only a single default clause may be specified on a parallel, task or
1634     //  teams directive.
1635     // OpenMP [2.5, parallel Construct, Restrictions]
1636     //  At most one proc_bind clause can appear on the directive.
1637     // OpenMP [5.0, Requires directive, Restrictions]
1638     //  At most one atomic_default_mem_order clause can appear
1639     //  on the directive
1640     if (!FirstClause) {
1641       Diag(Tok, diag::err_omp_more_one_clause)
1642           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1643       ErrorFound = true;
1644     }
1645 
1646     Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
1647     break;
1648   case OMPC_schedule:
1649   case OMPC_dist_schedule:
1650   case OMPC_defaultmap:
1651     // OpenMP [2.7.1, Restrictions, p. 3]
1652     //  Only one schedule clause can appear on a loop directive.
1653     // OpenMP [2.10.4, Restrictions, p. 106]
1654     //  At most one defaultmap clause can appear on the directive.
1655     if (!FirstClause) {
1656       Diag(Tok, diag::err_omp_more_one_clause)
1657           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1658       ErrorFound = true;
1659     }
1660     LLVM_FALLTHROUGH;
1661 
1662   case OMPC_if:
1663     Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
1664     break;
1665   case OMPC_nowait:
1666   case OMPC_untied:
1667   case OMPC_mergeable:
1668   case OMPC_read:
1669   case OMPC_write:
1670   case OMPC_update:
1671   case OMPC_capture:
1672   case OMPC_seq_cst:
1673   case OMPC_threads:
1674   case OMPC_simd:
1675   case OMPC_nogroup:
1676   case OMPC_unified_address:
1677   case OMPC_unified_shared_memory:
1678   case OMPC_reverse_offload:
1679   case OMPC_dynamic_allocators:
1680     // OpenMP [2.7.1, Restrictions, p. 9]
1681     //  Only one ordered clause can appear on a loop directive.
1682     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
1683     //  Only one nowait clause can appear on a for directive.
1684     // OpenMP [5.0, Requires directive, Restrictions]
1685     //   Each of the requires clauses can appear at most once on the directive.
1686     if (!FirstClause) {
1687       Diag(Tok, diag::err_omp_more_one_clause)
1688           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1689       ErrorFound = true;
1690     }
1691 
1692     Clause = ParseOpenMPClause(CKind, WrongDirective);
1693     break;
1694   case OMPC_private:
1695   case OMPC_firstprivate:
1696   case OMPC_lastprivate:
1697   case OMPC_shared:
1698   case OMPC_reduction:
1699   case OMPC_task_reduction:
1700   case OMPC_in_reduction:
1701   case OMPC_linear:
1702   case OMPC_aligned:
1703   case OMPC_copyin:
1704   case OMPC_copyprivate:
1705   case OMPC_flush:
1706   case OMPC_depend:
1707   case OMPC_map:
1708   case OMPC_to:
1709   case OMPC_from:
1710   case OMPC_use_device_ptr:
1711   case OMPC_is_device_ptr:
1712   case OMPC_allocate:
1713     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
1714     break;
1715   case OMPC_unknown:
1716     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1717         << getOpenMPDirectiveName(DKind);
1718     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1719     break;
1720   case OMPC_threadprivate:
1721   case OMPC_uniform:
1722     if (!WrongDirective)
1723       Diag(Tok, diag::err_omp_unexpected_clause)
1724           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
1725     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1726     break;
1727   }
1728   return ErrorFound ? nullptr : Clause;
1729 }
1730 
1731 /// Parses simple expression in parens for single-expression clauses of OpenMP
1732 /// constructs.
1733 /// \param RLoc Returned location of right paren.
ParseOpenMPParensExpr(StringRef ClauseName,SourceLocation & RLoc)1734 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
1735                                          SourceLocation &RLoc) {
1736   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1737   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1738     return ExprError();
1739 
1740   SourceLocation ELoc = Tok.getLocation();
1741   ExprResult LHS(ParseCastExpression(
1742       /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
1743   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
1744   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
1745 
1746   // Parse ')'.
1747   RLoc = Tok.getLocation();
1748   if (!T.consumeClose())
1749     RLoc = T.getCloseLocation();
1750 
1751   return Val;
1752 }
1753 
1754 /// Parsing of OpenMP clauses with single expressions like 'final',
1755 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
1756 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
1757 ///
1758 ///    final-clause:
1759 ///      'final' '(' expression ')'
1760 ///
1761 ///    num_threads-clause:
1762 ///      'num_threads' '(' expression ')'
1763 ///
1764 ///    safelen-clause:
1765 ///      'safelen' '(' expression ')'
1766 ///
1767 ///    simdlen-clause:
1768 ///      'simdlen' '(' expression ')'
1769 ///
1770 ///    collapse-clause:
1771 ///      'collapse' '(' expression ')'
1772 ///
1773 ///    priority-clause:
1774 ///      'priority' '(' expression ')'
1775 ///
1776 ///    grainsize-clause:
1777 ///      'grainsize' '(' expression ')'
1778 ///
1779 ///    num_tasks-clause:
1780 ///      'num_tasks' '(' expression ')'
1781 ///
1782 ///    hint-clause:
1783 ///      'hint' '(' expression ')'
1784 ///
1785 ///    allocator-clause:
1786 ///      'allocator' '(' expression ')'
1787 ///
ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,bool ParseOnly)1788 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
1789                                                bool ParseOnly) {
1790   SourceLocation Loc = ConsumeToken();
1791   SourceLocation LLoc = Tok.getLocation();
1792   SourceLocation RLoc;
1793 
1794   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
1795 
1796   if (Val.isInvalid())
1797     return nullptr;
1798 
1799   if (ParseOnly)
1800     return nullptr;
1801   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
1802 }
1803 
1804 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1805 ///
1806 ///    default-clause:
1807 ///         'default' '(' 'none' | 'shared' ')
1808 ///
1809 ///    proc_bind-clause:
1810 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1811 ///
ParseOpenMPSimpleClause(OpenMPClauseKind Kind,bool ParseOnly)1812 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
1813                                            bool ParseOnly) {
1814   SourceLocation Loc = Tok.getLocation();
1815   SourceLocation LOpen = ConsumeToken();
1816   // Parse '('.
1817   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1818   if (T.expectAndConsume(diag::err_expected_lparen_after,
1819                          getOpenMPClauseName(Kind)))
1820     return nullptr;
1821 
1822   unsigned Type = getOpenMPSimpleClauseType(
1823       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1824   SourceLocation TypeLoc = Tok.getLocation();
1825   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1826       Tok.isNot(tok::annot_pragma_openmp_end))
1827     ConsumeAnyToken();
1828 
1829   // Parse ')'.
1830   SourceLocation RLoc = Tok.getLocation();
1831   if (!T.consumeClose())
1832     RLoc = T.getCloseLocation();
1833 
1834   if (ParseOnly)
1835     return nullptr;
1836   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, RLoc);
1837 }
1838 
1839 /// Parsing of OpenMP clauses like 'ordered'.
1840 ///
1841 ///    ordered-clause:
1842 ///         'ordered'
1843 ///
1844 ///    nowait-clause:
1845 ///         'nowait'
1846 ///
1847 ///    untied-clause:
1848 ///         'untied'
1849 ///
1850 ///    mergeable-clause:
1851 ///         'mergeable'
1852 ///
1853 ///    read-clause:
1854 ///         'read'
1855 ///
1856 ///    threads-clause:
1857 ///         'threads'
1858 ///
1859 ///    simd-clause:
1860 ///         'simd'
1861 ///
1862 ///    nogroup-clause:
1863 ///         'nogroup'
1864 ///
ParseOpenMPClause(OpenMPClauseKind Kind,bool ParseOnly)1865 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
1866   SourceLocation Loc = Tok.getLocation();
1867   ConsumeAnyToken();
1868 
1869   if (ParseOnly)
1870     return nullptr;
1871   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
1872 }
1873 
1874 
1875 /// Parsing of OpenMP clauses with single expressions and some additional
1876 /// argument like 'schedule' or 'dist_schedule'.
1877 ///
1878 ///    schedule-clause:
1879 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
1880 ///      ')'
1881 ///
1882 ///    if-clause:
1883 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
1884 ///
1885 ///    defaultmap:
1886 ///      'defaultmap' '(' modifier ':' kind ')'
1887 ///
ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,bool ParseOnly)1888 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
1889                                                       bool ParseOnly) {
1890   SourceLocation Loc = ConsumeToken();
1891   SourceLocation DelimLoc;
1892   // Parse '('.
1893   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1894   if (T.expectAndConsume(diag::err_expected_lparen_after,
1895                          getOpenMPClauseName(Kind)))
1896     return nullptr;
1897 
1898   ExprResult Val;
1899   SmallVector<unsigned, 4> Arg;
1900   SmallVector<SourceLocation, 4> KLoc;
1901   if (Kind == OMPC_schedule) {
1902     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1903     Arg.resize(NumberOfElements);
1904     KLoc.resize(NumberOfElements);
1905     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1906     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1907     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1908     unsigned KindModifier = getOpenMPSimpleClauseType(
1909         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1910     if (KindModifier > OMPC_SCHEDULE_unknown) {
1911       // Parse 'modifier'
1912       Arg[Modifier1] = KindModifier;
1913       KLoc[Modifier1] = Tok.getLocation();
1914       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1915           Tok.isNot(tok::annot_pragma_openmp_end))
1916         ConsumeAnyToken();
1917       if (Tok.is(tok::comma)) {
1918         // Parse ',' 'modifier'
1919         ConsumeAnyToken();
1920         KindModifier = getOpenMPSimpleClauseType(
1921             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1922         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1923                              ? KindModifier
1924                              : (unsigned)OMPC_SCHEDULE_unknown;
1925         KLoc[Modifier2] = Tok.getLocation();
1926         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1927             Tok.isNot(tok::annot_pragma_openmp_end))
1928           ConsumeAnyToken();
1929       }
1930       // Parse ':'
1931       if (Tok.is(tok::colon))
1932         ConsumeAnyToken();
1933       else
1934         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1935       KindModifier = getOpenMPSimpleClauseType(
1936           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1937     }
1938     Arg[ScheduleKind] = KindModifier;
1939     KLoc[ScheduleKind] = Tok.getLocation();
1940     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1941         Tok.isNot(tok::annot_pragma_openmp_end))
1942       ConsumeAnyToken();
1943     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1944          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1945          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1946         Tok.is(tok::comma))
1947       DelimLoc = ConsumeAnyToken();
1948   } else if (Kind == OMPC_dist_schedule) {
1949     Arg.push_back(getOpenMPSimpleClauseType(
1950         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1951     KLoc.push_back(Tok.getLocation());
1952     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1953         Tok.isNot(tok::annot_pragma_openmp_end))
1954       ConsumeAnyToken();
1955     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1956       DelimLoc = ConsumeAnyToken();
1957   } else if (Kind == OMPC_defaultmap) {
1958     // Get a defaultmap modifier
1959     Arg.push_back(getOpenMPSimpleClauseType(
1960         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1961     KLoc.push_back(Tok.getLocation());
1962     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1963         Tok.isNot(tok::annot_pragma_openmp_end))
1964       ConsumeAnyToken();
1965     // Parse ':'
1966     if (Tok.is(tok::colon))
1967       ConsumeAnyToken();
1968     else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1969       Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1970     // Get a defaultmap kind
1971     Arg.push_back(getOpenMPSimpleClauseType(
1972         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1973     KLoc.push_back(Tok.getLocation());
1974     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1975         Tok.isNot(tok::annot_pragma_openmp_end))
1976       ConsumeAnyToken();
1977   } else {
1978     assert(Kind == OMPC_if);
1979     KLoc.push_back(Tok.getLocation());
1980     TentativeParsingAction TPA(*this);
1981     Arg.push_back(parseOpenMPDirectiveKind(*this));
1982     if (Arg.back() != OMPD_unknown) {
1983       ConsumeToken();
1984       if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
1985         TPA.Commit();
1986         DelimLoc = ConsumeToken();
1987       } else {
1988         TPA.Revert();
1989         Arg.back() = OMPD_unknown;
1990       }
1991     } else {
1992       TPA.Revert();
1993     }
1994   }
1995 
1996   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1997                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1998                           Kind == OMPC_if;
1999   if (NeedAnExpression) {
2000     SourceLocation ELoc = Tok.getLocation();
2001     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
2002     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
2003     Val =
2004         Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
2005   }
2006 
2007   // Parse ')'.
2008   SourceLocation RLoc = Tok.getLocation();
2009   if (!T.consumeClose())
2010     RLoc = T.getCloseLocation();
2011 
2012   if (NeedAnExpression && Val.isInvalid())
2013     return nullptr;
2014 
2015   if (ParseOnly)
2016     return nullptr;
2017   return Actions.ActOnOpenMPSingleExprWithArgClause(
2018       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
2019 }
2020 
ParseReductionId(Parser & P,CXXScopeSpec & ReductionIdScopeSpec,UnqualifiedId & ReductionId)2021 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
2022                              UnqualifiedId &ReductionId) {
2023   if (ReductionIdScopeSpec.isEmpty()) {
2024     auto OOK = OO_None;
2025     switch (P.getCurToken().getKind()) {
2026     case tok::plus:
2027       OOK = OO_Plus;
2028       break;
2029     case tok::minus:
2030       OOK = OO_Minus;
2031       break;
2032     case tok::star:
2033       OOK = OO_Star;
2034       break;
2035     case tok::amp:
2036       OOK = OO_Amp;
2037       break;
2038     case tok::pipe:
2039       OOK = OO_Pipe;
2040       break;
2041     case tok::caret:
2042       OOK = OO_Caret;
2043       break;
2044     case tok::ampamp:
2045       OOK = OO_AmpAmp;
2046       break;
2047     case tok::pipepipe:
2048       OOK = OO_PipePipe;
2049       break;
2050     default:
2051       break;
2052     }
2053     if (OOK != OO_None) {
2054       SourceLocation OpLoc = P.ConsumeToken();
2055       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
2056       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
2057       return false;
2058     }
2059   }
2060   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
2061                               /*AllowDestructorName*/ false,
2062                               /*AllowConstructorName*/ false,
2063                               /*AllowDeductionGuide*/ false,
2064                               nullptr, nullptr, ReductionId);
2065 }
2066 
2067 /// Checks if the token is a valid map-type-modifier.
isMapModifier(Parser & P)2068 static OpenMPMapModifierKind isMapModifier(Parser &P) {
2069   Token Tok = P.getCurToken();
2070   if (!Tok.is(tok::identifier))
2071     return OMPC_MAP_MODIFIER_unknown;
2072 
2073   Preprocessor &PP = P.getPreprocessor();
2074   OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
2075       getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2076   return TypeModifier;
2077 }
2078 
2079 /// Parse the mapper modifier in map, to, and from clauses.
parseMapperModifier(OpenMPVarListDataTy & Data)2080 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
2081   // Parse '('.
2082   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
2083   if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
2084     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2085               StopBeforeMatch);
2086     return true;
2087   }
2088   // Parse mapper-identifier
2089   if (getLangOpts().CPlusPlus)
2090     ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2091                                    /*ObjectType=*/nullptr,
2092                                    /*EnteringContext=*/false);
2093   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
2094     Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2095     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2096               StopBeforeMatch);
2097     return true;
2098   }
2099   auto &DeclNames = Actions.getASTContext().DeclarationNames;
2100   Data.ReductionOrMapperId = DeclarationNameInfo(
2101       DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
2102   ConsumeToken();
2103   // Parse ')'.
2104   return T.consumeClose();
2105 }
2106 
2107 /// Parse map-type-modifiers in map clause.
2108 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2109 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
parseMapTypeModifiers(OpenMPVarListDataTy & Data)2110 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
2111   while (getCurToken().isNot(tok::colon)) {
2112     OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
2113     if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2114         TypeModifier == OMPC_MAP_MODIFIER_close) {
2115       Data.MapTypeModifiers.push_back(TypeModifier);
2116       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2117       ConsumeToken();
2118     } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2119       Data.MapTypeModifiers.push_back(TypeModifier);
2120       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2121       ConsumeToken();
2122       if (parseMapperModifier(Data))
2123         return true;
2124     } else {
2125       // For the case of unknown map-type-modifier or a map-type.
2126       // Map-type is followed by a colon; the function returns when it
2127       // encounters a token followed by a colon.
2128       if (Tok.is(tok::comma)) {
2129         Diag(Tok, diag::err_omp_map_type_modifier_missing);
2130         ConsumeToken();
2131         continue;
2132       }
2133       // Potential map-type token as it is followed by a colon.
2134       if (PP.LookAhead(0).is(tok::colon))
2135         return false;
2136       Diag(Tok, diag::err_omp_unknown_map_type_modifier);
2137       ConsumeToken();
2138     }
2139     if (getCurToken().is(tok::comma))
2140       ConsumeToken();
2141   }
2142   return false;
2143 }
2144 
2145 /// Checks if the token is a valid map-type.
isMapType(Parser & P)2146 static OpenMPMapClauseKind isMapType(Parser &P) {
2147   Token Tok = P.getCurToken();
2148   // The map-type token can be either an identifier or the C++ delete keyword.
2149   if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
2150     return OMPC_MAP_unknown;
2151   Preprocessor &PP = P.getPreprocessor();
2152   OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
2153       getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2154   return MapType;
2155 }
2156 
2157 /// Parse map-type in map clause.
2158 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2159 /// where, map-type ::= to | from | tofrom | alloc | release | delete
parseMapType(Parser & P,Parser::OpenMPVarListDataTy & Data)2160 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
2161   Token Tok = P.getCurToken();
2162   if (Tok.is(tok::colon)) {
2163     P.Diag(Tok, diag::err_omp_map_type_missing);
2164     return;
2165   }
2166   Data.MapType = isMapType(P);
2167   if (Data.MapType == OMPC_MAP_unknown)
2168     P.Diag(Tok, diag::err_omp_unknown_map_type);
2169   P.ConsumeToken();
2170 }
2171 
2172 /// Parses clauses with list.
ParseOpenMPVarList(OpenMPDirectiveKind DKind,OpenMPClauseKind Kind,SmallVectorImpl<Expr * > & Vars,OpenMPVarListDataTy & Data)2173 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
2174                                 OpenMPClauseKind Kind,
2175                                 SmallVectorImpl<Expr *> &Vars,
2176                                 OpenMPVarListDataTy &Data) {
2177   UnqualifiedId UnqualifiedReductionId;
2178   bool InvalidReductionId = false;
2179   bool IsInvalidMapperModifier = false;
2180 
2181   // Parse '('.
2182   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2183   if (T.expectAndConsume(diag::err_expected_lparen_after,
2184                          getOpenMPClauseName(Kind)))
2185     return true;
2186 
2187   bool NeedRParenForLinear = false;
2188   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
2189                                   tok::annot_pragma_openmp_end);
2190   // Handle reduction-identifier for reduction clause.
2191   if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
2192       Kind == OMPC_in_reduction) {
2193     ColonProtectionRAIIObject ColonRAII(*this);
2194     if (getLangOpts().CPlusPlus)
2195       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2196                                      /*ObjectType=*/nullptr,
2197                                      /*EnteringContext=*/false);
2198     InvalidReductionId = ParseReductionId(
2199         *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
2200     if (InvalidReductionId) {
2201       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2202                 StopBeforeMatch);
2203     }
2204     if (Tok.is(tok::colon))
2205       Data.ColonLoc = ConsumeToken();
2206     else
2207       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
2208     if (!InvalidReductionId)
2209       Data.ReductionOrMapperId =
2210           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
2211   } else if (Kind == OMPC_depend) {
2212   // Handle dependency type for depend clause.
2213     ColonProtectionRAIIObject ColonRAII(*this);
2214     Data.DepKind =
2215         static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
2216             Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
2217     Data.DepLinMapLoc = Tok.getLocation();
2218 
2219     if (Data.DepKind == OMPC_DEPEND_unknown) {
2220       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2221                 StopBeforeMatch);
2222     } else {
2223       ConsumeToken();
2224       // Special processing for depend(source) clause.
2225       if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
2226         // Parse ')'.
2227         T.consumeClose();
2228         return false;
2229       }
2230     }
2231     if (Tok.is(tok::colon)) {
2232       Data.ColonLoc = ConsumeToken();
2233     } else {
2234       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
2235                                       : diag::warn_pragma_expected_colon)
2236           << "dependency type";
2237     }
2238   } else if (Kind == OMPC_linear) {
2239     // Try to parse modifier if any.
2240     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
2241       Data.LinKind = static_cast<OpenMPLinearClauseKind>(
2242           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2243       Data.DepLinMapLoc = ConsumeToken();
2244       LinearT.consumeOpen();
2245       NeedRParenForLinear = true;
2246     }
2247   } else if (Kind == OMPC_map) {
2248     // Handle map type for map clause.
2249     ColonProtectionRAIIObject ColonRAII(*this);
2250 
2251     // The first identifier may be a list item, a map-type or a
2252     // map-type-modifier. The map-type can also be delete which has the same
2253     // spelling of the C++ delete keyword.
2254     Data.DepLinMapLoc = Tok.getLocation();
2255 
2256     // Check for presence of a colon in the map clause.
2257     TentativeParsingAction TPA(*this);
2258     bool ColonPresent = false;
2259     if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2260         StopBeforeMatch)) {
2261       if (Tok.is(tok::colon))
2262         ColonPresent = true;
2263     }
2264     TPA.Revert();
2265     // Only parse map-type-modifier[s] and map-type if a colon is present in
2266     // the map clause.
2267     if (ColonPresent) {
2268       IsInvalidMapperModifier = parseMapTypeModifiers(Data);
2269       if (!IsInvalidMapperModifier)
2270         parseMapType(*this, Data);
2271       else
2272         SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
2273     }
2274     if (Data.MapType == OMPC_MAP_unknown) {
2275       Data.MapType = OMPC_MAP_tofrom;
2276       Data.IsMapTypeImplicit = true;
2277     }
2278 
2279     if (Tok.is(tok::colon))
2280       Data.ColonLoc = ConsumeToken();
2281   } else if (Kind == OMPC_to || Kind == OMPC_from) {
2282     if (Tok.is(tok::identifier)) {
2283       bool IsMapperModifier = false;
2284       if (Kind == OMPC_to) {
2285         auto Modifier = static_cast<OpenMPToModifierKind>(
2286             getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2287         if (Modifier == OMPC_TO_MODIFIER_mapper)
2288           IsMapperModifier = true;
2289       } else {
2290         auto Modifier = static_cast<OpenMPFromModifierKind>(
2291             getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2292         if (Modifier == OMPC_FROM_MODIFIER_mapper)
2293           IsMapperModifier = true;
2294       }
2295       if (IsMapperModifier) {
2296         // Parse the mapper modifier.
2297         ConsumeToken();
2298         IsInvalidMapperModifier = parseMapperModifier(Data);
2299         if (Tok.isNot(tok::colon)) {
2300           if (!IsInvalidMapperModifier)
2301             Diag(Tok, diag::warn_pragma_expected_colon) << ")";
2302           SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2303                     StopBeforeMatch);
2304         }
2305         // Consume ':'.
2306         if (Tok.is(tok::colon))
2307           ConsumeToken();
2308       }
2309     }
2310   } else if (Kind == OMPC_allocate) {
2311     // Handle optional allocator expression followed by colon delimiter.
2312     ColonProtectionRAIIObject ColonRAII(*this);
2313     TentativeParsingAction TPA(*this);
2314     ExprResult Tail =
2315         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2316     Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
2317                                        /*DiscardedValue=*/false);
2318     if (Tail.isUsable()) {
2319       if (Tok.is(tok::colon)) {
2320         Data.TailExpr = Tail.get();
2321         Data.ColonLoc = ConsumeToken();
2322         TPA.Commit();
2323       } else {
2324         // colon not found, no allocator specified, parse only list of
2325         // variables.
2326         TPA.Revert();
2327       }
2328     } else {
2329       // Parsing was unsuccessfull, revert and skip to the end of clause or
2330       // directive.
2331       TPA.Revert();
2332       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2333                 StopBeforeMatch);
2334     }
2335   }
2336 
2337   bool IsComma =
2338       (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
2339        Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
2340       (Kind == OMPC_reduction && !InvalidReductionId) ||
2341       (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown) ||
2342       (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
2343   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
2344   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
2345                      Tok.isNot(tok::annot_pragma_openmp_end))) {
2346     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
2347     // Parse variable
2348     ExprResult VarExpr =
2349         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2350     if (VarExpr.isUsable()) {
2351       Vars.push_back(VarExpr.get());
2352     } else {
2353       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2354                 StopBeforeMatch);
2355     }
2356     // Skip ',' if any
2357     IsComma = Tok.is(tok::comma);
2358     if (IsComma)
2359       ConsumeToken();
2360     else if (Tok.isNot(tok::r_paren) &&
2361              Tok.isNot(tok::annot_pragma_openmp_end) &&
2362              (!MayHaveTail || Tok.isNot(tok::colon)))
2363       Diag(Tok, diag::err_omp_expected_punc)
2364           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
2365                                    : getOpenMPClauseName(Kind))
2366           << (Kind == OMPC_flush);
2367   }
2368 
2369   // Parse ')' for linear clause with modifier.
2370   if (NeedRParenForLinear)
2371     LinearT.consumeClose();
2372 
2373   // Parse ':' linear-step (or ':' alignment).
2374   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
2375   if (MustHaveTail) {
2376     Data.ColonLoc = Tok.getLocation();
2377     SourceLocation ELoc = ConsumeToken();
2378     ExprResult Tail = ParseAssignmentExpression();
2379     Tail =
2380         Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
2381     if (Tail.isUsable())
2382       Data.TailExpr = Tail.get();
2383     else
2384       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2385                 StopBeforeMatch);
2386   }
2387 
2388   // Parse ')'.
2389   Data.RLoc = Tok.getLocation();
2390   if (!T.consumeClose())
2391     Data.RLoc = T.getCloseLocation();
2392   return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
2393           Vars.empty()) ||
2394          (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
2395          (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
2396          IsInvalidMapperModifier;
2397 }
2398 
2399 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
2400 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
2401 /// 'in_reduction'.
2402 ///
2403 ///    private-clause:
2404 ///       'private' '(' list ')'
2405 ///    firstprivate-clause:
2406 ///       'firstprivate' '(' list ')'
2407 ///    lastprivate-clause:
2408 ///       'lastprivate' '(' list ')'
2409 ///    shared-clause:
2410 ///       'shared' '(' list ')'
2411 ///    linear-clause:
2412 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
2413 ///    aligned-clause:
2414 ///       'aligned' '(' list [ ':' alignment ] ')'
2415 ///    reduction-clause:
2416 ///       'reduction' '(' reduction-identifier ':' list ')'
2417 ///    task_reduction-clause:
2418 ///       'task_reduction' '(' reduction-identifier ':' list ')'
2419 ///    in_reduction-clause:
2420 ///       'in_reduction' '(' reduction-identifier ':' list ')'
2421 ///    copyprivate-clause:
2422 ///       'copyprivate' '(' list ')'
2423 ///    flush-clause:
2424 ///       'flush' '(' list ')'
2425 ///    depend-clause:
2426 ///       'depend' '(' in | out | inout : list | source ')'
2427 ///    map-clause:
2428 ///       'map' '(' [ [ always [,] ] [ close [,] ]
2429 ///          [ mapper '(' mapper-identifier ')' [,] ]
2430 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
2431 ///    to-clause:
2432 ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2433 ///    from-clause:
2434 ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2435 ///    use_device_ptr-clause:
2436 ///       'use_device_ptr' '(' list ')'
2437 ///    is_device_ptr-clause:
2438 ///       'is_device_ptr' '(' list ')'
2439 ///    allocate-clause:
2440 ///       'allocate' '(' [ allocator ':' ] list ')'
2441 ///
2442 /// For 'linear' clause linear-list may have the following forms:
2443 ///  list
2444 ///  modifier(list)
2445 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,OpenMPClauseKind Kind,bool ParseOnly)2446 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
2447                                             OpenMPClauseKind Kind,
2448                                             bool ParseOnly) {
2449   SourceLocation Loc = Tok.getLocation();
2450   SourceLocation LOpen = ConsumeToken();
2451   SmallVector<Expr *, 4> Vars;
2452   OpenMPVarListDataTy Data;
2453 
2454   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
2455     return nullptr;
2456 
2457   if (ParseOnly)
2458     return nullptr;
2459   OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
2460   return Actions.ActOnOpenMPVarListClause(
2461       Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
2462       Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind,
2463       Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
2464       Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc);
2465 }
2466 
2467