Home | History | Annotate | Download | only in Parse
      1 //===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 /// \brief This file implements parsing of all OpenMP directives and clauses.
     11 ///
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "RAIIObjectsForParser.h"
     15 #include "clang/AST/ASTConsumer.h"
     16 #include "clang/AST/ASTContext.h"
     17 #include "clang/AST/StmtOpenMP.h"
     18 #include "clang/Parse/ParseDiagnostic.h"
     19 #include "clang/Parse/Parser.h"
     20 #include "clang/Sema/Scope.h"
     21 #include "llvm/ADT/PointerIntPair.h"
     22 
     23 using namespace clang;
     24 
     25 //===----------------------------------------------------------------------===//
     26 // OpenMP declarative directives.
     27 //===----------------------------------------------------------------------===//
     28 
     29 namespace {
     30 enum OpenMPDirectiveKindEx {
     31   OMPD_cancellation = OMPD_unknown + 1,
     32   OMPD_data,
     33   OMPD_declare,
     34   OMPD_end,
     35   OMPD_end_declare,
     36   OMPD_enter,
     37   OMPD_exit,
     38   OMPD_point,
     39   OMPD_reduction,
     40   OMPD_target_enter,
     41   OMPD_target_exit,
     42   OMPD_update,
     43   OMPD_distribute_parallel
     44 };
     45 
     46 class ThreadprivateListParserHelper final {
     47   SmallVector<Expr *, 4> Identifiers;
     48   Parser *P;
     49 
     50 public:
     51   ThreadprivateListParserHelper(Parser *P) : P(P) {}
     52   void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
     53     ExprResult Res =
     54         P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo);
     55     if (Res.isUsable())
     56       Identifiers.push_back(Res.get());
     57   }
     58   llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
     59 };
     60 } // namespace
     61 
     62 // Map token string to extended OMP token kind that are
     63 // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
     64 static unsigned getOpenMPDirectiveKindEx(StringRef S) {
     65   auto DKind = getOpenMPDirectiveKind(S);
     66   if (DKind != OMPD_unknown)
     67     return DKind;
     68 
     69   return llvm::StringSwitch<unsigned>(S)
     70       .Case("cancellation", OMPD_cancellation)
     71       .Case("data", OMPD_data)
     72       .Case("declare", OMPD_declare)
     73       .Case("end", OMPD_end)
     74       .Case("enter", OMPD_enter)
     75       .Case("exit", OMPD_exit)
     76       .Case("point", OMPD_point)
     77       .Case("reduction", OMPD_reduction)
     78       .Case("update", OMPD_update)
     79       .Default(OMPD_unknown);
     80 }
     81 
     82 static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
     83   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
     84   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
     85   // TODO: add other combined directives in topological order.
     86   static const unsigned F[][3] = {
     87     { OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
     88     { OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
     89     { OMPD_declare, OMPD_simd, OMPD_declare_simd },
     90     { OMPD_declare, OMPD_target, OMPD_declare_target },
     91     { OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel },
     92     { OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for },
     93     { OMPD_distribute_parallel_for, OMPD_simd,
     94       OMPD_distribute_parallel_for_simd },
     95     { OMPD_distribute, OMPD_simd, OMPD_distribute_simd },
     96     { OMPD_end, OMPD_declare, OMPD_end_declare },
     97     { OMPD_end_declare, OMPD_target, OMPD_end_declare_target },
     98     { OMPD_target, OMPD_data, OMPD_target_data },
     99     { OMPD_target, OMPD_enter, OMPD_target_enter },
    100     { OMPD_target, OMPD_exit, OMPD_target_exit },
    101     { OMPD_target, OMPD_update, OMPD_target_update },
    102     { OMPD_target_enter, OMPD_data, OMPD_target_enter_data },
    103     { OMPD_target_exit, OMPD_data, OMPD_target_exit_data },
    104     { OMPD_for, OMPD_simd, OMPD_for_simd },
    105     { OMPD_parallel, OMPD_for, OMPD_parallel_for },
    106     { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd },
    107     { OMPD_parallel, OMPD_sections, OMPD_parallel_sections },
    108     { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd },
    109     { OMPD_target, OMPD_parallel, OMPD_target_parallel },
    110     { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for },
    111     { OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd }
    112   };
    113   enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
    114   auto Tok = P.getCurToken();
    115   unsigned DKind =
    116       Tok.isAnnotation()
    117           ? static_cast<unsigned>(OMPD_unknown)
    118           : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
    119   if (DKind == OMPD_unknown)
    120     return OMPD_unknown;
    121 
    122   for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
    123     if (DKind != F[i][0])
    124       continue;
    125 
    126     Tok = P.getPreprocessor().LookAhead(0);
    127     unsigned SDKind =
    128         Tok.isAnnotation()
    129             ? static_cast<unsigned>(OMPD_unknown)
    130             : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
    131     if (SDKind == OMPD_unknown)
    132       continue;
    133 
    134     if (SDKind == F[i][1]) {
    135       P.ConsumeToken();
    136       DKind = F[i][2];
    137     }
    138   }
    139   return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
    140                               : OMPD_unknown;
    141 }
    142 
    143 static DeclarationName parseOpenMPReductionId(Parser &P) {
    144   Token Tok = P.getCurToken();
    145   Sema &Actions = P.getActions();
    146   OverloadedOperatorKind OOK = OO_None;
    147   // Allow to use 'operator' keyword for C++ operators
    148   bool WithOperator = false;
    149   if (Tok.is(tok::kw_operator)) {
    150     P.ConsumeToken();
    151     Tok = P.getCurToken();
    152     WithOperator = true;
    153   }
    154   switch (Tok.getKind()) {
    155   case tok::plus: // '+'
    156     OOK = OO_Plus;
    157     break;
    158   case tok::minus: // '-'
    159     OOK = OO_Minus;
    160     break;
    161   case tok::star: // '*'
    162     OOK = OO_Star;
    163     break;
    164   case tok::amp: // '&'
    165     OOK = OO_Amp;
    166     break;
    167   case tok::pipe: // '|'
    168     OOK = OO_Pipe;
    169     break;
    170   case tok::caret: // '^'
    171     OOK = OO_Caret;
    172     break;
    173   case tok::ampamp: // '&&'
    174     OOK = OO_AmpAmp;
    175     break;
    176   case tok::pipepipe: // '||'
    177     OOK = OO_PipePipe;
    178     break;
    179   case tok::identifier: // identifier
    180     if (!WithOperator)
    181       break;
    182   default:
    183     P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
    184     P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
    185                 Parser::StopBeforeMatch);
    186     return DeclarationName();
    187   }
    188   P.ConsumeToken();
    189   auto &DeclNames = Actions.getASTContext().DeclarationNames;
    190   return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
    191                         : DeclNames.getCXXOperatorName(OOK);
    192 }
    193 
    194 /// \brief Parse 'omp declare reduction' construct.
    195 ///
    196 ///       declare-reduction-directive:
    197 ///        annot_pragma_openmp 'declare' 'reduction'
    198 ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
    199 ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
    200 ///        annot_pragma_openmp_end
    201 /// <reduction_id> is either a base language identifier or one of the following
    202 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
    203 ///
    204 Parser::DeclGroupPtrTy
    205 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
    206   // Parse '('.
    207   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
    208   if (T.expectAndConsume(diag::err_expected_lparen_after,
    209                          getOpenMPDirectiveName(OMPD_declare_reduction))) {
    210     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    211     return DeclGroupPtrTy();
    212   }
    213 
    214   DeclarationName Name = parseOpenMPReductionId(*this);
    215   if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
    216     return DeclGroupPtrTy();
    217 
    218   // Consume ':'.
    219   bool IsCorrect = !ExpectAndConsume(tok::colon);
    220 
    221   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
    222     return DeclGroupPtrTy();
    223 
    224   IsCorrect = IsCorrect && !Name.isEmpty();
    225 
    226   if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
    227     Diag(Tok.getLocation(), diag::err_expected_type);
    228     IsCorrect = false;
    229   }
    230 
    231   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
    232     return DeclGroupPtrTy();
    233 
    234   SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
    235   // Parse list of types until ':' token.
    236   do {
    237     ColonProtectionRAIIObject ColonRAII(*this);
    238     SourceRange Range;
    239     TypeResult TR = ParseTypeName(&Range, Declarator::PrototypeContext, AS);
    240     if (TR.isUsable()) {
    241       auto ReductionType =
    242           Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
    243       if (!ReductionType.isNull()) {
    244         ReductionTypes.push_back(
    245             std::make_pair(ReductionType, Range.getBegin()));
    246       }
    247     } else {
    248       SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
    249                 StopBeforeMatch);
    250     }
    251 
    252     if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
    253       break;
    254 
    255     // Consume ','.
    256     if (ExpectAndConsume(tok::comma)) {
    257       IsCorrect = false;
    258       if (Tok.is(tok::annot_pragma_openmp_end)) {
    259         Diag(Tok.getLocation(), diag::err_expected_type);
    260         return DeclGroupPtrTy();
    261       }
    262     }
    263   } while (Tok.isNot(tok::annot_pragma_openmp_end));
    264 
    265   if (ReductionTypes.empty()) {
    266     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    267     return DeclGroupPtrTy();
    268   }
    269 
    270   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
    271     return DeclGroupPtrTy();
    272 
    273   // Consume ':'.
    274   if (ExpectAndConsume(tok::colon))
    275     IsCorrect = false;
    276 
    277   if (Tok.is(tok::annot_pragma_openmp_end)) {
    278     Diag(Tok.getLocation(), diag::err_expected_expression);
    279     return DeclGroupPtrTy();
    280   }
    281 
    282   DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
    283       getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
    284 
    285   // Parse <combiner> expression and then parse initializer if any for each
    286   // correct type.
    287   unsigned I = 0, E = ReductionTypes.size();
    288   for (auto *D : DRD.get()) {
    289     TentativeParsingAction TPA(*this);
    290     ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
    291                                     Scope::OpenMPDirectiveScope);
    292     // Parse <combiner> expression.
    293     Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
    294     ExprResult CombinerResult =
    295         Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
    296                                     D->getLocation(), /*DiscardedValue=*/true);
    297     Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
    298 
    299     if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
    300         Tok.isNot(tok::annot_pragma_openmp_end)) {
    301       TPA.Commit();
    302       IsCorrect = false;
    303       break;
    304     }
    305     IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
    306     ExprResult InitializerResult;
    307     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    308       // Parse <initializer> expression.
    309       if (Tok.is(tok::identifier) &&
    310           Tok.getIdentifierInfo()->isStr("initializer"))
    311         ConsumeToken();
    312       else {
    313         Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
    314         TPA.Commit();
    315         IsCorrect = false;
    316         break;
    317       }
    318       // Parse '('.
    319       BalancedDelimiterTracker T(*this, tok::l_paren,
    320                                  tok::annot_pragma_openmp_end);
    321       IsCorrect =
    322           !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
    323           IsCorrect;
    324       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    325         ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
    326                                         Scope::OpenMPDirectiveScope);
    327         // Parse expression.
    328         Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), D);
    329         InitializerResult = Actions.ActOnFinishFullExpr(
    330             ParseAssignmentExpression().get(), D->getLocation(),
    331             /*DiscardedValue=*/true);
    332         Actions.ActOnOpenMPDeclareReductionInitializerEnd(
    333             D, InitializerResult.get());
    334         if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
    335             Tok.isNot(tok::annot_pragma_openmp_end)) {
    336           TPA.Commit();
    337           IsCorrect = false;
    338           break;
    339         }
    340         IsCorrect =
    341             !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
    342       }
    343     }
    344 
    345     ++I;
    346     // Revert parsing if not the last type, otherwise accept it, we're done with
    347     // parsing.
    348     if (I != E)
    349       TPA.Revert();
    350     else
    351       TPA.Commit();
    352   }
    353   return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
    354                                                          IsCorrect);
    355 }
    356 
    357 namespace {
    358 /// RAII that recreates function context for correct parsing of clauses of
    359 /// 'declare simd' construct.
    360 /// OpenMP, 2.8.2 declare simd Construct
    361 /// The expressions appearing in the clauses of this directive are evaluated in
    362 /// the scope of the arguments of the function declaration or definition.
    363 class FNContextRAII final {
    364   Parser &P;
    365   Sema::CXXThisScopeRAII *ThisScope;
    366   Parser::ParseScope *TempScope;
    367   Parser::ParseScope *FnScope;
    368   bool HasTemplateScope = false;
    369   bool HasFunScope = false;
    370   FNContextRAII() = delete;
    371   FNContextRAII(const FNContextRAII &) = delete;
    372   FNContextRAII &operator=(const FNContextRAII &) = delete;
    373 
    374 public:
    375   FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
    376     Decl *D = *Ptr.get().begin();
    377     NamedDecl *ND = dyn_cast<NamedDecl>(D);
    378     RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
    379     Sema &Actions = P.getActions();
    380 
    381     // Allow 'this' within late-parsed attributes.
    382     ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, /*TypeQuals=*/0,
    383                                            ND && ND->isCXXInstanceMember());
    384 
    385     // If the Decl is templatized, add template parameters to scope.
    386     HasTemplateScope = D->isTemplateDecl();
    387     TempScope =
    388         new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
    389     if (HasTemplateScope)
    390       Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
    391 
    392     // If the Decl is on a function, add function parameters to the scope.
    393     HasFunScope = D->isFunctionOrFunctionTemplate();
    394     FnScope = new Parser::ParseScope(&P, Scope::FnScope | Scope::DeclScope,
    395                                      HasFunScope);
    396     if (HasFunScope)
    397       Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
    398   }
    399   ~FNContextRAII() {
    400     if (HasFunScope) {
    401       P.getActions().ActOnExitFunctionContext();
    402       FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
    403     }
    404     if (HasTemplateScope)
    405       TempScope->Exit();
    406     delete FnScope;
    407     delete TempScope;
    408     delete ThisScope;
    409   }
    410 };
    411 } // namespace
    412 
    413 /// Parses clauses for 'declare simd' directive.
    414 ///    clause:
    415 ///      'inbranch' | 'notinbranch'
    416 ///      'simdlen' '(' <expr> ')'
    417 ///      { 'uniform' '(' <argument_list> ')' }
    418 ///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
    419 ///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
    420 static bool parseDeclareSimdClauses(
    421     Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
    422     SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
    423     SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
    424     SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
    425   SourceRange BSRange;
    426   const Token &Tok = P.getCurToken();
    427   bool IsError = false;
    428   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
    429     if (Tok.isNot(tok::identifier))
    430       break;
    431     OMPDeclareSimdDeclAttr::BranchStateTy Out;
    432     IdentifierInfo *II = Tok.getIdentifierInfo();
    433     StringRef ClauseName = II->getName();
    434     // Parse 'inranch|notinbranch' clauses.
    435     if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
    436       if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
    437         P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
    438             << ClauseName
    439             << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
    440         IsError = true;
    441       }
    442       BS = Out;
    443       BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
    444       P.ConsumeToken();
    445     } else if (ClauseName.equals("simdlen")) {
    446       if (SimdLen.isUsable()) {
    447         P.Diag(Tok, diag::err_omp_more_one_clause)
    448             << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
    449         IsError = true;
    450       }
    451       P.ConsumeToken();
    452       SourceLocation RLoc;
    453       SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
    454       if (SimdLen.isInvalid())
    455         IsError = true;
    456     } else {
    457       OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
    458       if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
    459           CKind == OMPC_linear) {
    460         Parser::OpenMPVarListDataTy Data;
    461         auto *Vars = &Uniforms;
    462         if (CKind == OMPC_aligned)
    463           Vars = &Aligneds;
    464         else if (CKind == OMPC_linear)
    465           Vars = &Linears;
    466 
    467         P.ConsumeToken();
    468         if (P.ParseOpenMPVarList(OMPD_declare_simd,
    469                                  getOpenMPClauseKind(ClauseName), *Vars, Data))
    470           IsError = true;
    471         if (CKind == OMPC_aligned)
    472           Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
    473         else if (CKind == OMPC_linear) {
    474           if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
    475                                                        Data.DepLinMapLoc))
    476             Data.LinKind = OMPC_LINEAR_val;
    477           LinModifiers.append(Linears.size() - LinModifiers.size(),
    478                               Data.LinKind);
    479           Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
    480         }
    481       } else
    482         // TODO: add parsing of other clauses.
    483         break;
    484     }
    485     // Skip ',' if any.
    486     if (Tok.is(tok::comma))
    487       P.ConsumeToken();
    488   }
    489   return IsError;
    490 }
    491 
    492 /// Parse clauses for '#pragma omp declare simd'.
    493 Parser::DeclGroupPtrTy
    494 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
    495                                    CachedTokens &Toks, SourceLocation Loc) {
    496   PP.EnterToken(Tok);
    497   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
    498   // Consume the previously pushed token.
    499   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
    500 
    501   FNContextRAII FnContext(*this, Ptr);
    502   OMPDeclareSimdDeclAttr::BranchStateTy BS =
    503       OMPDeclareSimdDeclAttr::BS_Undefined;
    504   ExprResult Simdlen;
    505   SmallVector<Expr *, 4> Uniforms;
    506   SmallVector<Expr *, 4> Aligneds;
    507   SmallVector<Expr *, 4> Alignments;
    508   SmallVector<Expr *, 4> Linears;
    509   SmallVector<unsigned, 4> LinModifiers;
    510   SmallVector<Expr *, 4> Steps;
    511   bool IsError =
    512       parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
    513                               Alignments, Linears, LinModifiers, Steps);
    514   // Need to check for extra tokens.
    515   if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    516     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    517         << getOpenMPDirectiveName(OMPD_declare_simd);
    518     while (Tok.isNot(tok::annot_pragma_openmp_end))
    519       ConsumeAnyToken();
    520   }
    521   // Skip the last annot_pragma_openmp_end.
    522   SourceLocation EndLoc = ConsumeToken();
    523   if (!IsError) {
    524     return Actions.ActOnOpenMPDeclareSimdDirective(
    525         Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
    526         LinModifiers, Steps, SourceRange(Loc, EndLoc));
    527   }
    528   return Ptr;
    529 }
    530 
    531 /// \brief Parsing of declarative OpenMP directives.
    532 ///
    533 ///       threadprivate-directive:
    534 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
    535 ///         annot_pragma_openmp_end
    536 ///
    537 ///       declare-reduction-directive:
    538 ///        annot_pragma_openmp 'declare' 'reduction' [...]
    539 ///        annot_pragma_openmp_end
    540 ///
    541 ///       declare-simd-directive:
    542 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
    543 ///         annot_pragma_openmp_end
    544 ///         <function declaration/definition>
    545 ///
    546 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
    547     AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
    548     DeclSpec::TST TagType, Decl *Tag) {
    549   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
    550   ParenBraceBracketBalancer BalancerRAIIObj(*this);
    551 
    552   SourceLocation Loc = ConsumeToken();
    553   auto DKind = ParseOpenMPDirectiveKind(*this);
    554 
    555   switch (DKind) {
    556   case OMPD_threadprivate: {
    557     ConsumeToken();
    558     ThreadprivateListParserHelper Helper(this);
    559     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) {
    560       // The last seen token is annot_pragma_openmp_end - need to check for
    561       // extra tokens.
    562       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    563         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    564             << getOpenMPDirectiveName(OMPD_threadprivate);
    565         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    566       }
    567       // Skip the last annot_pragma_openmp_end.
    568       ConsumeToken();
    569       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
    570                                                        Helper.getIdentifiers());
    571     }
    572     break;
    573   }
    574   case OMPD_declare_reduction:
    575     ConsumeToken();
    576     if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) {
    577       // The last seen token is annot_pragma_openmp_end - need to check for
    578       // extra tokens.
    579       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    580         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    581             << getOpenMPDirectiveName(OMPD_declare_reduction);
    582         while (Tok.isNot(tok::annot_pragma_openmp_end))
    583           ConsumeAnyToken();
    584       }
    585       // Skip the last annot_pragma_openmp_end.
    586       ConsumeToken();
    587       return Res;
    588     }
    589     break;
    590   case OMPD_declare_simd: {
    591     // The syntax is:
    592     // { #pragma omp declare simd }
    593     // <function-declaration-or-definition>
    594     //
    595     ConsumeToken();
    596     CachedTokens Toks;
    597     while(Tok.isNot(tok::annot_pragma_openmp_end)) {
    598       Toks.push_back(Tok);
    599       ConsumeAnyToken();
    600     }
    601     Toks.push_back(Tok);
    602     ConsumeAnyToken();
    603 
    604     DeclGroupPtrTy Ptr;
    605     if (Tok.is(tok::annot_pragma_openmp))
    606       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
    607     else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
    608       // Here we expect to see some function declaration.
    609       if (AS == AS_none) {
    610         assert(TagType == DeclSpec::TST_unspecified);
    611         MaybeParseCXX11Attributes(Attrs);
    612         MaybeParseMicrosoftAttributes(Attrs);
    613         ParsingDeclSpec PDS(*this);
    614         Ptr = ParseExternalDeclaration(Attrs, &PDS);
    615       } else {
    616         Ptr =
    617             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
    618       }
    619     }
    620     if (!Ptr) {
    621       Diag(Loc, diag::err_omp_decl_in_declare_simd);
    622       return DeclGroupPtrTy();
    623     }
    624     return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
    625   }
    626   case OMPD_declare_target: {
    627     SourceLocation DTLoc = ConsumeAnyToken();
    628     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    629       // OpenMP 4.5 syntax with list of entities.
    630       llvm::SmallSetVector<const NamedDecl*, 16> SameDirectiveDecls;
    631       while (Tok.isNot(tok::annot_pragma_openmp_end)) {
    632         OMPDeclareTargetDeclAttr::MapTypeTy MT =
    633             OMPDeclareTargetDeclAttr::MT_To;
    634         if (Tok.is(tok::identifier)) {
    635           IdentifierInfo *II = Tok.getIdentifierInfo();
    636           StringRef ClauseName = II->getName();
    637           // Parse 'to|link' clauses.
    638           if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName,
    639                                                                MT)) {
    640             Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
    641                 << ClauseName;
    642             break;
    643           }
    644           ConsumeToken();
    645         }
    646         auto Callback = [this, MT, &SameDirectiveDecls](
    647             CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
    648           Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
    649                                                SameDirectiveDecls);
    650         };
    651         if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, true))
    652           break;
    653 
    654         // Consume optional ','.
    655         if (Tok.is(tok::comma))
    656           ConsumeToken();
    657       }
    658       SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    659       ConsumeAnyToken();
    660       return DeclGroupPtrTy();
    661     }
    662 
    663     // Skip the last annot_pragma_openmp_end.
    664     ConsumeAnyToken();
    665 
    666     if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
    667       return DeclGroupPtrTy();
    668 
    669     DKind = ParseOpenMPDirectiveKind(*this);
    670     while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target &&
    671            Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) {
    672       ParsedAttributesWithRange attrs(AttrFactory);
    673       MaybeParseCXX11Attributes(attrs);
    674       MaybeParseMicrosoftAttributes(attrs);
    675       ParseExternalDeclaration(attrs);
    676       if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
    677         TentativeParsingAction TPA(*this);
    678         ConsumeToken();
    679         DKind = ParseOpenMPDirectiveKind(*this);
    680         if (DKind != OMPD_end_declare_target)
    681           TPA.Revert();
    682         else
    683           TPA.Commit();
    684       }
    685     }
    686 
    687     if (DKind == OMPD_end_declare_target) {
    688       ConsumeAnyToken();
    689       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    690         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    691             << getOpenMPDirectiveName(OMPD_end_declare_target);
    692         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    693       }
    694       // Skip the last annot_pragma_openmp_end.
    695       ConsumeAnyToken();
    696     } else {
    697       Diag(Tok, diag::err_expected_end_declare_target);
    698       Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
    699     }
    700     Actions.ActOnFinishOpenMPDeclareTargetDirective();
    701     return DeclGroupPtrTy();
    702   }
    703   case OMPD_unknown:
    704     Diag(Tok, diag::err_omp_unknown_directive);
    705     break;
    706   case OMPD_parallel:
    707   case OMPD_simd:
    708   case OMPD_task:
    709   case OMPD_taskyield:
    710   case OMPD_barrier:
    711   case OMPD_taskwait:
    712   case OMPD_taskgroup:
    713   case OMPD_flush:
    714   case OMPD_for:
    715   case OMPD_for_simd:
    716   case OMPD_sections:
    717   case OMPD_section:
    718   case OMPD_single:
    719   case OMPD_master:
    720   case OMPD_ordered:
    721   case OMPD_critical:
    722   case OMPD_parallel_for:
    723   case OMPD_parallel_for_simd:
    724   case OMPD_parallel_sections:
    725   case OMPD_atomic:
    726   case OMPD_target:
    727   case OMPD_teams:
    728   case OMPD_cancellation_point:
    729   case OMPD_cancel:
    730   case OMPD_target_data:
    731   case OMPD_target_enter_data:
    732   case OMPD_target_exit_data:
    733   case OMPD_target_parallel:
    734   case OMPD_target_parallel_for:
    735   case OMPD_taskloop:
    736   case OMPD_taskloop_simd:
    737   case OMPD_distribute:
    738   case OMPD_end_declare_target:
    739   case OMPD_target_update:
    740   case OMPD_distribute_parallel_for:
    741   case OMPD_distribute_parallel_for_simd:
    742   case OMPD_distribute_simd:
    743   case OMPD_target_parallel_for_simd:
    744     Diag(Tok, diag::err_omp_unexpected_directive)
    745         << getOpenMPDirectiveName(DKind);
    746     break;
    747   }
    748   while (Tok.isNot(tok::annot_pragma_openmp_end))
    749     ConsumeAnyToken();
    750   ConsumeAnyToken();
    751   return nullptr;
    752 }
    753 
    754 /// \brief Parsing of declarative or executable OpenMP directives.
    755 ///
    756 ///       threadprivate-directive:
    757 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
    758 ///         annot_pragma_openmp_end
    759 ///
    760 ///       declare-reduction-directive:
    761 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
    762 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
    763 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
    764 ///         annot_pragma_openmp_end
    765 ///
    766 ///       executable-directive:
    767 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
    768 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
    769 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
    770 ///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
    771 ///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
    772 ///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
    773 ///         'distribute' | 'target enter data' | 'target exit data' |
    774 ///         'target parallel' | 'target parallel for' |
    775 ///         'target update' | 'distribute parallel for' |
    776 ///         'distribute paralle for simd' | 'distribute simd' |
    777 ///         'target parallel for simd' {clause}
    778 ///         annot_pragma_openmp_end
    779 ///
    780 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
    781     AllowedContsructsKind Allowed) {
    782   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
    783   ParenBraceBracketBalancer BalancerRAIIObj(*this);
    784   SmallVector<OMPClause *, 5> Clauses;
    785   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
    786   FirstClauses(OMPC_unknown + 1);
    787   unsigned ScopeFlags =
    788       Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
    789   SourceLocation Loc = ConsumeToken(), EndLoc;
    790   auto DKind = ParseOpenMPDirectiveKind(*this);
    791   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
    792   // Name of critical directive.
    793   DeclarationNameInfo DirName;
    794   StmtResult Directive = StmtError();
    795   bool HasAssociatedStatement = true;
    796   bool FlushHasClause = false;
    797 
    798   switch (DKind) {
    799   case OMPD_threadprivate: {
    800     if (Allowed != ACK_Any) {
    801       Diag(Tok, diag::err_omp_immediate_directive)
    802           << getOpenMPDirectiveName(DKind) << 0;
    803     }
    804     ConsumeToken();
    805     ThreadprivateListParserHelper Helper(this);
    806     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) {
    807       // The last seen token is annot_pragma_openmp_end - need to check for
    808       // extra tokens.
    809       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    810         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    811             << getOpenMPDirectiveName(OMPD_threadprivate);
    812         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    813       }
    814       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
    815           Loc, Helper.getIdentifiers());
    816       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
    817     }
    818     SkipUntil(tok::annot_pragma_openmp_end);
    819     break;
    820   }
    821   case OMPD_declare_reduction:
    822     ConsumeToken();
    823     if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
    824       // The last seen token is annot_pragma_openmp_end - need to check for
    825       // extra tokens.
    826       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    827         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    828             << getOpenMPDirectiveName(OMPD_declare_reduction);
    829         while (Tok.isNot(tok::annot_pragma_openmp_end))
    830           ConsumeAnyToken();
    831       }
    832       ConsumeAnyToken();
    833       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
    834     } else
    835       SkipUntil(tok::annot_pragma_openmp_end);
    836     break;
    837   case OMPD_flush:
    838     if (PP.LookAhead(0).is(tok::l_paren)) {
    839       FlushHasClause = true;
    840       // Push copy of the current token back to stream to properly parse
    841       // pseudo-clause OMPFlushClause.
    842       PP.EnterToken(Tok);
    843     }
    844   case OMPD_taskyield:
    845   case OMPD_barrier:
    846   case OMPD_taskwait:
    847   case OMPD_cancellation_point:
    848   case OMPD_cancel:
    849   case OMPD_target_enter_data:
    850   case OMPD_target_exit_data:
    851   case OMPD_target_update:
    852     if (Allowed == ACK_StatementsOpenMPNonStandalone) {
    853       Diag(Tok, diag::err_omp_immediate_directive)
    854           << getOpenMPDirectiveName(DKind) << 0;
    855     }
    856     HasAssociatedStatement = false;
    857     // Fall through for further analysis.
    858   case OMPD_parallel:
    859   case OMPD_simd:
    860   case OMPD_for:
    861   case OMPD_for_simd:
    862   case OMPD_sections:
    863   case OMPD_single:
    864   case OMPD_section:
    865   case OMPD_master:
    866   case OMPD_critical:
    867   case OMPD_parallel_for:
    868   case OMPD_parallel_for_simd:
    869   case OMPD_parallel_sections:
    870   case OMPD_task:
    871   case OMPD_ordered:
    872   case OMPD_atomic:
    873   case OMPD_target:
    874   case OMPD_teams:
    875   case OMPD_taskgroup:
    876   case OMPD_target_data:
    877   case OMPD_target_parallel:
    878   case OMPD_target_parallel_for:
    879   case OMPD_taskloop:
    880   case OMPD_taskloop_simd:
    881   case OMPD_distribute:
    882   case OMPD_distribute_parallel_for:
    883   case OMPD_distribute_parallel_for_simd:
    884   case OMPD_distribute_simd:
    885   case OMPD_target_parallel_for_simd: {
    886     ConsumeToken();
    887     // Parse directive name of the 'critical' directive if any.
    888     if (DKind == OMPD_critical) {
    889       BalancedDelimiterTracker T(*this, tok::l_paren,
    890                                  tok::annot_pragma_openmp_end);
    891       if (!T.consumeOpen()) {
    892         if (Tok.isAnyIdentifier()) {
    893           DirName =
    894               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
    895           ConsumeAnyToken();
    896         } else {
    897           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
    898         }
    899         T.consumeClose();
    900       }
    901     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
    902       CancelRegion = ParseOpenMPDirectiveKind(*this);
    903       if (Tok.isNot(tok::annot_pragma_openmp_end))
    904         ConsumeToken();
    905     }
    906 
    907     if (isOpenMPLoopDirective(DKind))
    908       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
    909     if (isOpenMPSimdDirective(DKind))
    910       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
    911     ParseScope OMPDirectiveScope(this, ScopeFlags);
    912     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
    913 
    914     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
    915       OpenMPClauseKind CKind =
    916           Tok.isAnnotation()
    917               ? OMPC_unknown
    918               : FlushHasClause ? OMPC_flush
    919                                : getOpenMPClauseKind(PP.getSpelling(Tok));
    920       Actions.StartOpenMPClause(CKind);
    921       FlushHasClause = false;
    922       OMPClause *Clause =
    923           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
    924       FirstClauses[CKind].setInt(true);
    925       if (Clause) {
    926         FirstClauses[CKind].setPointer(Clause);
    927         Clauses.push_back(Clause);
    928       }
    929 
    930       // Skip ',' if any.
    931       if (Tok.is(tok::comma))
    932         ConsumeToken();
    933       Actions.EndOpenMPClause();
    934     }
    935     // End location of the directive.
    936     EndLoc = Tok.getLocation();
    937     // Consume final annot_pragma_openmp_end.
    938     ConsumeToken();
    939 
    940     // OpenMP [2.13.8, ordered Construct, Syntax]
    941     // If the depend clause is specified, the ordered construct is a stand-alone
    942     // directive.
    943     if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
    944       if (Allowed == ACK_StatementsOpenMPNonStandalone) {
    945         Diag(Loc, diag::err_omp_immediate_directive)
    946             << getOpenMPDirectiveName(DKind) << 1
    947             << getOpenMPClauseName(OMPC_depend);
    948       }
    949       HasAssociatedStatement = false;
    950     }
    951 
    952     StmtResult AssociatedStmt;
    953     if (HasAssociatedStatement) {
    954       // The body is a block scope like in Lambdas and Blocks.
    955       Sema::CompoundScopeRAII CompoundScope(Actions);
    956       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
    957       Actions.ActOnStartOfCompoundStmt();
    958       // Parse statement
    959       AssociatedStmt = ParseStatement();
    960       Actions.ActOnFinishOfCompoundStmt();
    961       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
    962     }
    963     Directive = Actions.ActOnOpenMPExecutableDirective(
    964         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
    965         EndLoc);
    966 
    967     // Exit scope.
    968     Actions.EndOpenMPDSABlock(Directive.get());
    969     OMPDirectiveScope.Exit();
    970     break;
    971   }
    972   case OMPD_declare_simd:
    973   case OMPD_declare_target:
    974   case OMPD_end_declare_target:
    975     Diag(Tok, diag::err_omp_unexpected_directive)
    976         << getOpenMPDirectiveName(DKind);
    977     SkipUntil(tok::annot_pragma_openmp_end);
    978     break;
    979   case OMPD_unknown:
    980     Diag(Tok, diag::err_omp_unknown_directive);
    981     SkipUntil(tok::annot_pragma_openmp_end);
    982     break;
    983   }
    984   return Directive;
    985 }
    986 
    987 // Parses simple list:
    988 //   simple-variable-list:
    989 //         '(' id-expression {, id-expression} ')'
    990 //
    991 bool Parser::ParseOpenMPSimpleVarList(
    992     OpenMPDirectiveKind Kind,
    993     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
    994         Callback,
    995     bool AllowScopeSpecifier) {
    996   // Parse '('.
    997   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
    998   if (T.expectAndConsume(diag::err_expected_lparen_after,
    999                          getOpenMPDirectiveName(Kind)))
   1000     return true;
   1001   bool IsCorrect = true;
   1002   bool NoIdentIsFound = true;
   1003 
   1004   // Read tokens while ')' or annot_pragma_openmp_end is not found.
   1005   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
   1006     CXXScopeSpec SS;
   1007     SourceLocation TemplateKWLoc;
   1008     UnqualifiedId Name;
   1009     // Read var name.
   1010     Token PrevTok = Tok;
   1011     NoIdentIsFound = false;
   1012 
   1013     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
   1014         ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
   1015       IsCorrect = false;
   1016       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
   1017                 StopBeforeMatch);
   1018     } else if (ParseUnqualifiedId(SS, false, false, false, nullptr,
   1019                                   TemplateKWLoc, Name)) {
   1020       IsCorrect = false;
   1021       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
   1022                 StopBeforeMatch);
   1023     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
   1024                Tok.isNot(tok::annot_pragma_openmp_end)) {
   1025       IsCorrect = false;
   1026       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
   1027                 StopBeforeMatch);
   1028       Diag(PrevTok.getLocation(), diag::err_expected)
   1029           << tok::identifier
   1030           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
   1031     } else {
   1032       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
   1033     }
   1034     // Consume ','.
   1035     if (Tok.is(tok::comma)) {
   1036       ConsumeToken();
   1037     }
   1038   }
   1039 
   1040   if (NoIdentIsFound) {
   1041     Diag(Tok, diag::err_expected) << tok::identifier;
   1042     IsCorrect = false;
   1043   }
   1044 
   1045   // Parse ')'.
   1046   IsCorrect = !T.consumeClose() && IsCorrect;
   1047 
   1048   return !IsCorrect;
   1049 }
   1050 
   1051 /// \brief Parsing of OpenMP clauses.
   1052 ///
   1053 ///    clause:
   1054 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
   1055 ///       default-clause | private-clause | firstprivate-clause | shared-clause
   1056 ///       | linear-clause | aligned-clause | collapse-clause |
   1057 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
   1058 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
   1059 ///       mergeable-clause | flush-clause | read-clause | write-clause |
   1060 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
   1061 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
   1062 ///       thread_limit-clause | priority-clause | grainsize-clause |
   1063 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
   1064 ///       from-clause | is_device_ptr-clause
   1065 ///
   1066 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
   1067                                      OpenMPClauseKind CKind, bool FirstClause) {
   1068   OMPClause *Clause = nullptr;
   1069   bool ErrorFound = false;
   1070   // Check if clause is allowed for the given directive.
   1071   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
   1072     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
   1073                                                << getOpenMPDirectiveName(DKind);
   1074     ErrorFound = true;
   1075   }
   1076 
   1077   switch (CKind) {
   1078   case OMPC_final:
   1079   case OMPC_num_threads:
   1080   case OMPC_safelen:
   1081   case OMPC_simdlen:
   1082   case OMPC_collapse:
   1083   case OMPC_ordered:
   1084   case OMPC_device:
   1085   case OMPC_num_teams:
   1086   case OMPC_thread_limit:
   1087   case OMPC_priority:
   1088   case OMPC_grainsize:
   1089   case OMPC_num_tasks:
   1090   case OMPC_hint:
   1091     // OpenMP [2.5, Restrictions]
   1092     //  At most one num_threads clause can appear on the directive.
   1093     // OpenMP [2.8.1, simd construct, Restrictions]
   1094     //  Only one safelen  clause can appear on a simd directive.
   1095     //  Only one simdlen  clause can appear on a simd directive.
   1096     //  Only one collapse clause can appear on a simd directive.
   1097     // OpenMP [2.9.1, target data construct, Restrictions]
   1098     //  At most one device clause can appear on the directive.
   1099     // OpenMP [2.11.1, task Construct, Restrictions]
   1100     //  At most one if clause can appear on the directive.
   1101     //  At most one final clause can appear on the directive.
   1102     // OpenMP [teams Construct, Restrictions]
   1103     //  At most one num_teams clause can appear on the directive.
   1104     //  At most one thread_limit clause can appear on the directive.
   1105     // OpenMP [2.9.1, task Construct, Restrictions]
   1106     // At most one priority clause can appear on the directive.
   1107     // OpenMP [2.9.2, taskloop Construct, Restrictions]
   1108     // At most one grainsize clause can appear on the directive.
   1109     // OpenMP [2.9.2, taskloop Construct, Restrictions]
   1110     // At most one num_tasks clause can appear on the directive.
   1111     if (!FirstClause) {
   1112       Diag(Tok, diag::err_omp_more_one_clause)
   1113           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
   1114       ErrorFound = true;
   1115     }
   1116 
   1117     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
   1118       Clause = ParseOpenMPClause(CKind);
   1119     else
   1120       Clause = ParseOpenMPSingleExprClause(CKind);
   1121     break;
   1122   case OMPC_default:
   1123   case OMPC_proc_bind:
   1124     // OpenMP [2.14.3.1, Restrictions]
   1125     //  Only a single default clause may be specified on a parallel, task or
   1126     //  teams directive.
   1127     // OpenMP [2.5, parallel Construct, Restrictions]
   1128     //  At most one proc_bind clause can appear on the directive.
   1129     if (!FirstClause) {
   1130       Diag(Tok, diag::err_omp_more_one_clause)
   1131           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
   1132       ErrorFound = true;
   1133     }
   1134 
   1135     Clause = ParseOpenMPSimpleClause(CKind);
   1136     break;
   1137   case OMPC_schedule:
   1138   case OMPC_dist_schedule:
   1139   case OMPC_defaultmap:
   1140     // OpenMP [2.7.1, Restrictions, p. 3]
   1141     //  Only one schedule clause can appear on a loop directive.
   1142     // OpenMP [2.10.4, Restrictions, p. 106]
   1143     //  At most one defaultmap clause can appear on the directive.
   1144     if (!FirstClause) {
   1145       Diag(Tok, diag::err_omp_more_one_clause)
   1146           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
   1147       ErrorFound = true;
   1148     }
   1149 
   1150   case OMPC_if:
   1151     Clause = ParseOpenMPSingleExprWithArgClause(CKind);
   1152     break;
   1153   case OMPC_nowait:
   1154   case OMPC_untied:
   1155   case OMPC_mergeable:
   1156   case OMPC_read:
   1157   case OMPC_write:
   1158   case OMPC_update:
   1159   case OMPC_capture:
   1160   case OMPC_seq_cst:
   1161   case OMPC_threads:
   1162   case OMPC_simd:
   1163   case OMPC_nogroup:
   1164     // OpenMP [2.7.1, Restrictions, p. 9]
   1165     //  Only one ordered clause can appear on a loop directive.
   1166     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
   1167     //  Only one nowait clause can appear on a for directive.
   1168     if (!FirstClause) {
   1169       Diag(Tok, diag::err_omp_more_one_clause)
   1170           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
   1171       ErrorFound = true;
   1172     }
   1173 
   1174     Clause = ParseOpenMPClause(CKind);
   1175     break;
   1176   case OMPC_private:
   1177   case OMPC_firstprivate:
   1178   case OMPC_lastprivate:
   1179   case OMPC_shared:
   1180   case OMPC_reduction:
   1181   case OMPC_linear:
   1182   case OMPC_aligned:
   1183   case OMPC_copyin:
   1184   case OMPC_copyprivate:
   1185   case OMPC_flush:
   1186   case OMPC_depend:
   1187   case OMPC_map:
   1188   case OMPC_to:
   1189   case OMPC_from:
   1190   case OMPC_use_device_ptr:
   1191   case OMPC_is_device_ptr:
   1192     Clause = ParseOpenMPVarListClause(DKind, CKind);
   1193     break;
   1194   case OMPC_unknown:
   1195     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
   1196         << getOpenMPDirectiveName(DKind);
   1197     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
   1198     break;
   1199   case OMPC_threadprivate:
   1200   case OMPC_uniform:
   1201     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
   1202                                                << getOpenMPDirectiveName(DKind);
   1203     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
   1204     break;
   1205   }
   1206   return ErrorFound ? nullptr : Clause;
   1207 }
   1208 
   1209 /// Parses simple expression in parens for single-expression clauses of OpenMP
   1210 /// constructs.
   1211 /// \param RLoc Returned location of right paren.
   1212 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
   1213                                          SourceLocation &RLoc) {
   1214   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   1215   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
   1216     return ExprError();
   1217 
   1218   SourceLocation ELoc = Tok.getLocation();
   1219   ExprResult LHS(ParseCastExpression(
   1220       /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
   1221   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
   1222   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
   1223 
   1224   // Parse ')'.
   1225   T.consumeClose();
   1226 
   1227   RLoc = T.getCloseLocation();
   1228   return Val;
   1229 }
   1230 
   1231 /// \brief Parsing of OpenMP clauses with single expressions like 'final',
   1232 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
   1233 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
   1234 ///
   1235 ///    final-clause:
   1236 ///      'final' '(' expression ')'
   1237 ///
   1238 ///    num_threads-clause:
   1239 ///      'num_threads' '(' expression ')'
   1240 ///
   1241 ///    safelen-clause:
   1242 ///      'safelen' '(' expression ')'
   1243 ///
   1244 ///    simdlen-clause:
   1245 ///      'simdlen' '(' expression ')'
   1246 ///
   1247 ///    collapse-clause:
   1248 ///      'collapse' '(' expression ')'
   1249 ///
   1250 ///    priority-clause:
   1251 ///      'priority' '(' expression ')'
   1252 ///
   1253 ///    grainsize-clause:
   1254 ///      'grainsize' '(' expression ')'
   1255 ///
   1256 ///    num_tasks-clause:
   1257 ///      'num_tasks' '(' expression ')'
   1258 ///
   1259 ///    hint-clause:
   1260 ///      'hint' '(' expression ')'
   1261 ///
   1262 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
   1263   SourceLocation Loc = ConsumeToken();
   1264   SourceLocation LLoc = Tok.getLocation();
   1265   SourceLocation RLoc;
   1266 
   1267   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
   1268 
   1269   if (Val.isInvalid())
   1270     return nullptr;
   1271 
   1272   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
   1273 }
   1274 
   1275 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
   1276 ///
   1277 ///    default-clause:
   1278 ///         'default' '(' 'none' | 'shared' ')
   1279 ///
   1280 ///    proc_bind-clause:
   1281 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
   1282 ///
   1283 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
   1284   SourceLocation Loc = Tok.getLocation();
   1285   SourceLocation LOpen = ConsumeToken();
   1286   // Parse '('.
   1287   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   1288   if (T.expectAndConsume(diag::err_expected_lparen_after,
   1289                          getOpenMPClauseName(Kind)))
   1290     return nullptr;
   1291 
   1292   unsigned Type = getOpenMPSimpleClauseType(
   1293       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
   1294   SourceLocation TypeLoc = Tok.getLocation();
   1295   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
   1296       Tok.isNot(tok::annot_pragma_openmp_end))
   1297     ConsumeAnyToken();
   1298 
   1299   // Parse ')'.
   1300   T.consumeClose();
   1301 
   1302   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
   1303                                          Tok.getLocation());
   1304 }
   1305 
   1306 /// \brief Parsing of OpenMP clauses like 'ordered'.
   1307 ///
   1308 ///    ordered-clause:
   1309 ///         'ordered'
   1310 ///
   1311 ///    nowait-clause:
   1312 ///         'nowait'
   1313 ///
   1314 ///    untied-clause:
   1315 ///         'untied'
   1316 ///
   1317 ///    mergeable-clause:
   1318 ///         'mergeable'
   1319 ///
   1320 ///    read-clause:
   1321 ///         'read'
   1322 ///
   1323 ///    threads-clause:
   1324 ///         'threads'
   1325 ///
   1326 ///    simd-clause:
   1327 ///         'simd'
   1328 ///
   1329 ///    nogroup-clause:
   1330 ///         'nogroup'
   1331 ///
   1332 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
   1333   SourceLocation Loc = Tok.getLocation();
   1334   ConsumeAnyToken();
   1335 
   1336   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
   1337 }
   1338 
   1339 
   1340 /// \brief Parsing of OpenMP clauses with single expressions and some additional
   1341 /// argument like 'schedule' or 'dist_schedule'.
   1342 ///
   1343 ///    schedule-clause:
   1344 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
   1345 ///      ')'
   1346 ///
   1347 ///    if-clause:
   1348 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
   1349 ///
   1350 ///    defaultmap:
   1351 ///      'defaultmap' '(' modifier ':' kind ')'
   1352 ///
   1353 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
   1354   SourceLocation Loc = ConsumeToken();
   1355   SourceLocation DelimLoc;
   1356   // Parse '('.
   1357   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   1358   if (T.expectAndConsume(diag::err_expected_lparen_after,
   1359                          getOpenMPClauseName(Kind)))
   1360     return nullptr;
   1361 
   1362   ExprResult Val;
   1363   SmallVector<unsigned, 4> Arg;
   1364   SmallVector<SourceLocation, 4> KLoc;
   1365   if (Kind == OMPC_schedule) {
   1366     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
   1367     Arg.resize(NumberOfElements);
   1368     KLoc.resize(NumberOfElements);
   1369     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
   1370     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
   1371     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
   1372     auto KindModifier = getOpenMPSimpleClauseType(
   1373         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
   1374     if (KindModifier > OMPC_SCHEDULE_unknown) {
   1375       // Parse 'modifier'
   1376       Arg[Modifier1] = KindModifier;
   1377       KLoc[Modifier1] = Tok.getLocation();
   1378       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
   1379           Tok.isNot(tok::annot_pragma_openmp_end))
   1380         ConsumeAnyToken();
   1381       if (Tok.is(tok::comma)) {
   1382         // Parse ',' 'modifier'
   1383         ConsumeAnyToken();
   1384         KindModifier = getOpenMPSimpleClauseType(
   1385             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
   1386         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
   1387                              ? KindModifier
   1388                              : (unsigned)OMPC_SCHEDULE_unknown;
   1389         KLoc[Modifier2] = Tok.getLocation();
   1390         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
   1391             Tok.isNot(tok::annot_pragma_openmp_end))
   1392           ConsumeAnyToken();
   1393       }
   1394       // Parse ':'
   1395       if (Tok.is(tok::colon))
   1396         ConsumeAnyToken();
   1397       else
   1398         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
   1399       KindModifier = getOpenMPSimpleClauseType(
   1400           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
   1401     }
   1402     Arg[ScheduleKind] = KindModifier;
   1403     KLoc[ScheduleKind] = Tok.getLocation();
   1404     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
   1405         Tok.isNot(tok::annot_pragma_openmp_end))
   1406       ConsumeAnyToken();
   1407     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
   1408          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
   1409          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
   1410         Tok.is(tok::comma))
   1411       DelimLoc = ConsumeAnyToken();
   1412   } else if (Kind == OMPC_dist_schedule) {
   1413     Arg.push_back(getOpenMPSimpleClauseType(
   1414         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
   1415     KLoc.push_back(Tok.getLocation());
   1416     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
   1417         Tok.isNot(tok::annot_pragma_openmp_end))
   1418       ConsumeAnyToken();
   1419     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
   1420       DelimLoc = ConsumeAnyToken();
   1421   } else if (Kind == OMPC_defaultmap) {
   1422     // Get a defaultmap modifier
   1423     Arg.push_back(getOpenMPSimpleClauseType(
   1424         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
   1425     KLoc.push_back(Tok.getLocation());
   1426     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
   1427         Tok.isNot(tok::annot_pragma_openmp_end))
   1428       ConsumeAnyToken();
   1429     // Parse ':'
   1430     if (Tok.is(tok::colon))
   1431       ConsumeAnyToken();
   1432     else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
   1433       Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
   1434     // Get a defaultmap kind
   1435     Arg.push_back(getOpenMPSimpleClauseType(
   1436         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
   1437     KLoc.push_back(Tok.getLocation());
   1438     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
   1439         Tok.isNot(tok::annot_pragma_openmp_end))
   1440       ConsumeAnyToken();
   1441   } else {
   1442     assert(Kind == OMPC_if);
   1443     KLoc.push_back(Tok.getLocation());
   1444     Arg.push_back(ParseOpenMPDirectiveKind(*this));
   1445     if (Arg.back() != OMPD_unknown) {
   1446       ConsumeToken();
   1447       if (Tok.is(tok::colon))
   1448         DelimLoc = ConsumeToken();
   1449       else
   1450         Diag(Tok, diag::warn_pragma_expected_colon)
   1451             << "directive name modifier";
   1452     }
   1453   }
   1454 
   1455   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
   1456                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
   1457                           Kind == OMPC_if;
   1458   if (NeedAnExpression) {
   1459     SourceLocation ELoc = Tok.getLocation();
   1460     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
   1461     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
   1462     Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
   1463   }
   1464 
   1465   // Parse ')'.
   1466   T.consumeClose();
   1467 
   1468   if (NeedAnExpression && Val.isInvalid())
   1469     return nullptr;
   1470 
   1471   return Actions.ActOnOpenMPSingleExprWithArgClause(
   1472       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
   1473       T.getCloseLocation());
   1474 }
   1475 
   1476 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
   1477                              UnqualifiedId &ReductionId) {
   1478   SourceLocation TemplateKWLoc;
   1479   if (ReductionIdScopeSpec.isEmpty()) {
   1480     auto OOK = OO_None;
   1481     switch (P.getCurToken().getKind()) {
   1482     case tok::plus:
   1483       OOK = OO_Plus;
   1484       break;
   1485     case tok::minus:
   1486       OOK = OO_Minus;
   1487       break;
   1488     case tok::star:
   1489       OOK = OO_Star;
   1490       break;
   1491     case tok::amp:
   1492       OOK = OO_Amp;
   1493       break;
   1494     case tok::pipe:
   1495       OOK = OO_Pipe;
   1496       break;
   1497     case tok::caret:
   1498       OOK = OO_Caret;
   1499       break;
   1500     case tok::ampamp:
   1501       OOK = OO_AmpAmp;
   1502       break;
   1503     case tok::pipepipe:
   1504       OOK = OO_PipePipe;
   1505       break;
   1506     default:
   1507       break;
   1508     }
   1509     if (OOK != OO_None) {
   1510       SourceLocation OpLoc = P.ConsumeToken();
   1511       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
   1512       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
   1513       return false;
   1514     }
   1515   }
   1516   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
   1517                               /*AllowDestructorName*/ false,
   1518                               /*AllowConstructorName*/ false, nullptr,
   1519                               TemplateKWLoc, ReductionId);
   1520 }
   1521 
   1522 /// Parses clauses with list.
   1523 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
   1524                                 OpenMPClauseKind Kind,
   1525                                 SmallVectorImpl<Expr *> &Vars,
   1526                                 OpenMPVarListDataTy &Data) {
   1527   UnqualifiedId UnqualifiedReductionId;
   1528   bool InvalidReductionId = false;
   1529   bool MapTypeModifierSpecified = false;
   1530 
   1531   // Parse '('.
   1532   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   1533   if (T.expectAndConsume(diag::err_expected_lparen_after,
   1534                          getOpenMPClauseName(Kind)))
   1535     return true;
   1536 
   1537   bool NeedRParenForLinear = false;
   1538   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
   1539                                   tok::annot_pragma_openmp_end);
   1540   // Handle reduction-identifier for reduction clause.
   1541   if (Kind == OMPC_reduction) {
   1542     ColonProtectionRAIIObject ColonRAII(*this);
   1543     if (getLangOpts().CPlusPlus)
   1544       ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec,
   1545                                      /*ObjectType=*/nullptr,
   1546                                      /*EnteringContext=*/false);
   1547     InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec,
   1548                                           UnqualifiedReductionId);
   1549     if (InvalidReductionId) {
   1550       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
   1551                 StopBeforeMatch);
   1552     }
   1553     if (Tok.is(tok::colon))
   1554       Data.ColonLoc = ConsumeToken();
   1555     else
   1556       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
   1557     if (!InvalidReductionId)
   1558       Data.ReductionId =
   1559           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
   1560   } else if (Kind == OMPC_depend) {
   1561   // Handle dependency type for depend clause.
   1562     ColonProtectionRAIIObject ColonRAII(*this);
   1563     Data.DepKind =
   1564         static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
   1565             Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
   1566     Data.DepLinMapLoc = Tok.getLocation();
   1567 
   1568     if (Data.DepKind == OMPC_DEPEND_unknown) {
   1569       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
   1570                 StopBeforeMatch);
   1571     } else {
   1572       ConsumeToken();
   1573       // Special processing for depend(source) clause.
   1574       if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
   1575         // Parse ')'.
   1576         T.consumeClose();
   1577         return false;
   1578       }
   1579     }
   1580     if (Tok.is(tok::colon))
   1581       Data.ColonLoc = ConsumeToken();
   1582     else {
   1583       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
   1584                                       : diag::warn_pragma_expected_colon)
   1585           << "dependency type";
   1586     }
   1587   } else if (Kind == OMPC_linear) {
   1588     // Try to parse modifier if any.
   1589     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
   1590       Data.LinKind = static_cast<OpenMPLinearClauseKind>(
   1591           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
   1592       Data.DepLinMapLoc = ConsumeToken();
   1593       LinearT.consumeOpen();
   1594       NeedRParenForLinear = true;
   1595     }
   1596   } else if (Kind == OMPC_map) {
   1597     // Handle map type for map clause.
   1598     ColonProtectionRAIIObject ColonRAII(*this);
   1599 
   1600     /// The map clause modifier token can be either a identifier or the C++
   1601     /// delete keyword.
   1602     auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool {
   1603       return Tok.isOneOf(tok::identifier, tok::kw_delete);
   1604     };
   1605 
   1606     // The first identifier may be a list item, a map-type or a
   1607     // map-type-modifier. The map modifier can also be delete which has the same
   1608     // spelling of the C++ delete keyword.
   1609     Data.MapType =
   1610         IsMapClauseModifierToken(Tok)
   1611             ? static_cast<OpenMPMapClauseKind>(
   1612                   getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
   1613             : OMPC_MAP_unknown;
   1614     Data.DepLinMapLoc = Tok.getLocation();
   1615     bool ColonExpected = false;
   1616 
   1617     if (IsMapClauseModifierToken(Tok)) {
   1618       if (PP.LookAhead(0).is(tok::colon)) {
   1619         if (Data.MapType == OMPC_MAP_unknown)
   1620           Diag(Tok, diag::err_omp_unknown_map_type);
   1621         else if (Data.MapType == OMPC_MAP_always)
   1622           Diag(Tok, diag::err_omp_map_type_missing);
   1623         ConsumeToken();
   1624       } else if (PP.LookAhead(0).is(tok::comma)) {
   1625         if (IsMapClauseModifierToken(PP.LookAhead(1)) &&
   1626             PP.LookAhead(2).is(tok::colon)) {
   1627           Data.MapTypeModifier = Data.MapType;
   1628           if (Data.MapTypeModifier != OMPC_MAP_always) {
   1629             Diag(Tok, diag::err_omp_unknown_map_type_modifier);
   1630             Data.MapTypeModifier = OMPC_MAP_unknown;
   1631           } else
   1632             MapTypeModifierSpecified = true;
   1633 
   1634           ConsumeToken();
   1635           ConsumeToken();
   1636 
   1637           Data.MapType =
   1638               IsMapClauseModifierToken(Tok)
   1639                   ? static_cast<OpenMPMapClauseKind>(
   1640                         getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
   1641                   : OMPC_MAP_unknown;
   1642           if (Data.MapType == OMPC_MAP_unknown ||
   1643               Data.MapType == OMPC_MAP_always)
   1644             Diag(Tok, diag::err_omp_unknown_map_type);
   1645           ConsumeToken();
   1646         } else {
   1647           Data.MapType = OMPC_MAP_tofrom;
   1648           Data.IsMapTypeImplicit = true;
   1649         }
   1650       } else {
   1651         Data.MapType = OMPC_MAP_tofrom;
   1652         Data.IsMapTypeImplicit = true;
   1653       }
   1654     } else {
   1655       Data.MapType = OMPC_MAP_tofrom;
   1656       Data.IsMapTypeImplicit = true;
   1657     }
   1658 
   1659     if (Tok.is(tok::colon))
   1660       Data.ColonLoc = ConsumeToken();
   1661     else if (ColonExpected)
   1662       Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
   1663   }
   1664 
   1665   bool IsComma =
   1666       (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
   1667       (Kind == OMPC_reduction && !InvalidReductionId) ||
   1668       (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown &&
   1669        (!MapTypeModifierSpecified ||
   1670         Data.MapTypeModifier == OMPC_MAP_always)) ||
   1671       (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
   1672   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
   1673   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
   1674                      Tok.isNot(tok::annot_pragma_openmp_end))) {
   1675     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
   1676     // Parse variable
   1677     ExprResult VarExpr =
   1678         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
   1679     if (VarExpr.isUsable())
   1680       Vars.push_back(VarExpr.get());
   1681     else {
   1682       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
   1683                 StopBeforeMatch);
   1684     }
   1685     // Skip ',' if any
   1686     IsComma = Tok.is(tok::comma);
   1687     if (IsComma)
   1688       ConsumeToken();
   1689     else if (Tok.isNot(tok::r_paren) &&
   1690              Tok.isNot(tok::annot_pragma_openmp_end) &&
   1691              (!MayHaveTail || Tok.isNot(tok::colon)))
   1692       Diag(Tok, diag::err_omp_expected_punc)
   1693           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
   1694                                    : getOpenMPClauseName(Kind))
   1695           << (Kind == OMPC_flush);
   1696   }
   1697 
   1698   // Parse ')' for linear clause with modifier.
   1699   if (NeedRParenForLinear)
   1700     LinearT.consumeClose();
   1701 
   1702   // Parse ':' linear-step (or ':' alignment).
   1703   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
   1704   if (MustHaveTail) {
   1705     Data.ColonLoc = Tok.getLocation();
   1706     SourceLocation ELoc = ConsumeToken();
   1707     ExprResult Tail = ParseAssignmentExpression();
   1708     Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
   1709     if (Tail.isUsable())
   1710       Data.TailExpr = Tail.get();
   1711     else
   1712       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
   1713                 StopBeforeMatch);
   1714   }
   1715 
   1716   // Parse ')'.
   1717   T.consumeClose();
   1718   if ((Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
   1719        Vars.empty()) ||
   1720       (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
   1721       (MustHaveTail && !Data.TailExpr) || InvalidReductionId)
   1722     return true;
   1723   return false;
   1724 }
   1725 
   1726 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
   1727 /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
   1728 ///
   1729 ///    private-clause:
   1730 ///       'private' '(' list ')'
   1731 ///    firstprivate-clause:
   1732 ///       'firstprivate' '(' list ')'
   1733 ///    lastprivate-clause:
   1734 ///       'lastprivate' '(' list ')'
   1735 ///    shared-clause:
   1736 ///       'shared' '(' list ')'
   1737 ///    linear-clause:
   1738 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
   1739 ///    aligned-clause:
   1740 ///       'aligned' '(' list [ ':' alignment ] ')'
   1741 ///    reduction-clause:
   1742 ///       'reduction' '(' reduction-identifier ':' list ')'
   1743 ///    copyprivate-clause:
   1744 ///       'copyprivate' '(' list ')'
   1745 ///    flush-clause:
   1746 ///       'flush' '(' list ')'
   1747 ///    depend-clause:
   1748 ///       'depend' '(' in | out | inout : list | source ')'
   1749 ///    map-clause:
   1750 ///       'map' '(' [ [ always , ]
   1751 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
   1752 ///    to-clause:
   1753 ///       'to' '(' list ')'
   1754 ///    from-clause:
   1755 ///       'from' '(' list ')'
   1756 ///    use_device_ptr-clause:
   1757 ///       'use_device_ptr' '(' list ')'
   1758 ///    is_device_ptr-clause:
   1759 ///       'is_device_ptr' '(' list ')'
   1760 ///
   1761 /// For 'linear' clause linear-list may have the following forms:
   1762 ///  list
   1763 ///  modifier(list)
   1764 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
   1765 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
   1766                                             OpenMPClauseKind Kind) {
   1767   SourceLocation Loc = Tok.getLocation();
   1768   SourceLocation LOpen = ConsumeToken();
   1769   SmallVector<Expr *, 4> Vars;
   1770   OpenMPVarListDataTy Data;
   1771 
   1772   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
   1773     return nullptr;
   1774 
   1775   return Actions.ActOnOpenMPVarListClause(
   1776       Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Tok.getLocation(),
   1777       Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind,
   1778       Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit,
   1779       Data.DepLinMapLoc);
   1780 }
   1781 
   1782