blob: 2f6be9e7876992e391925a924974b3cce8ca6cd9 [file] [log] [blame]
Alexey Bataevc6400582013-03-22 06:34:35 +00001//===--- 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 "clang/AST/ASTConsumer.h"
Alexey Bataev4fa7eab2013-07-19 03:13:43 +000015#include "clang/AST/StmtOpenMP.h"
Alexey Bataevc6400582013-03-22 06:34:35 +000016#include "clang/Parse/ParseDiagnostic.h"
Alexey Bataev6af701f2013-05-13 04:18:18 +000017#include "clang/Parse/Parser.h"
18#include "clang/Sema/Scope.h"
19#include "llvm/ADT/PointerIntPair.h"
Alexey Bataevc6400582013-03-22 06:34:35 +000020#include "RAIIObjectsForParser.h"
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24// OpenMP declarative directives.
25//===----------------------------------------------------------------------===//
26
Alexey Bataev6af701f2013-05-13 04:18:18 +000027/// \brief Parsing of declarative OpenMP directives.
28///
29/// threadprivate-directive:
30/// annot_pragma_openmp 'threadprivate' simple-variable-list
Alexey Bataevc6400582013-03-22 06:34:35 +000031///
32Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
33 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
34
35 SourceLocation Loc = ConsumeToken();
Alexey Bataev6af701f2013-05-13 04:18:18 +000036 SmallVector<Expr *, 5> Identifiers;
37 OpenMPDirectiveKind DKind = Tok.isAnnotation() ?
38 OMPD_unknown :
39 getOpenMPDirectiveKind(PP.getSpelling(Tok));
40
41 switch (DKind) {
Alexey Bataevc6400582013-03-22 06:34:35 +000042 case OMPD_threadprivate:
43 ConsumeToken();
Alexey Bataev6af701f2013-05-13 04:18:18 +000044 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) {
Alexey Bataevc6400582013-03-22 06:34:35 +000045 // The last seen token is annot_pragma_openmp_end - need to check for
46 // extra tokens.
47 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
48 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
49 << getOpenMPDirectiveName(OMPD_threadprivate);
50 SkipUntil(tok::annot_pragma_openmp_end, false, true);
51 }
Alexey Bataev6af701f2013-05-13 04:18:18 +000052 // Skip the last annot_pragma_openmp_end.
Alexey Bataevc6400582013-03-22 06:34:35 +000053 ConsumeToken();
54 return Actions.ActOnOpenMPThreadprivateDirective(Loc,
Alexey Bataevc6400582013-03-22 06:34:35 +000055 Identifiers);
56 }
57 break;
58 case OMPD_unknown:
59 Diag(Tok, diag::err_omp_unknown_directive);
60 break;
Alexey Bataev4fa7eab2013-07-19 03:13:43 +000061 case OMPD_parallel:
62 case OMPD_task:
63 case NUM_OPENMP_DIRECTIVES:
Alexey Bataevc6400582013-03-22 06:34:35 +000064 Diag(Tok, diag::err_omp_unexpected_directive)
Alexey Bataev6af701f2013-05-13 04:18:18 +000065 << getOpenMPDirectiveName(DKind);
Alexey Bataevc6400582013-03-22 06:34:35 +000066 break;
67 }
68 SkipUntil(tok::annot_pragma_openmp_end, false);
69 return DeclGroupPtrTy();
70}
71
Alexey Bataev4fa7eab2013-07-19 03:13:43 +000072/// \brief Parsing of declarative or executable OpenMP directives.
73///
74/// threadprivate-directive:
75/// annot_pragma_openmp 'threadprivate' simple-variable-list
76/// annot_pragma_openmp_end
77///
78/// parallel-directive:
79/// annot_pragma_openmp 'parallel' {clause} annot_pragma_openmp_end
80///
81StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
82 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
83 SmallVector<Expr *, 5> Identifiers;
84 SmallVector<OMPClause *, 5> Clauses;
85 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, NUM_OPENMP_CLAUSES>
86 FirstClauses(NUM_OPENMP_CLAUSES);
87 const unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope;
88 SourceLocation Loc = ConsumeToken(), EndLoc;
89 OpenMPDirectiveKind DKind = Tok.isAnnotation() ?
90 OMPD_unknown :
91 getOpenMPDirectiveKind(PP.getSpelling(Tok));
92 StmtResult Directive = StmtError();
93
94 switch (DKind) {
95 case OMPD_threadprivate:
96 ConsumeToken();
97 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
98 // The last seen token is annot_pragma_openmp_end - need to check for
99 // extra tokens.
100 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
101 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
102 << getOpenMPDirectiveName(OMPD_threadprivate);
103 SkipUntil(tok::annot_pragma_openmp_end, false, true);
104 }
105 DeclGroupPtrTy Res =
106 Actions.ActOnOpenMPThreadprivateDirective(Loc,
107 Identifiers);
108 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
109 }
110 SkipUntil(tok::annot_pragma_openmp_end, false);
111 break;
112 case OMPD_parallel: {
113 ConsumeToken();
114 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
115 OpenMPClauseKind CKind = Tok.isAnnotation() ?
116 OMPC_unknown :
117 getOpenMPClauseKind(PP.getSpelling(Tok));
118 OMPClause *Clause = ParseOpenMPClause(DKind, CKind,
119 !FirstClauses[CKind].getInt());
120 FirstClauses[CKind].setInt(true);
121 if (Clause) {
122 FirstClauses[CKind].setPointer(Clause);
123 Clauses.push_back(Clause);
124 }
125
126 // Skip ',' if any.
127 if (Tok.is(tok::comma))
128 ConsumeToken();
129 }
130 // End location of the directive.
131 EndLoc = Tok.getLocation();
132 // Consume final annot_pragma_openmp_end.
133 ConsumeToken();
134
135 StmtResult AssociatedStmt;
136 bool CreateDirective = true;
137 ParseScope OMPDirectiveScope(this, ScopeFlags);
138 {
139 // The body is a block scope like in Lambdas and Blocks.
140 Sema::CompoundScopeRAII CompoundScope(Actions);
141 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default, 1);
142 Actions.ActOnStartOfCompoundStmt();
143 // Parse statement
144 AssociatedStmt = ParseStatement();
145 Actions.ActOnFinishOfCompoundStmt();
146 if (!AssociatedStmt.isUsable()) {
147 Actions.ActOnCapturedRegionError();
148 CreateDirective = false;
149 } else {
150 AssociatedStmt = Actions.ActOnCapturedRegionEnd(AssociatedStmt.take());
151 CreateDirective = AssociatedStmt.isUsable();
152 }
153 }
154 if (CreateDirective)
155 Directive = Actions.ActOnOpenMPExecutableDirective(DKind, Clauses,
156 AssociatedStmt.take(),
157 Loc, EndLoc);
158
159 // Exit scope.
160 OMPDirectiveScope.Exit();
161 }
162 break;
163 case OMPD_unknown:
164 Diag(Tok, diag::err_omp_unknown_directive);
165 SkipUntil(tok::annot_pragma_openmp_end, false);
166 break;
167 case OMPD_task:
168 case NUM_OPENMP_DIRECTIVES:
169 Diag(Tok, diag::err_omp_unexpected_directive)
170 << getOpenMPDirectiveName(DKind);
171 SkipUntil(tok::annot_pragma_openmp_end, false);
172 break;
173 }
174 return Directive;
175}
176
Alexey Bataevc6400582013-03-22 06:34:35 +0000177/// \brief Parses list of simple variables for '#pragma omp threadprivate'
Alexey Bataev6af701f2013-05-13 04:18:18 +0000178/// directive.
Alexey Bataevc6400582013-03-22 06:34:35 +0000179///
Alexey Bataev6af701f2013-05-13 04:18:18 +0000180/// simple-variable-list:
181/// '(' id-expression {, id-expression} ')'
182///
183bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
184 SmallVectorImpl<Expr *> &VarList,
185 bool AllowScopeSpecifier) {
186 VarList.clear();
Alexey Bataevc6400582013-03-22 06:34:35 +0000187 // Parse '('.
Alexey Bataev6af701f2013-05-13 04:18:18 +0000188 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +0000189 if (T.expectAndConsume(diag::err_expected_lparen_after,
190 getOpenMPDirectiveName(Kind)))
191 return true;
192 bool IsCorrect = true;
Alexey Bataev6af701f2013-05-13 04:18:18 +0000193 bool NoIdentIsFound = true;
Alexey Bataevc6400582013-03-22 06:34:35 +0000194
195 // Read tokens while ')' or annot_pragma_openmp_end is not found.
Alexey Bataev6af701f2013-05-13 04:18:18 +0000196 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataevc6400582013-03-22 06:34:35 +0000197 CXXScopeSpec SS;
198 SourceLocation TemplateKWLoc;
199 UnqualifiedId Name;
200 // Read var name.
201 Token PrevTok = Tok;
Alexey Bataev6af701f2013-05-13 04:18:18 +0000202 NoIdentIsFound = false;
Alexey Bataevc6400582013-03-22 06:34:35 +0000203
Alexey Bataev6af701f2013-05-13 04:18:18 +0000204 if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
205 ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) {
Alexey Bataevc6400582013-03-22 06:34:35 +0000206 IsCorrect = false;
207 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
208 false, true);
Alexey Bataev6af701f2013-05-13 04:18:18 +0000209 } else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(),
210 TemplateKWLoc, Name)) {
Alexey Bataevc6400582013-03-22 06:34:35 +0000211 IsCorrect = false;
212 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
213 false, true);
Alexey Bataev6af701f2013-05-13 04:18:18 +0000214 } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
215 Tok.isNot(tok::annot_pragma_openmp_end)) {
216 IsCorrect = false;
217 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
218 false, true);
219 Diag(PrevTok.getLocation(), diag::err_expected_ident)
Alexey Bataevc6400582013-03-22 06:34:35 +0000220 << SourceRange(PrevTok.getLocation(), PrevTokLocation);
221 } else {
Alexey Bataev6af701f2013-05-13 04:18:18 +0000222 DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
223 ExprResult Res = Actions.ActOnOpenMPIdExpression(getCurScope(), SS,
224 NameInfo);
225 if (Res.isUsable())
226 VarList.push_back(Res.take());
Alexey Bataevc6400582013-03-22 06:34:35 +0000227 }
228 // Consume ','.
229 if (Tok.is(tok::comma)) {
230 ConsumeToken();
231 }
Alexey Bataevc6400582013-03-22 06:34:35 +0000232 }
233
Alexey Bataev6af701f2013-05-13 04:18:18 +0000234 if (NoIdentIsFound) {
235 Diag(Tok, diag::err_expected_ident);
236 IsCorrect = false;
237 }
238
239 // Parse ')'.
Alexey Bataev4fa7eab2013-07-19 03:13:43 +0000240 IsCorrect = !T.consumeClose() && IsCorrect;
Alexey Bataev6af701f2013-05-13 04:18:18 +0000241
242 return !IsCorrect && VarList.empty();
Alexey Bataevc6400582013-03-22 06:34:35 +0000243}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +0000244
245/// \brief Parsing of OpenMP clauses.
246///
247/// clause:
248/// default-clause|private-clause
249///
250OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
251 OpenMPClauseKind CKind, bool FirstClause) {
252 OMPClause *Clause = 0;
253 bool ErrorFound = false;
254 // Check if clause is allowed for the given directive.
255 if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
256 Diag(Tok, diag::err_omp_unexpected_clause)
257 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
258 ErrorFound = true;
259 }
260
261 switch (CKind) {
262 case OMPC_default:
263 // OpenMP [2.9.3.1, Restrictions]
264 // Only a single default clause may be specified on a parallel or task
265 // directive.
266 if (!FirstClause) {
267 Diag(Tok, diag::err_omp_more_one_clause)
268 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind);
269 }
270
271 Clause = ParseOpenMPSimpleClause(CKind);
272 break;
273 case OMPC_private:
274 Clause = ParseOpenMPVarListClause(CKind);
275 break;
276 case OMPC_unknown:
277 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
278 << getOpenMPDirectiveName(DKind);
279 SkipUntil(tok::annot_pragma_openmp_end, false, true);
280 break;
281 case OMPC_threadprivate:
282 case NUM_OPENMP_CLAUSES:
283 Diag(Tok, diag::err_omp_unexpected_clause)
284 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
285 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, false, true);
286 break;
287 }
288 return ErrorFound ? 0 : Clause;
289}
290
291/// \brief Parsing of simple OpenMP clauses like 'default'.
292///
293/// default-clause:
294/// 'default' '(' 'none' | 'shared' ')
295///
296OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
297 SourceLocation Loc = Tok.getLocation();
298 SourceLocation LOpen = ConsumeToken();
299 // Parse '('.
300 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
301 if (T.expectAndConsume(diag::err_expected_lparen_after,
302 getOpenMPClauseName(Kind)))
303 return 0;
304
305 unsigned Type = Tok.isAnnotation() ?
306 OMPC_DEFAULT_unknown :
307 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
308 SourceLocation TypeLoc = Tok.getLocation();
309 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
310 Tok.isNot(tok::annot_pragma_openmp_end))
311 ConsumeAnyToken();
312
313 // Parse ')'.
314 T.consumeClose();
315
316 return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
317 Tok.getLocation());
318}
319
320/// \brief Parsing of OpenMP clause 'private', 'firstprivate',
321/// 'shared', 'copyin', or 'reduction'.
322///
323/// private-clause:
324/// 'private' '(' list ')'
325///
326OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
327 SourceLocation Loc = Tok.getLocation();
328 SourceLocation LOpen = ConsumeToken();
329 // Parse '('.
330 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
331 if (T.expectAndConsume(diag::err_expected_lparen_after,
332 getOpenMPClauseName(Kind)))
333 return 0;
334
335 SmallVector<Expr *, 5> Vars;
336 bool IsComma = true;
337 while (IsComma || (Tok.isNot(tok::r_paren) &&
338 Tok.isNot(tok::annot_pragma_openmp_end))) {
339 // Parse variable
340 ExprResult VarExpr = ParseAssignmentExpression();
341 if (VarExpr.isUsable()) {
342 Vars.push_back(VarExpr.take());
343 } else {
344 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
345 false, true);
346 }
347 // Skip ',' if any
348 IsComma = Tok.is(tok::comma);
349 if (IsComma) {
350 ConsumeToken();
351 } else if (Tok.isNot(tok::r_paren) &&
352 Tok.isNot(tok::annot_pragma_openmp_end)) {
353 Diag(Tok, diag::err_omp_expected_punc)
354 << 1 << getOpenMPClauseName(Kind);
355 }
356 }
357
358 // Parse ')'.
359 T.consumeClose();
360 if (Vars.empty())
361 return 0;
362
363 return Actions.ActOnOpenMPVarListClause(Kind, Vars, Loc, LOpen,
364 Tok.getLocation());
365}
366