1*f4a2713aSLionel Sambuc //===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc /// \file 10*f4a2713aSLionel Sambuc /// \brief This file implements parsing of all OpenMP directives and clauses. 11*f4a2713aSLionel Sambuc /// 12*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambuc #include "clang/AST/ASTConsumer.h" 15*f4a2713aSLionel Sambuc #include "clang/AST/StmtOpenMP.h" 16*f4a2713aSLionel Sambuc #include "clang/Parse/ParseDiagnostic.h" 17*f4a2713aSLionel Sambuc #include "clang/Parse/Parser.h" 18*f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h" 19*f4a2713aSLionel Sambuc #include "llvm/ADT/PointerIntPair.h" 20*f4a2713aSLionel Sambuc #include "RAIIObjectsForParser.h" 21*f4a2713aSLionel Sambuc using namespace clang; 22*f4a2713aSLionel Sambuc 23*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 24*f4a2713aSLionel Sambuc // OpenMP declarative directives. 25*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 26*f4a2713aSLionel Sambuc 27*f4a2713aSLionel Sambuc /// \brief Parsing of declarative OpenMP directives. 28*f4a2713aSLionel Sambuc /// 29*f4a2713aSLionel Sambuc /// threadprivate-directive: 30*f4a2713aSLionel Sambuc /// annot_pragma_openmp 'threadprivate' simple-variable-list 31*f4a2713aSLionel Sambuc /// 32*f4a2713aSLionel Sambuc Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { 33*f4a2713aSLionel Sambuc assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); 34*f4a2713aSLionel Sambuc ParenBraceBracketBalancer BalancerRAIIObj(*this); 35*f4a2713aSLionel Sambuc 36*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); 37*f4a2713aSLionel Sambuc SmallVector<Expr *, 5> Identifiers; 38*f4a2713aSLionel Sambuc OpenMPDirectiveKind DKind = Tok.isAnnotation() ? 39*f4a2713aSLionel Sambuc OMPD_unknown : 40*f4a2713aSLionel Sambuc getOpenMPDirectiveKind(PP.getSpelling(Tok)); 41*f4a2713aSLionel Sambuc 42*f4a2713aSLionel Sambuc switch (DKind) { 43*f4a2713aSLionel Sambuc case OMPD_threadprivate: 44*f4a2713aSLionel Sambuc ConsumeToken(); 45*f4a2713aSLionel Sambuc if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) { 46*f4a2713aSLionel Sambuc // The last seen token is annot_pragma_openmp_end - need to check for 47*f4a2713aSLionel Sambuc // extra tokens. 48*f4a2713aSLionel Sambuc if (Tok.isNot(tok::annot_pragma_openmp_end)) { 49*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 50*f4a2713aSLionel Sambuc << getOpenMPDirectiveName(OMPD_threadprivate); 51*f4a2713aSLionel Sambuc SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 52*f4a2713aSLionel Sambuc } 53*f4a2713aSLionel Sambuc // Skip the last annot_pragma_openmp_end. 54*f4a2713aSLionel Sambuc ConsumeToken(); 55*f4a2713aSLionel Sambuc return Actions.ActOnOpenMPThreadprivateDirective(Loc, 56*f4a2713aSLionel Sambuc Identifiers); 57*f4a2713aSLionel Sambuc } 58*f4a2713aSLionel Sambuc break; 59*f4a2713aSLionel Sambuc case OMPD_unknown: 60*f4a2713aSLionel Sambuc Diag(Tok, diag::err_omp_unknown_directive); 61*f4a2713aSLionel Sambuc break; 62*f4a2713aSLionel Sambuc case OMPD_parallel: 63*f4a2713aSLionel Sambuc case OMPD_task: 64*f4a2713aSLionel Sambuc case NUM_OPENMP_DIRECTIVES: 65*f4a2713aSLionel Sambuc Diag(Tok, diag::err_omp_unexpected_directive) 66*f4a2713aSLionel Sambuc << getOpenMPDirectiveName(DKind); 67*f4a2713aSLionel Sambuc break; 68*f4a2713aSLionel Sambuc } 69*f4a2713aSLionel Sambuc SkipUntil(tok::annot_pragma_openmp_end); 70*f4a2713aSLionel Sambuc return DeclGroupPtrTy(); 71*f4a2713aSLionel Sambuc } 72*f4a2713aSLionel Sambuc 73*f4a2713aSLionel Sambuc /// \brief Parsing of declarative or executable OpenMP directives. 74*f4a2713aSLionel Sambuc /// 75*f4a2713aSLionel Sambuc /// threadprivate-directive: 76*f4a2713aSLionel Sambuc /// annot_pragma_openmp 'threadprivate' simple-variable-list 77*f4a2713aSLionel Sambuc /// annot_pragma_openmp_end 78*f4a2713aSLionel Sambuc /// 79*f4a2713aSLionel Sambuc /// parallel-directive: 80*f4a2713aSLionel Sambuc /// annot_pragma_openmp 'parallel' {clause} annot_pragma_openmp_end 81*f4a2713aSLionel Sambuc /// 82*f4a2713aSLionel Sambuc StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() { 83*f4a2713aSLionel Sambuc assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); 84*f4a2713aSLionel Sambuc ParenBraceBracketBalancer BalancerRAIIObj(*this); 85*f4a2713aSLionel Sambuc SmallVector<Expr *, 5> Identifiers; 86*f4a2713aSLionel Sambuc SmallVector<OMPClause *, 5> Clauses; 87*f4a2713aSLionel Sambuc SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, NUM_OPENMP_CLAUSES> 88*f4a2713aSLionel Sambuc FirstClauses(NUM_OPENMP_CLAUSES); 89*f4a2713aSLionel Sambuc const unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | 90*f4a2713aSLionel Sambuc Scope::OpenMPDirectiveScope; 91*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(), EndLoc; 92*f4a2713aSLionel Sambuc OpenMPDirectiveKind DKind = Tok.isAnnotation() ? 93*f4a2713aSLionel Sambuc OMPD_unknown : 94*f4a2713aSLionel Sambuc getOpenMPDirectiveKind(PP.getSpelling(Tok)); 95*f4a2713aSLionel Sambuc // Name of critical directive. 96*f4a2713aSLionel Sambuc DeclarationNameInfo DirName; 97*f4a2713aSLionel Sambuc StmtResult Directive = StmtError(); 98*f4a2713aSLionel Sambuc 99*f4a2713aSLionel Sambuc switch (DKind) { 100*f4a2713aSLionel Sambuc case OMPD_threadprivate: 101*f4a2713aSLionel Sambuc ConsumeToken(); 102*f4a2713aSLionel Sambuc if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) { 103*f4a2713aSLionel Sambuc // The last seen token is annot_pragma_openmp_end - need to check for 104*f4a2713aSLionel Sambuc // extra tokens. 105*f4a2713aSLionel Sambuc if (Tok.isNot(tok::annot_pragma_openmp_end)) { 106*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 107*f4a2713aSLionel Sambuc << getOpenMPDirectiveName(OMPD_threadprivate); 108*f4a2713aSLionel Sambuc SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 109*f4a2713aSLionel Sambuc } 110*f4a2713aSLionel Sambuc DeclGroupPtrTy Res = 111*f4a2713aSLionel Sambuc Actions.ActOnOpenMPThreadprivateDirective(Loc, 112*f4a2713aSLionel Sambuc Identifiers); 113*f4a2713aSLionel Sambuc Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 114*f4a2713aSLionel Sambuc } 115*f4a2713aSLionel Sambuc SkipUntil(tok::annot_pragma_openmp_end); 116*f4a2713aSLionel Sambuc break; 117*f4a2713aSLionel Sambuc case OMPD_parallel: { 118*f4a2713aSLionel Sambuc ConsumeToken(); 119*f4a2713aSLionel Sambuc 120*f4a2713aSLionel Sambuc Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope()); 121*f4a2713aSLionel Sambuc 122*f4a2713aSLionel Sambuc while (Tok.isNot(tok::annot_pragma_openmp_end)) { 123*f4a2713aSLionel Sambuc OpenMPClauseKind CKind = Tok.isAnnotation() ? 124*f4a2713aSLionel Sambuc OMPC_unknown : 125*f4a2713aSLionel Sambuc getOpenMPClauseKind(PP.getSpelling(Tok)); 126*f4a2713aSLionel Sambuc OMPClause *Clause = ParseOpenMPClause(DKind, CKind, 127*f4a2713aSLionel Sambuc !FirstClauses[CKind].getInt()); 128*f4a2713aSLionel Sambuc FirstClauses[CKind].setInt(true); 129*f4a2713aSLionel Sambuc if (Clause) { 130*f4a2713aSLionel Sambuc FirstClauses[CKind].setPointer(Clause); 131*f4a2713aSLionel Sambuc Clauses.push_back(Clause); 132*f4a2713aSLionel Sambuc } 133*f4a2713aSLionel Sambuc 134*f4a2713aSLionel Sambuc // Skip ',' if any. 135*f4a2713aSLionel Sambuc if (Tok.is(tok::comma)) 136*f4a2713aSLionel Sambuc ConsumeToken(); 137*f4a2713aSLionel Sambuc } 138*f4a2713aSLionel Sambuc // End location of the directive. 139*f4a2713aSLionel Sambuc EndLoc = Tok.getLocation(); 140*f4a2713aSLionel Sambuc // Consume final annot_pragma_openmp_end. 141*f4a2713aSLionel Sambuc ConsumeToken(); 142*f4a2713aSLionel Sambuc 143*f4a2713aSLionel Sambuc StmtResult AssociatedStmt; 144*f4a2713aSLionel Sambuc bool CreateDirective = true; 145*f4a2713aSLionel Sambuc ParseScope OMPDirectiveScope(this, ScopeFlags); 146*f4a2713aSLionel Sambuc { 147*f4a2713aSLionel Sambuc // The body is a block scope like in Lambdas and Blocks. 148*f4a2713aSLionel Sambuc Sema::CompoundScopeRAII CompoundScope(Actions); 149*f4a2713aSLionel Sambuc Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_OpenMP, 1); 150*f4a2713aSLionel Sambuc Actions.ActOnStartOfCompoundStmt(); 151*f4a2713aSLionel Sambuc // Parse statement 152*f4a2713aSLionel Sambuc AssociatedStmt = ParseStatement(); 153*f4a2713aSLionel Sambuc Actions.ActOnFinishOfCompoundStmt(); 154*f4a2713aSLionel Sambuc if (!AssociatedStmt.isUsable()) { 155*f4a2713aSLionel Sambuc Actions.ActOnCapturedRegionError(); 156*f4a2713aSLionel Sambuc CreateDirective = false; 157*f4a2713aSLionel Sambuc } else { 158*f4a2713aSLionel Sambuc AssociatedStmt = Actions.ActOnCapturedRegionEnd(AssociatedStmt.take()); 159*f4a2713aSLionel Sambuc CreateDirective = AssociatedStmt.isUsable(); 160*f4a2713aSLionel Sambuc } 161*f4a2713aSLionel Sambuc } 162*f4a2713aSLionel Sambuc if (CreateDirective) 163*f4a2713aSLionel Sambuc Directive = Actions.ActOnOpenMPExecutableDirective(DKind, Clauses, 164*f4a2713aSLionel Sambuc AssociatedStmt.take(), 165*f4a2713aSLionel Sambuc Loc, EndLoc); 166*f4a2713aSLionel Sambuc 167*f4a2713aSLionel Sambuc // Exit scope. 168*f4a2713aSLionel Sambuc Actions.EndOpenMPDSABlock(Directive.get()); 169*f4a2713aSLionel Sambuc OMPDirectiveScope.Exit(); 170*f4a2713aSLionel Sambuc } 171*f4a2713aSLionel Sambuc break; 172*f4a2713aSLionel Sambuc case OMPD_unknown: 173*f4a2713aSLionel Sambuc Diag(Tok, diag::err_omp_unknown_directive); 174*f4a2713aSLionel Sambuc SkipUntil(tok::annot_pragma_openmp_end); 175*f4a2713aSLionel Sambuc break; 176*f4a2713aSLionel Sambuc case OMPD_task: 177*f4a2713aSLionel Sambuc case NUM_OPENMP_DIRECTIVES: 178*f4a2713aSLionel Sambuc Diag(Tok, diag::err_omp_unexpected_directive) 179*f4a2713aSLionel Sambuc << getOpenMPDirectiveName(DKind); 180*f4a2713aSLionel Sambuc SkipUntil(tok::annot_pragma_openmp_end); 181*f4a2713aSLionel Sambuc break; 182*f4a2713aSLionel Sambuc } 183*f4a2713aSLionel Sambuc return Directive; 184*f4a2713aSLionel Sambuc } 185*f4a2713aSLionel Sambuc 186*f4a2713aSLionel Sambuc /// \brief Parses list of simple variables for '#pragma omp threadprivate' 187*f4a2713aSLionel Sambuc /// directive. 188*f4a2713aSLionel Sambuc /// 189*f4a2713aSLionel Sambuc /// simple-variable-list: 190*f4a2713aSLionel Sambuc /// '(' id-expression {, id-expression} ')' 191*f4a2713aSLionel Sambuc /// 192*f4a2713aSLionel Sambuc bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, 193*f4a2713aSLionel Sambuc SmallVectorImpl<Expr *> &VarList, 194*f4a2713aSLionel Sambuc bool AllowScopeSpecifier) { 195*f4a2713aSLionel Sambuc VarList.clear(); 196*f4a2713aSLionel Sambuc // Parse '('. 197*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 198*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen_after, 199*f4a2713aSLionel Sambuc getOpenMPDirectiveName(Kind))) 200*f4a2713aSLionel Sambuc return true; 201*f4a2713aSLionel Sambuc bool IsCorrect = true; 202*f4a2713aSLionel Sambuc bool NoIdentIsFound = true; 203*f4a2713aSLionel Sambuc 204*f4a2713aSLionel Sambuc // Read tokens while ')' or annot_pragma_openmp_end is not found. 205*f4a2713aSLionel Sambuc while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) { 206*f4a2713aSLionel Sambuc CXXScopeSpec SS; 207*f4a2713aSLionel Sambuc SourceLocation TemplateKWLoc; 208*f4a2713aSLionel Sambuc UnqualifiedId Name; 209*f4a2713aSLionel Sambuc // Read var name. 210*f4a2713aSLionel Sambuc Token PrevTok = Tok; 211*f4a2713aSLionel Sambuc NoIdentIsFound = false; 212*f4a2713aSLionel Sambuc 213*f4a2713aSLionel Sambuc if (AllowScopeSpecifier && getLangOpts().CPlusPlus && 214*f4a2713aSLionel Sambuc ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) { 215*f4a2713aSLionel Sambuc IsCorrect = false; 216*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 217*f4a2713aSLionel Sambuc StopBeforeMatch); 218*f4a2713aSLionel Sambuc } else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(), 219*f4a2713aSLionel Sambuc TemplateKWLoc, Name)) { 220*f4a2713aSLionel Sambuc IsCorrect = false; 221*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 222*f4a2713aSLionel Sambuc StopBeforeMatch); 223*f4a2713aSLionel Sambuc } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) && 224*f4a2713aSLionel Sambuc Tok.isNot(tok::annot_pragma_openmp_end)) { 225*f4a2713aSLionel Sambuc IsCorrect = false; 226*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 227*f4a2713aSLionel Sambuc StopBeforeMatch); 228*f4a2713aSLionel Sambuc Diag(PrevTok.getLocation(), diag::err_expected_ident) 229*f4a2713aSLionel Sambuc << SourceRange(PrevTok.getLocation(), PrevTokLocation); 230*f4a2713aSLionel Sambuc } else { 231*f4a2713aSLionel Sambuc DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name); 232*f4a2713aSLionel Sambuc ExprResult Res = Actions.ActOnOpenMPIdExpression(getCurScope(), SS, 233*f4a2713aSLionel Sambuc NameInfo); 234*f4a2713aSLionel Sambuc if (Res.isUsable()) 235*f4a2713aSLionel Sambuc VarList.push_back(Res.take()); 236*f4a2713aSLionel Sambuc } 237*f4a2713aSLionel Sambuc // Consume ','. 238*f4a2713aSLionel Sambuc if (Tok.is(tok::comma)) { 239*f4a2713aSLionel Sambuc ConsumeToken(); 240*f4a2713aSLionel Sambuc } 241*f4a2713aSLionel Sambuc } 242*f4a2713aSLionel Sambuc 243*f4a2713aSLionel Sambuc if (NoIdentIsFound) { 244*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 245*f4a2713aSLionel Sambuc IsCorrect = false; 246*f4a2713aSLionel Sambuc } 247*f4a2713aSLionel Sambuc 248*f4a2713aSLionel Sambuc // Parse ')'. 249*f4a2713aSLionel Sambuc IsCorrect = !T.consumeClose() && IsCorrect; 250*f4a2713aSLionel Sambuc 251*f4a2713aSLionel Sambuc return !IsCorrect && VarList.empty(); 252*f4a2713aSLionel Sambuc } 253*f4a2713aSLionel Sambuc 254*f4a2713aSLionel Sambuc /// \brief Parsing of OpenMP clauses. 255*f4a2713aSLionel Sambuc /// 256*f4a2713aSLionel Sambuc /// clause: 257*f4a2713aSLionel Sambuc /// default-clause|private-clause|firstprivate-clause|shared-clause 258*f4a2713aSLionel Sambuc /// 259*f4a2713aSLionel Sambuc OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, 260*f4a2713aSLionel Sambuc OpenMPClauseKind CKind, bool FirstClause) { 261*f4a2713aSLionel Sambuc OMPClause *Clause = 0; 262*f4a2713aSLionel Sambuc bool ErrorFound = false; 263*f4a2713aSLionel Sambuc // Check if clause is allowed for the given directive. 264*f4a2713aSLionel Sambuc if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) { 265*f4a2713aSLionel Sambuc Diag(Tok, diag::err_omp_unexpected_clause) 266*f4a2713aSLionel Sambuc << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); 267*f4a2713aSLionel Sambuc ErrorFound = true; 268*f4a2713aSLionel Sambuc } 269*f4a2713aSLionel Sambuc 270*f4a2713aSLionel Sambuc switch (CKind) { 271*f4a2713aSLionel Sambuc case OMPC_default: 272*f4a2713aSLionel Sambuc // OpenMP [2.9.3.1, Restrictions] 273*f4a2713aSLionel Sambuc // Only a single default clause may be specified on a parallel or task 274*f4a2713aSLionel Sambuc // directive. 275*f4a2713aSLionel Sambuc if (!FirstClause) { 276*f4a2713aSLionel Sambuc Diag(Tok, diag::err_omp_more_one_clause) 277*f4a2713aSLionel Sambuc << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind); 278*f4a2713aSLionel Sambuc } 279*f4a2713aSLionel Sambuc 280*f4a2713aSLionel Sambuc Clause = ParseOpenMPSimpleClause(CKind); 281*f4a2713aSLionel Sambuc break; 282*f4a2713aSLionel Sambuc case OMPC_private: 283*f4a2713aSLionel Sambuc case OMPC_firstprivate: 284*f4a2713aSLionel Sambuc case OMPC_shared: 285*f4a2713aSLionel Sambuc Clause = ParseOpenMPVarListClause(CKind); 286*f4a2713aSLionel Sambuc break; 287*f4a2713aSLionel Sambuc case OMPC_unknown: 288*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 289*f4a2713aSLionel Sambuc << getOpenMPDirectiveName(DKind); 290*f4a2713aSLionel Sambuc SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 291*f4a2713aSLionel Sambuc break; 292*f4a2713aSLionel Sambuc case OMPC_threadprivate: 293*f4a2713aSLionel Sambuc case NUM_OPENMP_CLAUSES: 294*f4a2713aSLionel Sambuc Diag(Tok, diag::err_omp_unexpected_clause) 295*f4a2713aSLionel Sambuc << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); 296*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch); 297*f4a2713aSLionel Sambuc break; 298*f4a2713aSLionel Sambuc } 299*f4a2713aSLionel Sambuc return ErrorFound ? 0 : Clause; 300*f4a2713aSLionel Sambuc } 301*f4a2713aSLionel Sambuc 302*f4a2713aSLionel Sambuc /// \brief Parsing of simple OpenMP clauses like 'default'. 303*f4a2713aSLionel Sambuc /// 304*f4a2713aSLionel Sambuc /// default-clause: 305*f4a2713aSLionel Sambuc /// 'default' '(' 'none' | 'shared' ') 306*f4a2713aSLionel Sambuc /// 307*f4a2713aSLionel Sambuc OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) { 308*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 309*f4a2713aSLionel Sambuc SourceLocation LOpen = ConsumeToken(); 310*f4a2713aSLionel Sambuc // Parse '('. 311*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 312*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen_after, 313*f4a2713aSLionel Sambuc getOpenMPClauseName(Kind))) 314*f4a2713aSLionel Sambuc return 0; 315*f4a2713aSLionel Sambuc 316*f4a2713aSLionel Sambuc unsigned Type = Tok.isAnnotation() ? 317*f4a2713aSLionel Sambuc unsigned(OMPC_DEFAULT_unknown) : 318*f4a2713aSLionel Sambuc getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)); 319*f4a2713aSLionel Sambuc SourceLocation TypeLoc = Tok.getLocation(); 320*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 321*f4a2713aSLionel Sambuc Tok.isNot(tok::annot_pragma_openmp_end)) 322*f4a2713aSLionel Sambuc ConsumeAnyToken(); 323*f4a2713aSLionel Sambuc 324*f4a2713aSLionel Sambuc // Parse ')'. 325*f4a2713aSLionel Sambuc T.consumeClose(); 326*f4a2713aSLionel Sambuc 327*f4a2713aSLionel Sambuc return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, 328*f4a2713aSLionel Sambuc Tok.getLocation()); 329*f4a2713aSLionel Sambuc } 330*f4a2713aSLionel Sambuc 331*f4a2713aSLionel Sambuc /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 332*f4a2713aSLionel Sambuc /// 'shared', 'copyin', or 'reduction'. 333*f4a2713aSLionel Sambuc /// 334*f4a2713aSLionel Sambuc /// private-clause: 335*f4a2713aSLionel Sambuc /// 'private' '(' list ')' 336*f4a2713aSLionel Sambuc /// firstprivate-clause: 337*f4a2713aSLionel Sambuc /// 'firstprivate' '(' list ')' 338*f4a2713aSLionel Sambuc /// shared-clause: 339*f4a2713aSLionel Sambuc /// 'shared' '(' list ')' 340*f4a2713aSLionel Sambuc /// 341*f4a2713aSLionel Sambuc OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { 342*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 343*f4a2713aSLionel Sambuc SourceLocation LOpen = ConsumeToken(); 344*f4a2713aSLionel Sambuc // Parse '('. 345*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 346*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen_after, 347*f4a2713aSLionel Sambuc getOpenMPClauseName(Kind))) 348*f4a2713aSLionel Sambuc return 0; 349*f4a2713aSLionel Sambuc 350*f4a2713aSLionel Sambuc SmallVector<Expr *, 5> Vars; 351*f4a2713aSLionel Sambuc bool IsComma = true; 352*f4a2713aSLionel Sambuc while (IsComma || (Tok.isNot(tok::r_paren) && 353*f4a2713aSLionel Sambuc Tok.isNot(tok::annot_pragma_openmp_end))) { 354*f4a2713aSLionel Sambuc // Parse variable 355*f4a2713aSLionel Sambuc ExprResult VarExpr = ParseAssignmentExpression(); 356*f4a2713aSLionel Sambuc if (VarExpr.isUsable()) { 357*f4a2713aSLionel Sambuc Vars.push_back(VarExpr.take()); 358*f4a2713aSLionel Sambuc } else { 359*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 360*f4a2713aSLionel Sambuc StopBeforeMatch); 361*f4a2713aSLionel Sambuc } 362*f4a2713aSLionel Sambuc // Skip ',' if any 363*f4a2713aSLionel Sambuc IsComma = Tok.is(tok::comma); 364*f4a2713aSLionel Sambuc if (IsComma) { 365*f4a2713aSLionel Sambuc ConsumeToken(); 366*f4a2713aSLionel Sambuc } else if (Tok.isNot(tok::r_paren) && 367*f4a2713aSLionel Sambuc Tok.isNot(tok::annot_pragma_openmp_end)) { 368*f4a2713aSLionel Sambuc Diag(Tok, diag::err_omp_expected_punc) 369*f4a2713aSLionel Sambuc << 1 << getOpenMPClauseName(Kind); 370*f4a2713aSLionel Sambuc } 371*f4a2713aSLionel Sambuc } 372*f4a2713aSLionel Sambuc 373*f4a2713aSLionel Sambuc // Parse ')'. 374*f4a2713aSLionel Sambuc T.consumeClose(); 375*f4a2713aSLionel Sambuc if (Vars.empty()) 376*f4a2713aSLionel Sambuc return 0; 377*f4a2713aSLionel Sambuc 378*f4a2713aSLionel Sambuc return Actions.ActOnOpenMPVarListClause(Kind, Vars, Loc, LOpen, 379*f4a2713aSLionel Sambuc Tok.getLocation()); 380*f4a2713aSLionel Sambuc } 381*f4a2713aSLionel Sambuc 382