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