xref: /minix3/external/bsd/llvm/dist/clang/lib/Parse/ParseOpenMP.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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