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 static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
     30   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
     31   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
     32   // TODO: add other combined directives in topological order.
     33   const OpenMPDirectiveKind F[][3] = {
     34       {OMPD_unknown /*cancellation*/, OMPD_unknown /*point*/,
     35        OMPD_cancellation_point},
     36       {OMPD_target, OMPD_unknown /*data*/, OMPD_target_data},
     37       {OMPD_for, OMPD_simd, OMPD_for_simd},
     38       {OMPD_parallel, OMPD_for, OMPD_parallel_for},
     39       {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
     40       {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
     41       {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd}};
     42   auto Tok = P.getCurToken();
     43   auto DKind =
     44       Tok.isAnnotation()
     45           ? OMPD_unknown
     46           : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
     47 
     48   bool TokenMatched = false;
     49   for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
     50     if (!Tok.isAnnotation() && DKind == OMPD_unknown) {
     51       TokenMatched =
     52           (i == 0) &&
     53           !P.getPreprocessor().getSpelling(Tok).compare("cancellation");
     54     } else {
     55       TokenMatched = DKind == F[i][0] && DKind != OMPD_unknown;
     56     }
     57 
     58     if (TokenMatched) {
     59       Tok = P.getPreprocessor().LookAhead(0);
     60       auto TokenIsAnnotation = Tok.isAnnotation();
     61       auto SDKind =
     62           TokenIsAnnotation
     63               ? OMPD_unknown
     64               : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
     65 
     66       if (!TokenIsAnnotation && SDKind == OMPD_unknown) {
     67         TokenMatched =
     68             ((i == 0) &&
     69              !P.getPreprocessor().getSpelling(Tok).compare("point")) ||
     70             ((i == 1) && !P.getPreprocessor().getSpelling(Tok).compare("data"));
     71       } else {
     72         TokenMatched = SDKind == F[i][1] && SDKind != OMPD_unknown;
     73       }
     74 
     75       if (TokenMatched) {
     76         P.ConsumeToken();
     77         DKind = F[i][2];
     78       }
     79     }
     80   }
     81   return DKind;
     82 }
     83 
     84 /// \brief Parsing of declarative OpenMP directives.
     85 ///
     86 ///       threadprivate-directive:
     87 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
     88 ///
     89 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
     90   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
     91   ParenBraceBracketBalancer BalancerRAIIObj(*this);
     92 
     93   SourceLocation Loc = ConsumeToken();
     94   SmallVector<Expr *, 5> Identifiers;
     95   auto DKind = ParseOpenMPDirectiveKind(*this);
     96 
     97   switch (DKind) {
     98   case OMPD_threadprivate:
     99     ConsumeToken();
    100     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) {
    101       // The last seen token is annot_pragma_openmp_end - need to check for
    102       // extra tokens.
    103       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    104         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    105             << getOpenMPDirectiveName(OMPD_threadprivate);
    106         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    107       }
    108       // Skip the last annot_pragma_openmp_end.
    109       ConsumeToken();
    110       return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
    111     }
    112     break;
    113   case OMPD_unknown:
    114     Diag(Tok, diag::err_omp_unknown_directive);
    115     break;
    116   case OMPD_parallel:
    117   case OMPD_simd:
    118   case OMPD_task:
    119   case OMPD_taskyield:
    120   case OMPD_barrier:
    121   case OMPD_taskwait:
    122   case OMPD_taskgroup:
    123   case OMPD_flush:
    124   case OMPD_for:
    125   case OMPD_for_simd:
    126   case OMPD_sections:
    127   case OMPD_section:
    128   case OMPD_single:
    129   case OMPD_master:
    130   case OMPD_ordered:
    131   case OMPD_critical:
    132   case OMPD_parallel_for:
    133   case OMPD_parallel_for_simd:
    134   case OMPD_parallel_sections:
    135   case OMPD_atomic:
    136   case OMPD_target:
    137   case OMPD_teams:
    138   case OMPD_cancellation_point:
    139   case OMPD_cancel:
    140   case OMPD_target_data:
    141   case OMPD_taskloop:
    142   case OMPD_taskloop_simd:
    143   case OMPD_distribute:
    144     Diag(Tok, diag::err_omp_unexpected_directive)
    145         << getOpenMPDirectiveName(DKind);
    146     break;
    147   }
    148   SkipUntil(tok::annot_pragma_openmp_end);
    149   return DeclGroupPtrTy();
    150 }
    151 
    152 /// \brief Parsing of declarative or executable OpenMP directives.
    153 ///
    154 ///       threadprivate-directive:
    155 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
    156 ///         annot_pragma_openmp_end
    157 ///
    158 ///       executable-directive:
    159 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
    160 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
    161 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
    162 ///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
    163 ///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
    164 ///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' {clause} |
    165 ///         'distribute'
    166 ///         annot_pragma_openmp_end
    167 ///
    168 StmtResult
    169 Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
    170   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
    171   ParenBraceBracketBalancer BalancerRAIIObj(*this);
    172   SmallVector<Expr *, 5> Identifiers;
    173   SmallVector<OMPClause *, 5> Clauses;
    174   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
    175   FirstClauses(OMPC_unknown + 1);
    176   unsigned ScopeFlags =
    177       Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
    178   SourceLocation Loc = ConsumeToken(), EndLoc;
    179   auto DKind = ParseOpenMPDirectiveKind(*this);
    180   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
    181   // Name of critical directive.
    182   DeclarationNameInfo DirName;
    183   StmtResult Directive = StmtError();
    184   bool HasAssociatedStatement = true;
    185   bool FlushHasClause = false;
    186 
    187   switch (DKind) {
    188   case OMPD_threadprivate:
    189     ConsumeToken();
    190     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
    191       // The last seen token is annot_pragma_openmp_end - need to check for
    192       // extra tokens.
    193       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
    194         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    195             << getOpenMPDirectiveName(OMPD_threadprivate);
    196         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    197       }
    198       DeclGroupPtrTy Res =
    199           Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
    200       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
    201     }
    202     SkipUntil(tok::annot_pragma_openmp_end);
    203     break;
    204   case OMPD_flush:
    205     if (PP.LookAhead(0).is(tok::l_paren)) {
    206       FlushHasClause = true;
    207       // Push copy of the current token back to stream to properly parse
    208       // pseudo-clause OMPFlushClause.
    209       PP.EnterToken(Tok);
    210     }
    211   case OMPD_taskyield:
    212   case OMPD_barrier:
    213   case OMPD_taskwait:
    214   case OMPD_cancellation_point:
    215   case OMPD_cancel:
    216     if (!StandAloneAllowed) {
    217       Diag(Tok, diag::err_omp_immediate_directive)
    218           << getOpenMPDirectiveName(DKind) << 0;
    219     }
    220     HasAssociatedStatement = false;
    221     // Fall through for further analysis.
    222   case OMPD_parallel:
    223   case OMPD_simd:
    224   case OMPD_for:
    225   case OMPD_for_simd:
    226   case OMPD_sections:
    227   case OMPD_single:
    228   case OMPD_section:
    229   case OMPD_master:
    230   case OMPD_critical:
    231   case OMPD_parallel_for:
    232   case OMPD_parallel_for_simd:
    233   case OMPD_parallel_sections:
    234   case OMPD_task:
    235   case OMPD_ordered:
    236   case OMPD_atomic:
    237   case OMPD_target:
    238   case OMPD_teams:
    239   case OMPD_taskgroup:
    240   case OMPD_target_data:
    241   case OMPD_taskloop:
    242   case OMPD_taskloop_simd:
    243   case OMPD_distribute: {
    244     ConsumeToken();
    245     // Parse directive name of the 'critical' directive if any.
    246     if (DKind == OMPD_critical) {
    247       BalancedDelimiterTracker T(*this, tok::l_paren,
    248                                  tok::annot_pragma_openmp_end);
    249       if (!T.consumeOpen()) {
    250         if (Tok.isAnyIdentifier()) {
    251           DirName =
    252               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
    253           ConsumeAnyToken();
    254         } else {
    255           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
    256         }
    257         T.consumeClose();
    258       }
    259     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
    260       CancelRegion = ParseOpenMPDirectiveKind(*this);
    261       if (Tok.isNot(tok::annot_pragma_openmp_end))
    262         ConsumeToken();
    263     }
    264 
    265     if (isOpenMPLoopDirective(DKind))
    266       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
    267     if (isOpenMPSimdDirective(DKind))
    268       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
    269     ParseScope OMPDirectiveScope(this, ScopeFlags);
    270     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
    271 
    272     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
    273       OpenMPClauseKind CKind =
    274           Tok.isAnnotation()
    275               ? OMPC_unknown
    276               : FlushHasClause ? OMPC_flush
    277                                : getOpenMPClauseKind(PP.getSpelling(Tok));
    278       Actions.StartOpenMPClause(CKind);
    279       FlushHasClause = false;
    280       OMPClause *Clause =
    281           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
    282       FirstClauses[CKind].setInt(true);
    283       if (Clause) {
    284         FirstClauses[CKind].setPointer(Clause);
    285         Clauses.push_back(Clause);
    286       }
    287 
    288       // Skip ',' if any.
    289       if (Tok.is(tok::comma))
    290         ConsumeToken();
    291       Actions.EndOpenMPClause();
    292     }
    293     // End location of the directive.
    294     EndLoc = Tok.getLocation();
    295     // Consume final annot_pragma_openmp_end.
    296     ConsumeToken();
    297 
    298     // OpenMP [2.13.8, ordered Construct, Syntax]
    299     // If the depend clause is specified, the ordered construct is a stand-alone
    300     // directive.
    301     if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
    302       if (!StandAloneAllowed) {
    303         Diag(Loc, diag::err_omp_immediate_directive)
    304             << getOpenMPDirectiveName(DKind) << 1
    305             << getOpenMPClauseName(OMPC_depend);
    306       }
    307       HasAssociatedStatement = false;
    308     }
    309 
    310     StmtResult AssociatedStmt;
    311     if (HasAssociatedStatement) {
    312       // The body is a block scope like in Lambdas and Blocks.
    313       Sema::CompoundScopeRAII CompoundScope(Actions);
    314       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
    315       Actions.ActOnStartOfCompoundStmt();
    316       // Parse statement
    317       AssociatedStmt = ParseStatement();
    318       Actions.ActOnFinishOfCompoundStmt();
    319       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
    320     }
    321     Directive = Actions.ActOnOpenMPExecutableDirective(
    322         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
    323         EndLoc);
    324 
    325     // Exit scope.
    326     Actions.EndOpenMPDSABlock(Directive.get());
    327     OMPDirectiveScope.Exit();
    328     break;
    329   }
    330   case OMPD_unknown:
    331     Diag(Tok, diag::err_omp_unknown_directive);
    332     SkipUntil(tok::annot_pragma_openmp_end);
    333     break;
    334   }
    335   return Directive;
    336 }
    337 
    338 /// \brief Parses list of simple variables for '#pragma omp threadprivate'
    339 /// directive.
    340 ///
    341 ///   simple-variable-list:
    342 ///         '(' id-expression {, id-expression} ')'
    343 ///
    344 bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
    345                                       SmallVectorImpl<Expr *> &VarList,
    346                                       bool AllowScopeSpecifier) {
    347   VarList.clear();
    348   // Parse '('.
    349   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
    350   if (T.expectAndConsume(diag::err_expected_lparen_after,
    351                          getOpenMPDirectiveName(Kind)))
    352     return true;
    353   bool IsCorrect = true;
    354   bool NoIdentIsFound = true;
    355 
    356   // Read tokens while ')' or annot_pragma_openmp_end is not found.
    357   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
    358     CXXScopeSpec SS;
    359     SourceLocation TemplateKWLoc;
    360     UnqualifiedId Name;
    361     // Read var name.
    362     Token PrevTok = Tok;
    363     NoIdentIsFound = false;
    364 
    365     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
    366         ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) {
    367       IsCorrect = false;
    368       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
    369                 StopBeforeMatch);
    370     } else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(),
    371                                   TemplateKWLoc, Name)) {
    372       IsCorrect = false;
    373       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
    374                 StopBeforeMatch);
    375     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
    376                Tok.isNot(tok::annot_pragma_openmp_end)) {
    377       IsCorrect = false;
    378       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
    379                 StopBeforeMatch);
    380       Diag(PrevTok.getLocation(), diag::err_expected)
    381           << tok::identifier
    382           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
    383     } else {
    384       DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
    385       ExprResult Res =
    386           Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
    387       if (Res.isUsable())
    388         VarList.push_back(Res.get());
    389     }
    390     // Consume ','.
    391     if (Tok.is(tok::comma)) {
    392       ConsumeToken();
    393     }
    394   }
    395 
    396   if (NoIdentIsFound) {
    397     Diag(Tok, diag::err_expected) << tok::identifier;
    398     IsCorrect = false;
    399   }
    400 
    401   // Parse ')'.
    402   IsCorrect = !T.consumeClose() && IsCorrect;
    403 
    404   return !IsCorrect && VarList.empty();
    405 }
    406 
    407 /// \brief Parsing of OpenMP clauses.
    408 ///
    409 ///    clause:
    410 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
    411 ///       default-clause | private-clause | firstprivate-clause | shared-clause
    412 ///       | linear-clause | aligned-clause | collapse-clause |
    413 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
    414 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
    415 ///       mergeable-clause | flush-clause | read-clause | write-clause |
    416 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
    417 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
    418 ///       thread_limit-clause | priority-clause | grainsize-clause |
    419 ///       nogroup-clause | num_tasks-clause | hint-clause
    420 ///
    421 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
    422                                      OpenMPClauseKind CKind, bool FirstClause) {
    423   OMPClause *Clause = nullptr;
    424   bool ErrorFound = false;
    425   // Check if clause is allowed for the given directive.
    426   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
    427     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
    428                                                << getOpenMPDirectiveName(DKind);
    429     ErrorFound = true;
    430   }
    431 
    432   switch (CKind) {
    433   case OMPC_final:
    434   case OMPC_num_threads:
    435   case OMPC_safelen:
    436   case OMPC_simdlen:
    437   case OMPC_collapse:
    438   case OMPC_ordered:
    439   case OMPC_device:
    440   case OMPC_num_teams:
    441   case OMPC_thread_limit:
    442   case OMPC_priority:
    443   case OMPC_grainsize:
    444   case OMPC_num_tasks:
    445   case OMPC_hint:
    446     // OpenMP [2.5, Restrictions]
    447     //  At most one num_threads clause can appear on the directive.
    448     // OpenMP [2.8.1, simd construct, Restrictions]
    449     //  Only one safelen  clause can appear on a simd directive.
    450     //  Only one simdlen  clause can appear on a simd directive.
    451     //  Only one collapse clause can appear on a simd directive.
    452     // OpenMP [2.9.1, target data construct, Restrictions]
    453     //  At most one device clause can appear on the directive.
    454     // OpenMP [2.11.1, task Construct, Restrictions]
    455     //  At most one if clause can appear on the directive.
    456     //  At most one final clause can appear on the directive.
    457     // OpenMP [teams Construct, Restrictions]
    458     //  At most one num_teams clause can appear on the directive.
    459     //  At most one thread_limit clause can appear on the directive.
    460     // OpenMP [2.9.1, task Construct, Restrictions]
    461     // At most one priority clause can appear on the directive.
    462     // OpenMP [2.9.2, taskloop Construct, Restrictions]
    463     // At most one grainsize clause can appear on the directive.
    464     // OpenMP [2.9.2, taskloop Construct, Restrictions]
    465     // At most one num_tasks clause can appear on the directive.
    466     if (!FirstClause) {
    467       Diag(Tok, diag::err_omp_more_one_clause)
    468           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
    469       ErrorFound = true;
    470     }
    471 
    472     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
    473       Clause = ParseOpenMPClause(CKind);
    474     else
    475       Clause = ParseOpenMPSingleExprClause(CKind);
    476     break;
    477   case OMPC_default:
    478   case OMPC_proc_bind:
    479     // OpenMP [2.14.3.1, Restrictions]
    480     //  Only a single default clause may be specified on a parallel, task or
    481     //  teams directive.
    482     // OpenMP [2.5, parallel Construct, Restrictions]
    483     //  At most one proc_bind clause can appear on the directive.
    484     if (!FirstClause) {
    485       Diag(Tok, diag::err_omp_more_one_clause)
    486           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
    487       ErrorFound = true;
    488     }
    489 
    490     Clause = ParseOpenMPSimpleClause(CKind);
    491     break;
    492   case OMPC_schedule:
    493     // OpenMP [2.7.1, Restrictions, p. 3]
    494     //  Only one schedule clause can appear on a loop directive.
    495     if (!FirstClause) {
    496       Diag(Tok, diag::err_omp_more_one_clause)
    497           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
    498       ErrorFound = true;
    499     }
    500 
    501   case OMPC_if:
    502     Clause = ParseOpenMPSingleExprWithArgClause(CKind);
    503     break;
    504   case OMPC_nowait:
    505   case OMPC_untied:
    506   case OMPC_mergeable:
    507   case OMPC_read:
    508   case OMPC_write:
    509   case OMPC_update:
    510   case OMPC_capture:
    511   case OMPC_seq_cst:
    512   case OMPC_threads:
    513   case OMPC_simd:
    514   case OMPC_nogroup:
    515     // OpenMP [2.7.1, Restrictions, p. 9]
    516     //  Only one ordered clause can appear on a loop directive.
    517     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
    518     //  Only one nowait clause can appear on a for directive.
    519     if (!FirstClause) {
    520       Diag(Tok, diag::err_omp_more_one_clause)
    521           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
    522       ErrorFound = true;
    523     }
    524 
    525     Clause = ParseOpenMPClause(CKind);
    526     break;
    527   case OMPC_private:
    528   case OMPC_firstprivate:
    529   case OMPC_lastprivate:
    530   case OMPC_shared:
    531   case OMPC_reduction:
    532   case OMPC_linear:
    533   case OMPC_aligned:
    534   case OMPC_copyin:
    535   case OMPC_copyprivate:
    536   case OMPC_flush:
    537   case OMPC_depend:
    538   case OMPC_map:
    539     Clause = ParseOpenMPVarListClause(DKind, CKind);
    540     break;
    541   case OMPC_unknown:
    542     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
    543         << getOpenMPDirectiveName(DKind);
    544     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
    545     break;
    546   case OMPC_threadprivate:
    547     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
    548                                                << getOpenMPDirectiveName(DKind);
    549     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
    550     break;
    551   }
    552   return ErrorFound ? nullptr : Clause;
    553 }
    554 
    555 /// \brief Parsing of OpenMP clauses with single expressions like 'final',
    556 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
    557 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
    558 ///
    559 ///    final-clause:
    560 ///      'final' '(' expression ')'
    561 ///
    562 ///    num_threads-clause:
    563 ///      'num_threads' '(' expression ')'
    564 ///
    565 ///    safelen-clause:
    566 ///      'safelen' '(' expression ')'
    567 ///
    568 ///    simdlen-clause:
    569 ///      'simdlen' '(' expression ')'
    570 ///
    571 ///    collapse-clause:
    572 ///      'collapse' '(' expression ')'
    573 ///
    574 ///    priority-clause:
    575 ///      'priority' '(' expression ')'
    576 ///
    577 ///    grainsize-clause:
    578 ///      'grainsize' '(' expression ')'
    579 ///
    580 ///    num_tasks-clause:
    581 ///      'num_tasks' '(' expression ')'
    582 ///
    583 ///    hint-clause:
    584 ///      'hint' '(' expression ')'
    585 ///
    586 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
    587   SourceLocation Loc = ConsumeToken();
    588 
    589   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
    590   if (T.expectAndConsume(diag::err_expected_lparen_after,
    591                          getOpenMPClauseName(Kind)))
    592     return nullptr;
    593 
    594   SourceLocation ELoc = Tok.getLocation();
    595   ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
    596   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
    597   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
    598 
    599   // Parse ')'.
    600   T.consumeClose();
    601 
    602   if (Val.isInvalid())
    603     return nullptr;
    604 
    605   return Actions.ActOnOpenMPSingleExprClause(
    606       Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
    607 }
    608 
    609 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
    610 ///
    611 ///    default-clause:
    612 ///         'default' '(' 'none' | 'shared' ')
    613 ///
    614 ///    proc_bind-clause:
    615 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
    616 ///
    617 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
    618   SourceLocation Loc = Tok.getLocation();
    619   SourceLocation LOpen = ConsumeToken();
    620   // Parse '('.
    621   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
    622   if (T.expectAndConsume(diag::err_expected_lparen_after,
    623                          getOpenMPClauseName(Kind)))
    624     return nullptr;
    625 
    626   unsigned Type = getOpenMPSimpleClauseType(
    627       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
    628   SourceLocation TypeLoc = Tok.getLocation();
    629   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
    630       Tok.isNot(tok::annot_pragma_openmp_end))
    631     ConsumeAnyToken();
    632 
    633   // Parse ')'.
    634   T.consumeClose();
    635 
    636   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
    637                                          Tok.getLocation());
    638 }
    639 
    640 /// \brief Parsing of OpenMP clauses like 'ordered'.
    641 ///
    642 ///    ordered-clause:
    643 ///         'ordered'
    644 ///
    645 ///    nowait-clause:
    646 ///         'nowait'
    647 ///
    648 ///    untied-clause:
    649 ///         'untied'
    650 ///
    651 ///    mergeable-clause:
    652 ///         'mergeable'
    653 ///
    654 ///    read-clause:
    655 ///         'read'
    656 ///
    657 ///    threads-clause:
    658 ///         'threads'
    659 ///
    660 ///    simd-clause:
    661 ///         'simd'
    662 ///
    663 ///    nogroup-clause:
    664 ///         'nogroup'
    665 ///
    666 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
    667   SourceLocation Loc = Tok.getLocation();
    668   ConsumeAnyToken();
    669 
    670   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
    671 }
    672 
    673 
    674 /// \brief Parsing of OpenMP clauses with single expressions and some additional
    675 /// argument like 'schedule' or 'dist_schedule'.
    676 ///
    677 ///    schedule-clause:
    678 ///      'schedule' '(' kind [',' expression ] ')'
    679 ///
    680 ///    if-clause:
    681 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
    682 ///
    683 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
    684   SourceLocation Loc = ConsumeToken();
    685   SourceLocation DelimLoc;
    686   // Parse '('.
    687   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
    688   if (T.expectAndConsume(diag::err_expected_lparen_after,
    689                          getOpenMPClauseName(Kind)))
    690     return nullptr;
    691 
    692   ExprResult Val;
    693   unsigned Arg;
    694   SourceLocation KLoc;
    695   if (Kind == OMPC_schedule) {
    696     Arg = getOpenMPSimpleClauseType(
    697         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
    698     KLoc = Tok.getLocation();
    699     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
    700         Tok.isNot(tok::annot_pragma_openmp_end))
    701       ConsumeAnyToken();
    702     if ((Arg == OMPC_SCHEDULE_static || Arg == OMPC_SCHEDULE_dynamic ||
    703          Arg == OMPC_SCHEDULE_guided) &&
    704         Tok.is(tok::comma))
    705       DelimLoc = ConsumeAnyToken();
    706   } else {
    707     assert(Kind == OMPC_if);
    708     KLoc = Tok.getLocation();
    709     Arg = ParseOpenMPDirectiveKind(*this);
    710     if (Arg != OMPD_unknown) {
    711       ConsumeToken();
    712       if (Tok.is(tok::colon))
    713         DelimLoc = ConsumeToken();
    714       else
    715         Diag(Tok, diag::warn_pragma_expected_colon)
    716             << "directive name modifier";
    717     }
    718   }
    719 
    720   bool NeedAnExpression =
    721       (Kind == OMPC_schedule && DelimLoc.isValid()) || Kind == OMPC_if;
    722   if (NeedAnExpression) {
    723     SourceLocation ELoc = Tok.getLocation();
    724     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
    725     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
    726     Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
    727   }
    728 
    729   // Parse ')'.
    730   T.consumeClose();
    731 
    732   if (NeedAnExpression && Val.isInvalid())
    733     return nullptr;
    734 
    735   return Actions.ActOnOpenMPSingleExprWithArgClause(
    736       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
    737       T.getCloseLocation());
    738 }
    739 
    740 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
    741                              UnqualifiedId &ReductionId) {
    742   SourceLocation TemplateKWLoc;
    743   if (ReductionIdScopeSpec.isEmpty()) {
    744     auto OOK = OO_None;
    745     switch (P.getCurToken().getKind()) {
    746     case tok::plus:
    747       OOK = OO_Plus;
    748       break;
    749     case tok::minus:
    750       OOK = OO_Minus;
    751       break;
    752     case tok::star:
    753       OOK = OO_Star;
    754       break;
    755     case tok::amp:
    756       OOK = OO_Amp;
    757       break;
    758     case tok::pipe:
    759       OOK = OO_Pipe;
    760       break;
    761     case tok::caret:
    762       OOK = OO_Caret;
    763       break;
    764     case tok::ampamp:
    765       OOK = OO_AmpAmp;
    766       break;
    767     case tok::pipepipe:
    768       OOK = OO_PipePipe;
    769       break;
    770     default:
    771       break;
    772     }
    773     if (OOK != OO_None) {
    774       SourceLocation OpLoc = P.ConsumeToken();
    775       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
    776       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
    777       return false;
    778     }
    779   }
    780   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
    781                               /*AllowDestructorName*/ false,
    782                               /*AllowConstructorName*/ false, ParsedType(),
    783                               TemplateKWLoc, ReductionId);
    784 }
    785 
    786 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
    787 /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
    788 ///
    789 ///    private-clause:
    790 ///       'private' '(' list ')'
    791 ///    firstprivate-clause:
    792 ///       'firstprivate' '(' list ')'
    793 ///    lastprivate-clause:
    794 ///       'lastprivate' '(' list ')'
    795 ///    shared-clause:
    796 ///       'shared' '(' list ')'
    797 ///    linear-clause:
    798 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
    799 ///    aligned-clause:
    800 ///       'aligned' '(' list [ ':' alignment ] ')'
    801 ///    reduction-clause:
    802 ///       'reduction' '(' reduction-identifier ':' list ')'
    803 ///    copyprivate-clause:
    804 ///       'copyprivate' '(' list ')'
    805 ///    flush-clause:
    806 ///       'flush' '(' list ')'
    807 ///    depend-clause:
    808 ///       'depend' '(' in | out | inout : list | source ')'
    809 ///    map-clause:
    810 ///       'map' '(' [ [ always , ]
    811 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
    812 ///
    813 /// For 'linear' clause linear-list may have the following forms:
    814 ///  list
    815 ///  modifier(list)
    816 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
    817 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
    818                                             OpenMPClauseKind Kind) {
    819   SourceLocation Loc = Tok.getLocation();
    820   SourceLocation LOpen = ConsumeToken();
    821   SourceLocation ColonLoc = SourceLocation();
    822   // Optional scope specifier and unqualified id for reduction identifier.
    823   CXXScopeSpec ReductionIdScopeSpec;
    824   UnqualifiedId ReductionId;
    825   bool InvalidReductionId = false;
    826   OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
    827   // OpenMP 4.1 [2.15.3.7, linear Clause]
    828   //  If no modifier is specified it is assumed to be val.
    829   OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val;
    830   OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
    831   OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
    832   bool MapTypeModifierSpecified = false;
    833   bool UnexpectedId = false;
    834   SourceLocation DepLinMapLoc;
    835 
    836   // Parse '('.
    837   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
    838   if (T.expectAndConsume(diag::err_expected_lparen_after,
    839                          getOpenMPClauseName(Kind)))
    840     return nullptr;
    841 
    842   bool NeedRParenForLinear = false;
    843   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
    844                                   tok::annot_pragma_openmp_end);
    845   // Handle reduction-identifier for reduction clause.
    846   if (Kind == OMPC_reduction) {
    847     ColonProtectionRAIIObject ColonRAII(*this);
    848     if (getLangOpts().CPlusPlus) {
    849       ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, ParsedType(), false);
    850     }
    851     InvalidReductionId =
    852         ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
    853     if (InvalidReductionId) {
    854       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
    855                 StopBeforeMatch);
    856     }
    857     if (Tok.is(tok::colon)) {
    858       ColonLoc = ConsumeToken();
    859     } else {
    860       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
    861     }
    862   } else if (Kind == OMPC_depend) {
    863   // Handle dependency type for depend clause.
    864     ColonProtectionRAIIObject ColonRAII(*this);
    865     DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
    866         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
    867     DepLinMapLoc = Tok.getLocation();
    868 
    869     if (DepKind == OMPC_DEPEND_unknown) {
    870       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
    871                 StopBeforeMatch);
    872     } else {
    873       ConsumeToken();
    874       // Special processing for depend(source) clause.
    875       if (DKind == OMPD_ordered && DepKind == OMPC_DEPEND_source) {
    876         // Parse ')'.
    877         T.consumeClose();
    878         return Actions.ActOnOpenMPVarListClause(
    879             Kind, llvm::None, /*TailExpr=*/nullptr, Loc, LOpen,
    880             /*ColonLoc=*/SourceLocation(), Tok.getLocation(),
    881             ReductionIdScopeSpec, DeclarationNameInfo(), DepKind,
    882             LinearModifier, MapTypeModifier, MapType, DepLinMapLoc);
    883       }
    884     }
    885     if (Tok.is(tok::colon)) {
    886       ColonLoc = ConsumeToken();
    887     } else {
    888       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
    889                                       : diag::warn_pragma_expected_colon)
    890           << "dependency type";
    891     }
    892   } else if (Kind == OMPC_linear) {
    893     // Try to parse modifier if any.
    894     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
    895       LinearModifier = static_cast<OpenMPLinearClauseKind>(
    896           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
    897       DepLinMapLoc = ConsumeToken();
    898       LinearT.consumeOpen();
    899       NeedRParenForLinear = true;
    900     }
    901   } else if (Kind == OMPC_map) {
    902     // Handle map type for map clause.
    903     ColonProtectionRAIIObject ColonRAII(*this);
    904 
    905     // the first identifier may be a list item, a map-type or
    906     //   a map-type-modifier
    907     MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
    908         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
    909     DepLinMapLoc = Tok.getLocation();
    910     bool ColonExpected = false;
    911 
    912     if (Tok.is(tok::identifier)) {
    913       if (PP.LookAhead(0).is(tok::colon)) {
    914         MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
    915             Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
    916         if (MapType == OMPC_MAP_unknown) {
    917           Diag(Tok, diag::err_omp_unknown_map_type);
    918         } else if (MapType == OMPC_MAP_always) {
    919           Diag(Tok, diag::err_omp_map_type_missing);
    920         }
    921         ConsumeToken();
    922       } else if (PP.LookAhead(0).is(tok::comma)) {
    923         if (PP.LookAhead(1).is(tok::identifier) &&
    924             PP.LookAhead(2).is(tok::colon)) {
    925           MapTypeModifier =
    926               static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
    927                    Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
    928           if (MapTypeModifier != OMPC_MAP_always) {
    929             Diag(Tok, diag::err_omp_unknown_map_type_modifier);
    930             MapTypeModifier = OMPC_MAP_unknown;
    931           } else {
    932             MapTypeModifierSpecified = true;
    933           }
    934 
    935           ConsumeToken();
    936           ConsumeToken();
    937 
    938           MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
    939               Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
    940           if (MapType == OMPC_MAP_unknown || MapType == OMPC_MAP_always) {
    941             Diag(Tok, diag::err_omp_unknown_map_type);
    942           }
    943           ConsumeToken();
    944         } else {
    945           MapType = OMPC_MAP_tofrom;
    946         }
    947       } else {
    948         MapType = OMPC_MAP_tofrom;
    949       }
    950     } else {
    951       UnexpectedId = true;
    952     }
    953 
    954     if (Tok.is(tok::colon)) {
    955       ColonLoc = ConsumeToken();
    956     } else if (ColonExpected) {
    957       Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
    958     }
    959   }
    960 
    961   SmallVector<Expr *, 5> Vars;
    962   bool IsComma =
    963       ((Kind != OMPC_reduction) && (Kind != OMPC_depend) &&
    964        (Kind != OMPC_map)) ||
    965       ((Kind == OMPC_reduction) && !InvalidReductionId) ||
    966       ((Kind == OMPC_map) && (UnexpectedId || MapType != OMPC_MAP_unknown) &&
    967        (!MapTypeModifierSpecified ||
    968         (MapTypeModifierSpecified && MapTypeModifier == OMPC_MAP_always))) ||
    969       ((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
    970   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
    971   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
    972                      Tok.isNot(tok::annot_pragma_openmp_end))) {
    973     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
    974     // Parse variable
    975     ExprResult VarExpr =
    976         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
    977     if (VarExpr.isUsable()) {
    978       Vars.push_back(VarExpr.get());
    979     } else {
    980       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
    981                 StopBeforeMatch);
    982     }
    983     // Skip ',' if any
    984     IsComma = Tok.is(tok::comma);
    985     if (IsComma)
    986       ConsumeToken();
    987     else if (Tok.isNot(tok::r_paren) &&
    988              Tok.isNot(tok::annot_pragma_openmp_end) &&
    989              (!MayHaveTail || Tok.isNot(tok::colon)))
    990       Diag(Tok, diag::err_omp_expected_punc)
    991           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
    992                                    : getOpenMPClauseName(Kind))
    993           << (Kind == OMPC_flush);
    994   }
    995 
    996   // Parse ')' for linear clause with modifier.
    997   if (NeedRParenForLinear)
    998     LinearT.consumeClose();
    999 
   1000   // Parse ':' linear-step (or ':' alignment).
   1001   Expr *TailExpr = nullptr;
   1002   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
   1003   if (MustHaveTail) {
   1004     ColonLoc = Tok.getLocation();
   1005     SourceLocation ELoc = ConsumeToken();
   1006     ExprResult Tail = ParseAssignmentExpression();
   1007     Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
   1008     if (Tail.isUsable())
   1009       TailExpr = Tail.get();
   1010     else
   1011       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
   1012                 StopBeforeMatch);
   1013   }
   1014 
   1015   // Parse ')'.
   1016   T.consumeClose();
   1017   if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
   1018       (Kind != OMPC_depend && Vars.empty()) || (MustHaveTail && !TailExpr) ||
   1019       (Kind == OMPC_map && MapType == OMPC_MAP_unknown) ||
   1020       InvalidReductionId) {
   1021     return nullptr;
   1022   }
   1023 
   1024   return Actions.ActOnOpenMPVarListClause(
   1025       Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
   1026       ReductionIdScopeSpec,
   1027       ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
   1028                             : DeclarationNameInfo(),
   1029       DepKind, LinearModifier, MapTypeModifier, MapType, DepLinMapLoc);
   1030 }
   1031 
   1032