blob: 2d5afd6042d264ac2551b7744774b6a4549f8545 [file] [log] [blame]
Alexey Bataeva769e072013-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
Chandler Carruth5553d0d2014-01-07 11:51:46 +000014#include "RAIIObjectsForParser.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000015#include "clang/AST/ASTConsumer.h"
16#include "clang/AST/ASTContext.h"
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000017#include "clang/AST/StmtOpenMP.h"
Alexey Bataeva769e072013-03-22 06:34:35 +000018#include "clang/Parse/ParseDiagnostic.h"
Alexey Bataev6f6f3b42013-05-13 04:18:18 +000019#include "clang/Parse/Parser.h"
20#include "clang/Sema/Scope.h"
21#include "llvm/ADT/PointerIntPair.h"
Michael Wong65f367f2015-07-21 13:44:28 +000022
Alexey Bataeva769e072013-03-22 06:34:35 +000023using namespace clang;
24
25//===----------------------------------------------------------------------===//
26// OpenMP declarative directives.
27//===----------------------------------------------------------------------===//
28
Dmitry Polukhin82478332016-02-13 06:53:38 +000029namespace {
30enum OpenMPDirectiveKindEx {
31 OMPD_cancellation = OMPD_unknown + 1,
32 OMPD_data,
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000033 OMPD_declare,
Dmitry Polukhin82478332016-02-13 06:53:38 +000034 OMPD_enter,
35 OMPD_exit,
36 OMPD_point,
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000037 OMPD_reduction,
Dmitry Polukhin82478332016-02-13 06:53:38 +000038 OMPD_target_enter,
39 OMPD_target_exit
40};
41} // namespace
42
43// Map token string to extended OMP token kind that are
44// OpenMPDirectiveKind + OpenMPDirectiveKindEx.
45static unsigned getOpenMPDirectiveKindEx(StringRef S) {
46 auto DKind = getOpenMPDirectiveKind(S);
47 if (DKind != OMPD_unknown)
48 return DKind;
49
50 return llvm::StringSwitch<unsigned>(S)
51 .Case("cancellation", OMPD_cancellation)
52 .Case("data", OMPD_data)
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000053 .Case("declare", OMPD_declare)
Dmitry Polukhin82478332016-02-13 06:53:38 +000054 .Case("enter", OMPD_enter)
55 .Case("exit", OMPD_exit)
56 .Case("point", OMPD_point)
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000057 .Case("reduction", OMPD_reduction)
Dmitry Polukhin82478332016-02-13 06:53:38 +000058 .Default(OMPD_unknown);
59}
60
Alexey Bataev4acb8592014-07-07 13:01:15 +000061static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
Alexander Musmanf82886e2014-09-18 05:12:34 +000062 // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
63 // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
64 // TODO: add other combined directives in topological order.
Dmitry Polukhin82478332016-02-13 06:53:38 +000065 static const unsigned F[][3] = {
66 { OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000067 { OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
Dmitry Polukhin82478332016-02-13 06:53:38 +000068 { OMPD_target, OMPD_data, OMPD_target_data },
69 { OMPD_target, OMPD_enter, OMPD_target_enter },
70 { OMPD_target, OMPD_exit, OMPD_target_exit },
71 { OMPD_target_enter, OMPD_data, OMPD_target_enter_data },
72 { OMPD_target_exit, OMPD_data, OMPD_target_exit_data },
73 { OMPD_for, OMPD_simd, OMPD_for_simd },
74 { OMPD_parallel, OMPD_for, OMPD_parallel_for },
75 { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd },
76 { OMPD_parallel, OMPD_sections, OMPD_parallel_sections },
77 { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd },
78 { OMPD_target, OMPD_parallel, OMPD_target_parallel },
79 { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for }
80 };
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000081 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
Alexey Bataev4acb8592014-07-07 13:01:15 +000082 auto Tok = P.getCurToken();
Dmitry Polukhin82478332016-02-13 06:53:38 +000083 unsigned DKind =
Alexey Bataev4acb8592014-07-07 13:01:15 +000084 Tok.isAnnotation()
Dmitry Polukhin82478332016-02-13 06:53:38 +000085 ? static_cast<unsigned>(OMPD_unknown)
86 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
87 if (DKind == OMPD_unknown)
88 return OMPD_unknown;
Michael Wong65f367f2015-07-21 13:44:28 +000089
Alexander Musmanf82886e2014-09-18 05:12:34 +000090 for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
Dmitry Polukhin82478332016-02-13 06:53:38 +000091 if (DKind != F[i][0])
92 continue;
Michael Wong65f367f2015-07-21 13:44:28 +000093
Dmitry Polukhin82478332016-02-13 06:53:38 +000094 Tok = P.getPreprocessor().LookAhead(0);
95 unsigned SDKind =
96 Tok.isAnnotation()
97 ? static_cast<unsigned>(OMPD_unknown)
98 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
99 if (SDKind == OMPD_unknown)
100 continue;
Michael Wong65f367f2015-07-21 13:44:28 +0000101
Dmitry Polukhin82478332016-02-13 06:53:38 +0000102 if (SDKind == F[i][1]) {
103 P.ConsumeToken();
104 DKind = F[i][2];
Alexey Bataev4acb8592014-07-07 13:01:15 +0000105 }
106 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000107 return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
108 : OMPD_unknown;
109}
110
111static DeclarationName parseOpenMPReductionId(Parser &P) {
112 const Token Tok = P.getCurToken();
113 Sema &Actions = P.getActions();
114 OverloadedOperatorKind OOK = OO_None;
115 switch (Tok.getKind()) {
116 case tok::plus: // '+'
117 OOK = OO_Plus;
118 break;
119 case tok::minus: // '-'
120 OOK = OO_Minus;
121 break;
122 case tok::star: // '*'
123 OOK = OO_Star;
124 break;
125 case tok::amp: // '&'
126 OOK = OO_Amp;
127 break;
128 case tok::pipe: // '|'
129 OOK = OO_Pipe;
130 break;
131 case tok::caret: // '^'
132 OOK = OO_Caret;
133 break;
134 case tok::ampamp: // '&&'
135 OOK = OO_AmpAmp;
136 break;
137 case tok::pipepipe: // '||'
138 OOK = OO_PipePipe;
139 break;
140 case tok::identifier: // identifier
141 break;
142 default:
143 P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
144 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
145 Parser::StopBeforeMatch);
146 return DeclarationName();
147 }
148 P.ConsumeToken();
149 auto &DeclNames = Actions.getASTContext().DeclarationNames;
150 return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
151 : DeclNames.getCXXOperatorName(OOK);
152}
153
154/// \brief Parse 'omp declare reduction' construct.
155///
156/// declare-reduction-directive:
157/// annot_pragma_openmp 'declare' 'reduction'
158/// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
159/// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
160/// annot_pragma_openmp_end
161/// <reduction_id> is either a base language identifier or one of the following
162/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
163///
164Parser::DeclGroupPtrTy
165Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
166 // Parse '('.
167 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
168 if (T.expectAndConsume(diag::err_expected_lparen_after,
169 getOpenMPDirectiveName(OMPD_declare_reduction))) {
170 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
171 return DeclGroupPtrTy();
172 }
173
174 DeclarationName Name = parseOpenMPReductionId(*this);
175 if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
176 return DeclGroupPtrTy();
177
178 // Consume ':'.
179 bool IsCorrect = !ExpectAndConsume(tok::colon);
180
181 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
182 return DeclGroupPtrTy();
183
184 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
185 Diag(Tok.getLocation(), diag::err_expected_type);
186 IsCorrect = false;
187 }
188
189 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
190 return DeclGroupPtrTy();
191
192 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
193 // Parse list of types until ':' token.
194 do {
195 ColonProtectionRAIIObject ColonRAII(*this);
196 SourceRange Range;
197 TypeResult TR = ParseTypeName(&Range, Declarator::PrototypeContext, AS);
198 if (TR.isUsable()) {
199 auto ReductionType =
200 Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
201 if (!ReductionType.isNull()) {
202 ReductionTypes.push_back(
203 std::make_pair(ReductionType, Range.getBegin()));
204 }
205 } else {
206 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
207 StopBeforeMatch);
208 }
209
210 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
211 break;
212
213 // Consume ','.
214 if (ExpectAndConsume(tok::comma)) {
215 IsCorrect = false;
216 if (Tok.is(tok::annot_pragma_openmp_end)) {
217 Diag(Tok.getLocation(), diag::err_expected_type);
218 return DeclGroupPtrTy();
219 }
220 }
221 } while (Tok.isNot(tok::annot_pragma_openmp_end));
222
223 if (ReductionTypes.empty()) {
224 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
225 return DeclGroupPtrTy();
226 }
227
228 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
229 return DeclGroupPtrTy();
230
231 // Consume ':'.
232 if (ExpectAndConsume(tok::colon))
233 IsCorrect = false;
234
235 if (Tok.is(tok::annot_pragma_openmp_end)) {
236 Diag(Tok.getLocation(), diag::err_expected_expression);
237 return DeclGroupPtrTy();
238 }
239
240 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
241 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
242
243 // Parse <combiner> expression and then parse initializer if any for each
244 // correct type.
245 unsigned I = 0, E = ReductionTypes.size();
246 for (auto *D : DRD.get()) {
247 TentativeParsingAction TPA(*this);
248 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
249 Scope::OpenMPDirectiveScope);
250 // Parse <combiner> expression.
251 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
252 ExprResult CombinerResult =
253 Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
254 D->getLocation(), /*DiscardedValue=*/true);
255 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
256
257 if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
258 Tok.isNot(tok::annot_pragma_openmp_end)) {
259 TPA.Commit();
260 IsCorrect = false;
261 break;
262 }
263 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
264 ExprResult InitializerResult;
265 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
266 // Parse <initializer> expression.
267 if (Tok.is(tok::identifier) &&
268 Tok.getIdentifierInfo()->isStr("initializer"))
269 ConsumeToken();
270 else {
271 Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
272 TPA.Commit();
273 IsCorrect = false;
274 break;
275 }
276 // Parse '('.
277 BalancedDelimiterTracker T(*this, tok::l_paren,
278 tok::annot_pragma_openmp_end);
279 IsCorrect =
280 !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
281 IsCorrect;
282 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
283 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
284 Scope::OpenMPDirectiveScope);
285 // Parse expression.
286 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), D);
287 InitializerResult = Actions.ActOnFinishFullExpr(
288 ParseAssignmentExpression().get(), D->getLocation(),
289 /*DiscardedValue=*/true);
290 Actions.ActOnOpenMPDeclareReductionInitializerEnd(
291 D, InitializerResult.get());
292 if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
293 Tok.isNot(tok::annot_pragma_openmp_end)) {
294 TPA.Commit();
295 IsCorrect = false;
296 break;
297 }
298 IsCorrect =
299 !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
300 }
301 }
302
303 ++I;
304 // Revert parsing if not the last type, otherwise accept it, we're done with
305 // parsing.
306 if (I != E)
307 TPA.Revert();
308 else
309 TPA.Commit();
310 }
311 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
312 IsCorrect);
Alexey Bataev4acb8592014-07-07 13:01:15 +0000313}
314
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000315/// \brief Parsing of declarative OpenMP directives.
316///
317/// threadprivate-directive:
318/// annot_pragma_openmp 'threadprivate' simple-variable-list
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000319/// annot_pragma_openmp_end
Alexey Bataeva769e072013-03-22 06:34:35 +0000320///
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000321/// declare-reduction-directive:
322/// annot_pragma_openmp 'declare' 'reduction' [...]
323/// annot_pragma_openmp_end
324///
325Parser::DeclGroupPtrTy
326Parser::ParseOpenMPDeclarativeDirective(AccessSpecifier AS) {
Alexey Bataeva769e072013-03-22 06:34:35 +0000327 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
Alexey Bataevee6507d2013-11-18 08:17:37 +0000328 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Alexey Bataeva769e072013-03-22 06:34:35 +0000329
330 SourceLocation Loc = ConsumeToken();
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000331 SmallVector<Expr *, 5> Identifiers;
Alexey Bataev4acb8592014-07-07 13:01:15 +0000332 auto DKind = ParseOpenMPDirectiveKind(*this);
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000333
334 switch (DKind) {
Alexey Bataeva769e072013-03-22 06:34:35 +0000335 case OMPD_threadprivate:
336 ConsumeToken();
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000337 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) {
Alexey Bataeva769e072013-03-22 06:34:35 +0000338 // The last seen token is annot_pragma_openmp_end - need to check for
339 // extra tokens.
340 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
341 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
Alexey Bataeva55ed262014-05-28 06:15:33 +0000342 << getOpenMPDirectiveName(OMPD_threadprivate);
Alp Tokerd751fa72013-12-18 19:10:49 +0000343 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataeva769e072013-03-22 06:34:35 +0000344 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000345 // Skip the last annot_pragma_openmp_end.
Alexey Bataeva769e072013-03-22 06:34:35 +0000346 ConsumeToken();
Alexey Bataeva55ed262014-05-28 06:15:33 +0000347 return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
Alexey Bataeva769e072013-03-22 06:34:35 +0000348 }
349 break;
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000350 case OMPD_declare_reduction:
351 ConsumeToken();
352 if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) {
353 // The last seen token is annot_pragma_openmp_end - need to check for
354 // extra tokens.
355 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
356 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
357 << getOpenMPDirectiveName(OMPD_declare_reduction);
358 while (Tok.isNot(tok::annot_pragma_openmp_end))
359 ConsumeAnyToken();
360 }
361 // Skip the last annot_pragma_openmp_end.
362 ConsumeToken();
363 return Res;
364 }
365 break;
Alexey Bataeva769e072013-03-22 06:34:35 +0000366 case OMPD_unknown:
367 Diag(Tok, diag::err_omp_unknown_directive);
368 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000369 case OMPD_parallel:
Alexey Bataev1b59ab52014-02-27 08:29:12 +0000370 case OMPD_simd:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000371 case OMPD_task:
Alexey Bataev68446b72014-07-18 07:47:19 +0000372 case OMPD_taskyield:
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000373 case OMPD_barrier:
Alexey Bataev2df347a2014-07-18 10:17:07 +0000374 case OMPD_taskwait:
Alexey Bataevc30dd2d2015-06-18 12:14:09 +0000375 case OMPD_taskgroup:
Alexey Bataev6125da92014-07-21 11:26:11 +0000376 case OMPD_flush:
Alexey Bataevf29276e2014-06-18 04:14:57 +0000377 case OMPD_for:
Alexander Musmanf82886e2014-09-18 05:12:34 +0000378 case OMPD_for_simd:
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000379 case OMPD_sections:
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000380 case OMPD_section:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000381 case OMPD_single:
Alexander Musman80c22892014-07-17 08:54:58 +0000382 case OMPD_master:
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000383 case OMPD_ordered:
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000384 case OMPD_critical:
Alexey Bataev4acb8592014-07-07 13:01:15 +0000385 case OMPD_parallel_for:
Alexander Musmane4e893b2014-09-23 09:33:00 +0000386 case OMPD_parallel_for_simd:
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000387 case OMPD_parallel_sections:
Alexey Bataev0162e452014-07-22 10:10:35 +0000388 case OMPD_atomic:
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000389 case OMPD_target:
Alexey Bataev13314bf2014-10-09 04:18:56 +0000390 case OMPD_teams:
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000391 case OMPD_cancellation_point:
Alexey Bataev80909872015-07-02 11:25:17 +0000392 case OMPD_cancel:
Samuel Antao5b0688e2015-07-22 16:02:46 +0000393 case OMPD_target_data:
Samuel Antaodf67fc42016-01-19 19:15:56 +0000394 case OMPD_target_enter_data:
Samuel Antao72590762016-01-19 20:04:50 +0000395 case OMPD_target_exit_data:
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +0000396 case OMPD_target_parallel:
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +0000397 case OMPD_target_parallel_for:
Alexey Bataev49f6e782015-12-01 04:18:41 +0000398 case OMPD_taskloop:
Alexey Bataev0a6ed842015-12-03 09:40:15 +0000399 case OMPD_taskloop_simd:
Carlo Bertolli6200a3d2015-12-14 14:51:25 +0000400 case OMPD_distribute:
Alexey Bataeva769e072013-03-22 06:34:35 +0000401 Diag(Tok, diag::err_omp_unexpected_directive)
Alexey Bataeva55ed262014-05-28 06:15:33 +0000402 << getOpenMPDirectiveName(DKind);
Alexey Bataeva769e072013-03-22 06:34:35 +0000403 break;
404 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000405 while (Tok.isNot(tok::annot_pragma_openmp_end))
406 ConsumeAnyToken();
407 ConsumeAnyToken();
David Blaikie0403cb12016-01-15 23:43:25 +0000408 return nullptr;
Alexey Bataeva769e072013-03-22 06:34:35 +0000409}
410
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000411/// \brief Parsing of declarative or executable OpenMP directives.
412///
413/// threadprivate-directive:
414/// annot_pragma_openmp 'threadprivate' simple-variable-list
415/// annot_pragma_openmp_end
416///
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000417/// declare-reduction-directive:
418/// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
419/// <type> {',' <type>} ':' <expression> ')' ['initializer' '('
420/// ('omp_priv' '=' <expression>|<function_call>) ')']
421/// annot_pragma_openmp_end
422///
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000423/// executable-directive:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000424/// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000425/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
426/// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
Alexander Musmanf82886e2014-09-18 05:12:34 +0000427/// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
Michael Wong65f367f2015-07-21 13:44:28 +0000428/// 'for simd' | 'parallel for simd' | 'target' | 'target data' |
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +0000429/// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +0000430/// 'distribute' | 'target enter data' | 'target exit data' |
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +0000431/// 'target parallel' | 'target parallel for' {clause}
Samuel Antao72590762016-01-19 20:04:50 +0000432/// annot_pragma_openmp_end
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000433///
Alexey Bataevc4fad652016-01-13 11:18:54 +0000434StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
435 AllowedContsructsKind Allowed) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000436 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
Alexey Bataevee6507d2013-11-18 08:17:37 +0000437 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000438 SmallVector<Expr *, 5> Identifiers;
439 SmallVector<OMPClause *, 5> Clauses;
Alexey Bataev4ca40ed2014-05-12 04:23:46 +0000440 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
Alexey Bataeva55ed262014-05-28 06:15:33 +0000441 FirstClauses(OMPC_unknown + 1);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +0000442 unsigned ScopeFlags =
Alexey Bataeva55ed262014-05-28 06:15:33 +0000443 Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000444 SourceLocation Loc = ConsumeToken(), EndLoc;
Alexey Bataev4acb8592014-07-07 13:01:15 +0000445 auto DKind = ParseOpenMPDirectiveKind(*this);
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000446 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000447 // Name of critical directive.
448 DeclarationNameInfo DirName;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000449 StmtResult Directive = StmtError();
Alexey Bataev68446b72014-07-18 07:47:19 +0000450 bool HasAssociatedStatement = true;
Alexey Bataev6125da92014-07-21 11:26:11 +0000451 bool FlushHasClause = false;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000452
453 switch (DKind) {
454 case OMPD_threadprivate:
Alexey Bataevc4fad652016-01-13 11:18:54 +0000455 if (Allowed != ACK_Any) {
456 Diag(Tok, diag::err_omp_immediate_directive)
457 << getOpenMPDirectiveName(DKind) << 0;
458 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000459 ConsumeToken();
460 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
461 // The last seen token is annot_pragma_openmp_end - need to check for
462 // extra tokens.
463 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
464 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
Alexey Bataeva55ed262014-05-28 06:15:33 +0000465 << getOpenMPDirectiveName(OMPD_threadprivate);
Alp Tokerd751fa72013-12-18 19:10:49 +0000466 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000467 }
468 DeclGroupPtrTy Res =
Alexey Bataeva55ed262014-05-28 06:15:33 +0000469 Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000470 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
471 }
Alp Tokerd751fa72013-12-18 19:10:49 +0000472 SkipUntil(tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000473 break;
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000474 case OMPD_declare_reduction:
475 ConsumeToken();
476 if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
477 // The last seen token is annot_pragma_openmp_end - need to check for
478 // extra tokens.
479 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
480 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
481 << getOpenMPDirectiveName(OMPD_declare_reduction);
482 while (Tok.isNot(tok::annot_pragma_openmp_end))
483 ConsumeAnyToken();
484 }
485 ConsumeAnyToken();
486 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
487 } else
488 SkipUntil(tok::annot_pragma_openmp_end);
489 break;
Alexey Bataev6125da92014-07-21 11:26:11 +0000490 case OMPD_flush:
491 if (PP.LookAhead(0).is(tok::l_paren)) {
492 FlushHasClause = true;
493 // Push copy of the current token back to stream to properly parse
494 // pseudo-clause OMPFlushClause.
495 PP.EnterToken(Tok);
496 }
Alexey Bataev68446b72014-07-18 07:47:19 +0000497 case OMPD_taskyield:
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000498 case OMPD_barrier:
Alexey Bataev2df347a2014-07-18 10:17:07 +0000499 case OMPD_taskwait:
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000500 case OMPD_cancellation_point:
Alexey Bataev80909872015-07-02 11:25:17 +0000501 case OMPD_cancel:
Samuel Antaodf67fc42016-01-19 19:15:56 +0000502 case OMPD_target_enter_data:
Samuel Antao72590762016-01-19 20:04:50 +0000503 case OMPD_target_exit_data:
Alexey Bataevc4fad652016-01-13 11:18:54 +0000504 if (Allowed == ACK_StatementsOpenMPNonStandalone) {
Alexey Bataev68446b72014-07-18 07:47:19 +0000505 Diag(Tok, diag::err_omp_immediate_directive)
Alexey Bataeveb482352015-12-18 05:05:56 +0000506 << getOpenMPDirectiveName(DKind) << 0;
Alexey Bataev68446b72014-07-18 07:47:19 +0000507 }
508 HasAssociatedStatement = false;
Alexey Bataev6125da92014-07-21 11:26:11 +0000509 // Fall through for further analysis.
Alexey Bataev1b59ab52014-02-27 08:29:12 +0000510 case OMPD_parallel:
Alexey Bataevf29276e2014-06-18 04:14:57 +0000511 case OMPD_simd:
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000512 case OMPD_for:
Alexander Musmanf82886e2014-09-18 05:12:34 +0000513 case OMPD_for_simd:
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000514 case OMPD_sections:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000515 case OMPD_single:
Alexey Bataev4acb8592014-07-07 13:01:15 +0000516 case OMPD_section:
Alexander Musman80c22892014-07-17 08:54:58 +0000517 case OMPD_master:
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000518 case OMPD_critical:
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000519 case OMPD_parallel_for:
Alexander Musmane4e893b2014-09-23 09:33:00 +0000520 case OMPD_parallel_for_simd:
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000521 case OMPD_parallel_sections:
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000522 case OMPD_task:
Alexey Bataev0162e452014-07-22 10:10:35 +0000523 case OMPD_ordered:
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000524 case OMPD_atomic:
Alexey Bataev13314bf2014-10-09 04:18:56 +0000525 case OMPD_target:
Alexey Bataevc30dd2d2015-06-18 12:14:09 +0000526 case OMPD_teams:
Michael Wong65f367f2015-07-21 13:44:28 +0000527 case OMPD_taskgroup:
Alexey Bataev49f6e782015-12-01 04:18:41 +0000528 case OMPD_target_data:
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +0000529 case OMPD_target_parallel:
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +0000530 case OMPD_target_parallel_for:
Alexey Bataev0a6ed842015-12-03 09:40:15 +0000531 case OMPD_taskloop:
Carlo Bertolli6200a3d2015-12-14 14:51:25 +0000532 case OMPD_taskloop_simd:
533 case OMPD_distribute: {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000534 ConsumeToken();
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000535 // Parse directive name of the 'critical' directive if any.
536 if (DKind == OMPD_critical) {
537 BalancedDelimiterTracker T(*this, tok::l_paren,
538 tok::annot_pragma_openmp_end);
539 if (!T.consumeOpen()) {
540 if (Tok.isAnyIdentifier()) {
541 DirName =
542 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
543 ConsumeAnyToken();
544 } else {
545 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
546 }
547 T.consumeClose();
548 }
Alexey Bataev80909872015-07-02 11:25:17 +0000549 } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000550 CancelRegion = ParseOpenMPDirectiveKind(*this);
551 if (Tok.isNot(tok::annot_pragma_openmp_end))
552 ConsumeToken();
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000553 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000554
Alexey Bataevf29276e2014-06-18 04:14:57 +0000555 if (isOpenMPLoopDirective(DKind))
556 ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
557 if (isOpenMPSimdDirective(DKind))
558 ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
559 ParseScope OMPDirectiveScope(this, ScopeFlags);
Alexey Bataevbae9a792014-06-27 10:37:06 +0000560 Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
Alexey Bataev758e55e2013-09-06 18:03:48 +0000561
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000562 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataev6125da92014-07-21 11:26:11 +0000563 OpenMPClauseKind CKind =
564 Tok.isAnnotation()
565 ? OMPC_unknown
566 : FlushHasClause ? OMPC_flush
567 : getOpenMPClauseKind(PP.getSpelling(Tok));
Alexey Bataevaac108a2015-06-23 04:51:00 +0000568 Actions.StartOpenMPClause(CKind);
Alexey Bataev6125da92014-07-21 11:26:11 +0000569 FlushHasClause = false;
Alexey Bataeva55ed262014-05-28 06:15:33 +0000570 OMPClause *Clause =
571 ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000572 FirstClauses[CKind].setInt(true);
573 if (Clause) {
574 FirstClauses[CKind].setPointer(Clause);
575 Clauses.push_back(Clause);
576 }
577
578 // Skip ',' if any.
579 if (Tok.is(tok::comma))
580 ConsumeToken();
Alexey Bataevaac108a2015-06-23 04:51:00 +0000581 Actions.EndOpenMPClause();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000582 }
583 // End location of the directive.
584 EndLoc = Tok.getLocation();
585 // Consume final annot_pragma_openmp_end.
586 ConsumeToken();
587
Alexey Bataeveb482352015-12-18 05:05:56 +0000588 // OpenMP [2.13.8, ordered Construct, Syntax]
589 // If the depend clause is specified, the ordered construct is a stand-alone
590 // directive.
591 if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
Alexey Bataevc4fad652016-01-13 11:18:54 +0000592 if (Allowed == ACK_StatementsOpenMPNonStandalone) {
Alexey Bataeveb482352015-12-18 05:05:56 +0000593 Diag(Loc, diag::err_omp_immediate_directive)
594 << getOpenMPDirectiveName(DKind) << 1
595 << getOpenMPClauseName(OMPC_depend);
596 }
597 HasAssociatedStatement = false;
598 }
599
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000600 StmtResult AssociatedStmt;
Alexey Bataev68446b72014-07-18 07:47:19 +0000601 if (HasAssociatedStatement) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000602 // The body is a block scope like in Lambdas and Blocks.
603 Sema::CompoundScopeRAII CompoundScope(Actions);
Alexey Bataevbae9a792014-06-27 10:37:06 +0000604 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000605 Actions.ActOnStartOfCompoundStmt();
606 // Parse statement
607 AssociatedStmt = ParseStatement();
608 Actions.ActOnFinishOfCompoundStmt();
Alexey Bataeva8d4a5432015-04-02 07:48:16 +0000609 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000610 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000611 Directive = Actions.ActOnOpenMPExecutableDirective(
612 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
613 EndLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000614
615 // Exit scope.
Alexey Bataev758e55e2013-09-06 18:03:48 +0000616 Actions.EndOpenMPDSABlock(Directive.get());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000617 OMPDirectiveScope.Exit();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000618 break;
Alexey Bataeva55ed262014-05-28 06:15:33 +0000619 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000620 case OMPD_unknown:
621 Diag(Tok, diag::err_omp_unknown_directive);
Alp Tokerd751fa72013-12-18 19:10:49 +0000622 SkipUntil(tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000623 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000624 }
625 return Directive;
626}
627
Alexey Bataeva769e072013-03-22 06:34:35 +0000628/// \brief Parses list of simple variables for '#pragma omp threadprivate'
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000629/// directive.
Alexey Bataeva769e072013-03-22 06:34:35 +0000630///
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000631/// simple-variable-list:
632/// '(' id-expression {, id-expression} ')'
633///
634bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
635 SmallVectorImpl<Expr *> &VarList,
636 bool AllowScopeSpecifier) {
637 VarList.clear();
Alexey Bataeva769e072013-03-22 06:34:35 +0000638 // Parse '('.
Alp Tokerd751fa72013-12-18 19:10:49 +0000639 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000640 if (T.expectAndConsume(diag::err_expected_lparen_after,
641 getOpenMPDirectiveName(Kind)))
642 return true;
643 bool IsCorrect = true;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000644 bool NoIdentIsFound = true;
Alexey Bataeva769e072013-03-22 06:34:35 +0000645
646 // Read tokens while ')' or annot_pragma_openmp_end is not found.
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000647 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataeva769e072013-03-22 06:34:35 +0000648 CXXScopeSpec SS;
649 SourceLocation TemplateKWLoc;
650 UnqualifiedId Name;
651 // Read var name.
652 Token PrevTok = Tok;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000653 NoIdentIsFound = false;
Alexey Bataeva769e072013-03-22 06:34:35 +0000654
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000655 if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
David Blaikieefdccaa2016-01-15 23:43:34 +0000656 ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
Alexey Bataeva769e072013-03-22 06:34:35 +0000657 IsCorrect = false;
658 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +0000659 StopBeforeMatch);
David Blaikieefdccaa2016-01-15 23:43:34 +0000660 } else if (ParseUnqualifiedId(SS, false, false, false, nullptr,
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000661 TemplateKWLoc, Name)) {
Alexey Bataeva769e072013-03-22 06:34:35 +0000662 IsCorrect = false;
663 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +0000664 StopBeforeMatch);
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000665 } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
666 Tok.isNot(tok::annot_pragma_openmp_end)) {
667 IsCorrect = false;
668 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +0000669 StopBeforeMatch);
Alp Tokerec543272013-12-24 09:48:30 +0000670 Diag(PrevTok.getLocation(), diag::err_expected)
671 << tok::identifier
672 << SourceRange(PrevTok.getLocation(), PrevTokLocation);
Alexey Bataeva769e072013-03-22 06:34:35 +0000673 } else {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000674 DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
Alexey Bataeva55ed262014-05-28 06:15:33 +0000675 ExprResult Res =
676 Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000677 if (Res.isUsable())
Nikola Smiljanic01a75982014-05-29 10:55:11 +0000678 VarList.push_back(Res.get());
Alexey Bataeva769e072013-03-22 06:34:35 +0000679 }
680 // Consume ','.
681 if (Tok.is(tok::comma)) {
682 ConsumeToken();
683 }
Alexey Bataeva769e072013-03-22 06:34:35 +0000684 }
685
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000686 if (NoIdentIsFound) {
Alp Tokerec543272013-12-24 09:48:30 +0000687 Diag(Tok, diag::err_expected) << tok::identifier;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000688 IsCorrect = false;
689 }
690
691 // Parse ')'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000692 IsCorrect = !T.consumeClose() && IsCorrect;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +0000693
694 return !IsCorrect && VarList.empty();
Alexey Bataeva769e072013-03-22 06:34:35 +0000695}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000696
697/// \brief Parsing of OpenMP clauses.
698///
699/// clause:
Alexey Bataev3778b602014-07-17 07:32:53 +0000700/// if-clause | final-clause | num_threads-clause | safelen-clause |
701/// default-clause | private-clause | firstprivate-clause | shared-clause
702/// | linear-clause | aligned-clause | collapse-clause |
703/// lastprivate-clause | reduction-clause | proc_bind-clause |
Alexey Bataev74ba3a52014-07-17 12:47:03 +0000704/// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
Alexey Bataev67a4f222014-07-23 10:25:33 +0000705/// mergeable-clause | flush-clause | read-clause | write-clause |
Alexey Bataev66b15b52015-08-21 11:14:16 +0000706/// update-clause | capture-clause | seq_cst-clause | device-clause |
Kelvin Lia15fb1a2015-11-27 18:47:36 +0000707/// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
Alexey Bataev1fd4aed2015-12-07 12:52:51 +0000708/// thread_limit-clause | priority-clause | grainsize-clause |
Alexey Bataev28c75412015-12-15 08:19:24 +0000709/// nogroup-clause | num_tasks-clause | hint-clause
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000710///
711OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
712 OpenMPClauseKind CKind, bool FirstClause) {
Craig Topper161e4db2014-05-21 06:02:52 +0000713 OMPClause *Clause = nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000714 bool ErrorFound = false;
715 // Check if clause is allowed for the given directive.
716 if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
Alexey Bataeva55ed262014-05-28 06:15:33 +0000717 Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
718 << getOpenMPDirectiveName(DKind);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000719 ErrorFound = true;
720 }
721
722 switch (CKind) {
Alexey Bataev3778b602014-07-17 07:32:53 +0000723 case OMPC_final:
Alexey Bataev568a8332014-03-06 06:15:19 +0000724 case OMPC_num_threads:
Alexey Bataev62c87d22014-03-21 04:51:18 +0000725 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +0000726 case OMPC_simdlen:
Alexander Musman8bd31e62014-05-27 15:12:19 +0000727 case OMPC_collapse:
Alexey Bataev10e775f2015-07-30 11:36:16 +0000728 case OMPC_ordered:
Michael Wonge710d542015-08-07 16:16:36 +0000729 case OMPC_device:
Kelvin Li099bb8c2015-11-24 20:50:12 +0000730 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +0000731 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +0000732 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +0000733 case OMPC_grainsize:
Alexey Bataev382967a2015-12-08 12:06:20 +0000734 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +0000735 case OMPC_hint:
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000736 // OpenMP [2.5, Restrictions]
Alexey Bataev568a8332014-03-06 06:15:19 +0000737 // At most one num_threads clause can appear on the directive.
Alexey Bataev62c87d22014-03-21 04:51:18 +0000738 // OpenMP [2.8.1, simd construct, Restrictions]
Alexander Musman8bd31e62014-05-27 15:12:19 +0000739 // Only one safelen clause can appear on a simd directive.
Alexey Bataev66b15b52015-08-21 11:14:16 +0000740 // Only one simdlen clause can appear on a simd directive.
Alexander Musman8bd31e62014-05-27 15:12:19 +0000741 // Only one collapse clause can appear on a simd directive.
Michael Wonge710d542015-08-07 16:16:36 +0000742 // OpenMP [2.9.1, target data construct, Restrictions]
743 // At most one device clause can appear on the directive.
Alexey Bataev3778b602014-07-17 07:32:53 +0000744 // OpenMP [2.11.1, task Construct, Restrictions]
745 // At most one if clause can appear on the directive.
746 // At most one final clause can appear on the directive.
Kelvin Li099bb8c2015-11-24 20:50:12 +0000747 // OpenMP [teams Construct, Restrictions]
748 // At most one num_teams clause can appear on the directive.
Kelvin Lia15fb1a2015-11-27 18:47:36 +0000749 // At most one thread_limit clause can appear on the directive.
Alexey Bataeva0569352015-12-01 10:17:31 +0000750 // OpenMP [2.9.1, task Construct, Restrictions]
751 // At most one priority clause can appear on the directive.
Alexey Bataev1fd4aed2015-12-07 12:52:51 +0000752 // OpenMP [2.9.2, taskloop Construct, Restrictions]
753 // At most one grainsize clause can appear on the directive.
Alexey Bataev382967a2015-12-08 12:06:20 +0000754 // OpenMP [2.9.2, taskloop Construct, Restrictions]
755 // At most one num_tasks clause can appear on the directive.
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000756 if (!FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000757 Diag(Tok, diag::err_omp_more_one_clause)
758 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +0000759 ErrorFound = true;
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000760 }
761
Alexey Bataev10e775f2015-07-30 11:36:16 +0000762 if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
763 Clause = ParseOpenMPClause(CKind);
764 else
765 Clause = ParseOpenMPSingleExprClause(CKind);
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000766 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000767 case OMPC_default:
Alexey Bataevbcbadb62014-05-06 06:04:14 +0000768 case OMPC_proc_bind:
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000769 // OpenMP [2.14.3.1, Restrictions]
770 // Only a single default clause may be specified on a parallel, task or
771 // teams directive.
Alexey Bataevbcbadb62014-05-06 06:04:14 +0000772 // OpenMP [2.5, parallel Construct, Restrictions]
773 // At most one proc_bind clause can appear on the directive.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000774 if (!FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000775 Diag(Tok, diag::err_omp_more_one_clause)
776 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +0000777 ErrorFound = true;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000778 }
779
780 Clause = ParseOpenMPSimpleClause(CKind);
781 break;
Alexey Bataev56dafe82014-06-20 07:16:17 +0000782 case OMPC_schedule:
Carlo Bertollib4adf552016-01-15 18:50:31 +0000783 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +0000784 case OMPC_defaultmap:
Alexey Bataev56dafe82014-06-20 07:16:17 +0000785 // OpenMP [2.7.1, Restrictions, p. 3]
786 // Only one schedule clause can appear on a loop directive.
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +0000787 // OpenMP [2.10.4, Restrictions, p. 106]
788 // At most one defaultmap clause can appear on the directive.
Alexey Bataev56dafe82014-06-20 07:16:17 +0000789 if (!FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000790 Diag(Tok, diag::err_omp_more_one_clause)
791 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +0000792 ErrorFound = true;
Alexey Bataev56dafe82014-06-20 07:16:17 +0000793 }
794
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000795 case OMPC_if:
Alexey Bataev56dafe82014-06-20 07:16:17 +0000796 Clause = ParseOpenMPSingleExprWithArgClause(CKind);
797 break;
Alexey Bataev236070f2014-06-20 11:19:47 +0000798 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +0000799 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +0000800 case OMPC_mergeable:
Alexey Bataevf98b00c2014-07-23 02:27:21 +0000801 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +0000802 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +0000803 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +0000804 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +0000805 case OMPC_seq_cst:
Alexey Bataev346265e2015-09-25 10:37:12 +0000806 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +0000807 case OMPC_simd:
Alexey Bataevb825de12015-12-07 10:51:44 +0000808 case OMPC_nogroup:
Alexey Bataev142e1fc2014-06-20 09:44:06 +0000809 // OpenMP [2.7.1, Restrictions, p. 9]
810 // Only one ordered clause can appear on a loop directive.
Alexey Bataev236070f2014-06-20 11:19:47 +0000811 // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
812 // Only one nowait clause can appear on a for directive.
Alexey Bataev142e1fc2014-06-20 09:44:06 +0000813 if (!FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000814 Diag(Tok, diag::err_omp_more_one_clause)
815 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +0000816 ErrorFound = true;
Alexey Bataev142e1fc2014-06-20 09:44:06 +0000817 }
818
819 Clause = ParseOpenMPClause(CKind);
820 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000821 case OMPC_private:
Alexey Bataevd5af8e42013-10-01 05:32:34 +0000822 case OMPC_firstprivate:
Alexander Musman1bb328c2014-06-04 13:06:39 +0000823 case OMPC_lastprivate:
Alexey Bataev758e55e2013-09-06 18:03:48 +0000824 case OMPC_shared:
Alexey Bataevc5e02582014-06-16 07:08:35 +0000825 case OMPC_reduction:
Alexander Musman8dba6642014-04-22 13:09:42 +0000826 case OMPC_linear:
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000827 case OMPC_aligned:
Alexey Bataevd48bcd82014-03-31 03:36:38 +0000828 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +0000829 case OMPC_copyprivate:
Alexey Bataev6125da92014-07-21 11:26:11 +0000830 case OMPC_flush:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +0000831 case OMPC_depend:
Kelvin Li0bff7af2015-11-23 05:32:03 +0000832 case OMPC_map:
Alexey Bataeveb482352015-12-18 05:05:56 +0000833 Clause = ParseOpenMPVarListClause(DKind, CKind);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000834 break;
835 case OMPC_unknown:
836 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
Alexey Bataeva55ed262014-05-28 06:15:33 +0000837 << getOpenMPDirectiveName(DKind);
Alp Tokerd751fa72013-12-18 19:10:49 +0000838 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000839 break;
840 case OMPC_threadprivate:
Alexey Bataeva55ed262014-05-28 06:15:33 +0000841 Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
842 << getOpenMPDirectiveName(DKind);
Alp Tokerd751fa72013-12-18 19:10:49 +0000843 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000844 break;
845 }
Craig Topper161e4db2014-05-21 06:02:52 +0000846 return ErrorFound ? nullptr : Clause;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000847}
848
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000849/// \brief Parsing of OpenMP clauses with single expressions like 'final',
Alexey Bataeva0569352015-12-01 10:17:31 +0000850/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
Alexey Bataev28c75412015-12-15 08:19:24 +0000851/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000852///
Alexey Bataev3778b602014-07-17 07:32:53 +0000853/// final-clause:
854/// 'final' '(' expression ')'
855///
Alexey Bataev62c87d22014-03-21 04:51:18 +0000856/// num_threads-clause:
857/// 'num_threads' '(' expression ')'
858///
859/// safelen-clause:
860/// 'safelen' '(' expression ')'
861///
Alexey Bataev66b15b52015-08-21 11:14:16 +0000862/// simdlen-clause:
863/// 'simdlen' '(' expression ')'
864///
Alexander Musman8bd31e62014-05-27 15:12:19 +0000865/// collapse-clause:
866/// 'collapse' '(' expression ')'
867///
Alexey Bataeva0569352015-12-01 10:17:31 +0000868/// priority-clause:
869/// 'priority' '(' expression ')'
870///
Alexey Bataev1fd4aed2015-12-07 12:52:51 +0000871/// grainsize-clause:
872/// 'grainsize' '(' expression ')'
873///
Alexey Bataev382967a2015-12-08 12:06:20 +0000874/// num_tasks-clause:
875/// 'num_tasks' '(' expression ')'
876///
Alexey Bataev28c75412015-12-15 08:19:24 +0000877/// hint-clause:
878/// 'hint' '(' expression ')'
879///
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000880OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
881 SourceLocation Loc = ConsumeToken();
882
883 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
884 if (T.expectAndConsume(diag::err_expected_lparen_after,
885 getOpenMPClauseName(Kind)))
Craig Topper161e4db2014-05-21 06:02:52 +0000886 return nullptr;
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000887
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000888 SourceLocation ELoc = Tok.getLocation();
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000889 ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
890 ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000891 Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000892
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000893 // Parse ')'.
894 T.consumeClose();
895
896 if (Val.isInvalid())
Craig Topper161e4db2014-05-21 06:02:52 +0000897 return nullptr;
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000898
Alexey Bataeva55ed262014-05-28 06:15:33 +0000899 return Actions.ActOnOpenMPSingleExprClause(
Nikola Smiljanic01a75982014-05-29 10:55:11 +0000900 Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
Alexey Bataevaadd52e2014-02-13 05:29:23 +0000901}
902
Alexey Bataevbcbadb62014-05-06 06:04:14 +0000903/// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000904///
905/// default-clause:
906/// 'default' '(' 'none' | 'shared' ')
907///
Alexey Bataevbcbadb62014-05-06 06:04:14 +0000908/// proc_bind-clause:
909/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
910///
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000911OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
912 SourceLocation Loc = Tok.getLocation();
913 SourceLocation LOpen = ConsumeToken();
914 // Parse '('.
Alp Tokerd751fa72013-12-18 19:10:49 +0000915 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000916 if (T.expectAndConsume(diag::err_expected_lparen_after,
917 getOpenMPClauseName(Kind)))
Craig Topper161e4db2014-05-21 06:02:52 +0000918 return nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000919
Alexey Bataeva55ed262014-05-28 06:15:33 +0000920 unsigned Type = getOpenMPSimpleClauseType(
921 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
Alexey Bataev5ec3eb12013-07-19 03:13:43 +0000922 SourceLocation TypeLoc = Tok.getLocation();
923 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
924 Tok.isNot(tok::annot_pragma_openmp_end))
925 ConsumeAnyToken();
926
927 // Parse ')'.
928 T.consumeClose();
929
930 return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
931 Tok.getLocation());
932}
933
Alexey Bataev142e1fc2014-06-20 09:44:06 +0000934/// \brief Parsing of OpenMP clauses like 'ordered'.
935///
936/// ordered-clause:
937/// 'ordered'
938///
Alexey Bataev236070f2014-06-20 11:19:47 +0000939/// nowait-clause:
940/// 'nowait'
941///
Alexey Bataev7aea99a2014-07-17 12:19:31 +0000942/// untied-clause:
943/// 'untied'
944///
Alexey Bataev74ba3a52014-07-17 12:47:03 +0000945/// mergeable-clause:
946/// 'mergeable'
947///
Alexey Bataevf98b00c2014-07-23 02:27:21 +0000948/// read-clause:
949/// 'read'
950///
Alexey Bataev346265e2015-09-25 10:37:12 +0000951/// threads-clause:
952/// 'threads'
953///
Alexey Bataevd14d1e62015-09-28 06:39:35 +0000954/// simd-clause:
955/// 'simd'
956///
Alexey Bataevb825de12015-12-07 10:51:44 +0000957/// nogroup-clause:
958/// 'nogroup'
959///
Alexey Bataev142e1fc2014-06-20 09:44:06 +0000960OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
961 SourceLocation Loc = Tok.getLocation();
962 ConsumeAnyToken();
963
964 return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
965}
966
967
Alexey Bataev56dafe82014-06-20 07:16:17 +0000968/// \brief Parsing of OpenMP clauses with single expressions and some additional
969/// argument like 'schedule' or 'dist_schedule'.
970///
971/// schedule-clause:
Alexey Bataev6402bca2015-12-28 07:25:51 +0000972/// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
973/// ')'
Alexey Bataev56dafe82014-06-20 07:16:17 +0000974///
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000975/// if-clause:
976/// 'if' '(' [ directive-name-modifier ':' ] expression ')'
977///
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +0000978/// defaultmap:
979/// 'defaultmap' '(' modifier ':' kind ')'
980///
Alexey Bataev56dafe82014-06-20 07:16:17 +0000981OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
982 SourceLocation Loc = ConsumeToken();
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000983 SourceLocation DelimLoc;
Alexey Bataev56dafe82014-06-20 07:16:17 +0000984 // Parse '('.
985 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
986 if (T.expectAndConsume(diag::err_expected_lparen_after,
987 getOpenMPClauseName(Kind)))
988 return nullptr;
989
990 ExprResult Val;
Alexey Bataev6402bca2015-12-28 07:25:51 +0000991 SmallVector<unsigned, 4> Arg;
992 SmallVector<SourceLocation, 4> KLoc;
Alexey Bataev6b8046a2015-09-03 07:23:48 +0000993 if (Kind == OMPC_schedule) {
Alexey Bataev6402bca2015-12-28 07:25:51 +0000994 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
995 Arg.resize(NumberOfElements);
996 KLoc.resize(NumberOfElements);
997 Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
998 Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
999 Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1000 auto KindModifier = getOpenMPSimpleClauseType(
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001001 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
Alexey Bataev6402bca2015-12-28 07:25:51 +00001002 if (KindModifier > OMPC_SCHEDULE_unknown) {
1003 // Parse 'modifier'
1004 Arg[Modifier1] = KindModifier;
1005 KLoc[Modifier1] = Tok.getLocation();
1006 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1007 Tok.isNot(tok::annot_pragma_openmp_end))
1008 ConsumeAnyToken();
1009 if (Tok.is(tok::comma)) {
1010 // Parse ',' 'modifier'
1011 ConsumeAnyToken();
1012 KindModifier = getOpenMPSimpleClauseType(
1013 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1014 Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1015 ? KindModifier
Aaron Ballmanad8a1042015-12-28 15:52:46 +00001016 : (unsigned)OMPC_SCHEDULE_unknown;
Alexey Bataev6402bca2015-12-28 07:25:51 +00001017 KLoc[Modifier2] = Tok.getLocation();
1018 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1019 Tok.isNot(tok::annot_pragma_openmp_end))
1020 ConsumeAnyToken();
1021 }
1022 // Parse ':'
1023 if (Tok.is(tok::colon))
1024 ConsumeAnyToken();
1025 else
1026 Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1027 KindModifier = getOpenMPSimpleClauseType(
1028 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1029 }
1030 Arg[ScheduleKind] = KindModifier;
1031 KLoc[ScheduleKind] = Tok.getLocation();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001032 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1033 Tok.isNot(tok::annot_pragma_openmp_end))
1034 ConsumeAnyToken();
Alexey Bataev6402bca2015-12-28 07:25:51 +00001035 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1036 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1037 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001038 Tok.is(tok::comma))
1039 DelimLoc = ConsumeAnyToken();
Carlo Bertollib4adf552016-01-15 18:50:31 +00001040 } else if (Kind == OMPC_dist_schedule) {
1041 Arg.push_back(getOpenMPSimpleClauseType(
1042 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1043 KLoc.push_back(Tok.getLocation());
1044 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1045 Tok.isNot(tok::annot_pragma_openmp_end))
1046 ConsumeAnyToken();
1047 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1048 DelimLoc = ConsumeAnyToken();
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00001049 } else if (Kind == OMPC_defaultmap) {
1050 // Get a defaultmap modifier
1051 Arg.push_back(getOpenMPSimpleClauseType(
1052 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1053 KLoc.push_back(Tok.getLocation());
1054 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1055 Tok.isNot(tok::annot_pragma_openmp_end))
1056 ConsumeAnyToken();
1057 // Parse ':'
1058 if (Tok.is(tok::colon))
1059 ConsumeAnyToken();
1060 else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1061 Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1062 // Get a defaultmap kind
1063 Arg.push_back(getOpenMPSimpleClauseType(
1064 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1065 KLoc.push_back(Tok.getLocation());
1066 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1067 Tok.isNot(tok::annot_pragma_openmp_end))
1068 ConsumeAnyToken();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001069 } else {
1070 assert(Kind == OMPC_if);
Alexey Bataev6402bca2015-12-28 07:25:51 +00001071 KLoc.push_back(Tok.getLocation());
1072 Arg.push_back(ParseOpenMPDirectiveKind(*this));
1073 if (Arg.back() != OMPD_unknown) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001074 ConsumeToken();
1075 if (Tok.is(tok::colon))
1076 DelimLoc = ConsumeToken();
1077 else
1078 Diag(Tok, diag::warn_pragma_expected_colon)
1079 << "directive name modifier";
1080 }
1081 }
Alexey Bataev56dafe82014-06-20 07:16:17 +00001082
Carlo Bertollib4adf552016-01-15 18:50:31 +00001083 bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1084 (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1085 Kind == OMPC_if;
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001086 if (NeedAnExpression) {
1087 SourceLocation ELoc = Tok.getLocation();
Alexey Bataev56dafe82014-06-20 07:16:17 +00001088 ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
1089 Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001090 Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
Alexey Bataev56dafe82014-06-20 07:16:17 +00001091 }
1092
1093 // Parse ')'.
1094 T.consumeClose();
1095
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001096 if (NeedAnExpression && Val.isInvalid())
1097 return nullptr;
1098
Alexey Bataev56dafe82014-06-20 07:16:17 +00001099 return Actions.ActOnOpenMPSingleExprWithArgClause(
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001100 Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
Alexey Bataev56dafe82014-06-20 07:16:17 +00001101 T.getCloseLocation());
1102}
1103
Alexey Bataevc5e02582014-06-16 07:08:35 +00001104static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
1105 UnqualifiedId &ReductionId) {
1106 SourceLocation TemplateKWLoc;
1107 if (ReductionIdScopeSpec.isEmpty()) {
1108 auto OOK = OO_None;
1109 switch (P.getCurToken().getKind()) {
1110 case tok::plus:
1111 OOK = OO_Plus;
1112 break;
1113 case tok::minus:
1114 OOK = OO_Minus;
1115 break;
1116 case tok::star:
1117 OOK = OO_Star;
1118 break;
1119 case tok::amp:
1120 OOK = OO_Amp;
1121 break;
1122 case tok::pipe:
1123 OOK = OO_Pipe;
1124 break;
1125 case tok::caret:
1126 OOK = OO_Caret;
1127 break;
1128 case tok::ampamp:
1129 OOK = OO_AmpAmp;
1130 break;
1131 case tok::pipepipe:
1132 OOK = OO_PipePipe;
1133 break;
1134 default:
1135 break;
1136 }
1137 if (OOK != OO_None) {
1138 SourceLocation OpLoc = P.ConsumeToken();
Alexey Bataev23b69422014-06-18 07:08:49 +00001139 SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
Alexey Bataevc5e02582014-06-16 07:08:35 +00001140 ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
1141 return false;
1142 }
1143 }
1144 return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
1145 /*AllowDestructorName*/ false,
David Blaikieefdccaa2016-01-15 23:43:34 +00001146 /*AllowConstructorName*/ false, nullptr,
Alexey Bataevc5e02582014-06-16 07:08:35 +00001147 TemplateKWLoc, ReductionId);
1148}
1149
Alexander Musman1bb328c2014-06-04 13:06:39 +00001150/// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
Alexey Bataev6125da92014-07-21 11:26:11 +00001151/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001152///
1153/// private-clause:
1154/// 'private' '(' list ')'
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001155/// firstprivate-clause:
1156/// 'firstprivate' '(' list ')'
Alexander Musman1bb328c2014-06-04 13:06:39 +00001157/// lastprivate-clause:
1158/// 'lastprivate' '(' list ')'
Alexey Bataev758e55e2013-09-06 18:03:48 +00001159/// shared-clause:
1160/// 'shared' '(' list ')'
Alexander Musman8dba6642014-04-22 13:09:42 +00001161/// linear-clause:
Alexey Bataev182227b2015-08-20 10:54:39 +00001162/// 'linear' '(' linear-list [ ':' linear-step ] ')'
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001163/// aligned-clause:
1164/// 'aligned' '(' list [ ':' alignment ] ')'
Alexey Bataevc5e02582014-06-16 07:08:35 +00001165/// reduction-clause:
1166/// 'reduction' '(' reduction-identifier ':' list ')'
Alexey Bataev6125da92014-07-21 11:26:11 +00001167/// copyprivate-clause:
1168/// 'copyprivate' '(' list ')'
1169/// flush-clause:
1170/// 'flush' '(' list ')'
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001171/// depend-clause:
Alexey Bataeveb482352015-12-18 05:05:56 +00001172/// 'depend' '(' in | out | inout : list | source ')'
Kelvin Li0bff7af2015-11-23 05:32:03 +00001173/// map-clause:
1174/// 'map' '(' [ [ always , ]
1175/// to | from | tofrom | alloc | release | delete ':' ] list ')';
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001176///
Alexey Bataev182227b2015-08-20 10:54:39 +00001177/// For 'linear' clause linear-list may have the following forms:
1178/// list
1179/// modifier(list)
1180/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
Alexey Bataeveb482352015-12-18 05:05:56 +00001181OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
1182 OpenMPClauseKind Kind) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001183 SourceLocation Loc = Tok.getLocation();
1184 SourceLocation LOpen = ConsumeToken();
Alexander Musman8dba6642014-04-22 13:09:42 +00001185 SourceLocation ColonLoc = SourceLocation();
Alexey Bataevc5e02582014-06-16 07:08:35 +00001186 // Optional scope specifier and unqualified id for reduction identifier.
1187 CXXScopeSpec ReductionIdScopeSpec;
1188 UnqualifiedId ReductionId;
1189 bool InvalidReductionId = false;
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001190 OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
Alexey Bataev182227b2015-08-20 10:54:39 +00001191 // OpenMP 4.1 [2.15.3.7, linear Clause]
1192 // If no modifier is specified it is assumed to be val.
1193 OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val;
Kelvin Li0bff7af2015-11-23 05:32:03 +00001194 OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
1195 OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
Samuel Antao23abd722016-01-19 20:40:49 +00001196 bool MapTypeIsImplicit = false;
Kelvin Li0bff7af2015-11-23 05:32:03 +00001197 bool MapTypeModifierSpecified = false;
Kelvin Li0bff7af2015-11-23 05:32:03 +00001198 SourceLocation DepLinMapLoc;
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001199
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001200 // Parse '('.
Alp Tokerd751fa72013-12-18 19:10:49 +00001201 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001202 if (T.expectAndConsume(diag::err_expected_lparen_after,
1203 getOpenMPClauseName(Kind)))
Craig Topper161e4db2014-05-21 06:02:52 +00001204 return nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001205
Alexey Bataev182227b2015-08-20 10:54:39 +00001206 bool NeedRParenForLinear = false;
1207 BalancedDelimiterTracker LinearT(*this, tok::l_paren,
1208 tok::annot_pragma_openmp_end);
Alexey Bataevc5e02582014-06-16 07:08:35 +00001209 // Handle reduction-identifier for reduction clause.
1210 if (Kind == OMPC_reduction) {
1211 ColonProtectionRAIIObject ColonRAII(*this);
1212 if (getLangOpts().CPlusPlus) {
David Blaikieefdccaa2016-01-15 23:43:34 +00001213 ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, nullptr, false);
Alexey Bataevc5e02582014-06-16 07:08:35 +00001214 }
1215 InvalidReductionId =
1216 ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
1217 if (InvalidReductionId) {
1218 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1219 StopBeforeMatch);
1220 }
1221 if (Tok.is(tok::colon)) {
1222 ColonLoc = ConsumeToken();
1223 } else {
1224 Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
1225 }
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001226 } else if (Kind == OMPC_depend) {
1227 // Handle dependency type for depend clause.
1228 ColonProtectionRAIIObject ColonRAII(*this);
1229 DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
1230 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
Kelvin Li0bff7af2015-11-23 05:32:03 +00001231 DepLinMapLoc = Tok.getLocation();
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001232
1233 if (DepKind == OMPC_DEPEND_unknown) {
1234 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1235 StopBeforeMatch);
1236 } else {
1237 ConsumeToken();
Alexey Bataeveb482352015-12-18 05:05:56 +00001238 // Special processing for depend(source) clause.
1239 if (DKind == OMPD_ordered && DepKind == OMPC_DEPEND_source) {
1240 // Parse ')'.
1241 T.consumeClose();
1242 return Actions.ActOnOpenMPVarListClause(
1243 Kind, llvm::None, /*TailExpr=*/nullptr, Loc, LOpen,
1244 /*ColonLoc=*/SourceLocation(), Tok.getLocation(),
1245 ReductionIdScopeSpec, DeclarationNameInfo(), DepKind,
Samuel Antao23abd722016-01-19 20:40:49 +00001246 LinearModifier, MapTypeModifier, MapType, MapTypeIsImplicit,
1247 DepLinMapLoc);
Alexey Bataeveb482352015-12-18 05:05:56 +00001248 }
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001249 }
1250 if (Tok.is(tok::colon)) {
1251 ColonLoc = ConsumeToken();
1252 } else {
Alexey Bataeveb482352015-12-18 05:05:56 +00001253 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
1254 : diag::warn_pragma_expected_colon)
1255 << "dependency type";
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001256 }
Alexey Bataev182227b2015-08-20 10:54:39 +00001257 } else if (Kind == OMPC_linear) {
1258 // Try to parse modifier if any.
1259 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
Alexey Bataev182227b2015-08-20 10:54:39 +00001260 LinearModifier = static_cast<OpenMPLinearClauseKind>(
Alexey Bataev1185e192015-08-20 12:15:57 +00001261 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
Kelvin Li0bff7af2015-11-23 05:32:03 +00001262 DepLinMapLoc = ConsumeToken();
Alexey Bataev182227b2015-08-20 10:54:39 +00001263 LinearT.consumeOpen();
1264 NeedRParenForLinear = true;
1265 }
Kelvin Li0bff7af2015-11-23 05:32:03 +00001266 } else if (Kind == OMPC_map) {
1267 // Handle map type for map clause.
1268 ColonProtectionRAIIObject ColonRAII(*this);
1269
Samuel Antaof91b1632016-02-27 00:01:58 +00001270 /// The map clause modifier token can be either a identifier or the C++
1271 /// delete keyword.
1272 auto IsMapClauseModifierToken = [](const Token &Tok) {
1273 return Tok.isOneOf(tok::identifier, tok::kw_delete);
1274 };
1275
1276 // The first identifier may be a list item, a map-type or a
1277 // map-type-modifier. The map modifier can also be delete which has the same
1278 // spelling of the C++ delete keyword.
Kelvin Li0bff7af2015-11-23 05:32:03 +00001279 MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
Samuel Antaof91b1632016-02-27 00:01:58 +00001280 Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : ""));
Kelvin Li0bff7af2015-11-23 05:32:03 +00001281 DepLinMapLoc = Tok.getLocation();
1282 bool ColonExpected = false;
1283
Samuel Antaof91b1632016-02-27 00:01:58 +00001284 if (IsMapClauseModifierToken(Tok)) {
Kelvin Li0bff7af2015-11-23 05:32:03 +00001285 if (PP.LookAhead(0).is(tok::colon)) {
1286 MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
Samuel Antaof91b1632016-02-27 00:01:58 +00001287 Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : ""));
Kelvin Li0bff7af2015-11-23 05:32:03 +00001288 if (MapType == OMPC_MAP_unknown) {
1289 Diag(Tok, diag::err_omp_unknown_map_type);
1290 } else if (MapType == OMPC_MAP_always) {
1291 Diag(Tok, diag::err_omp_map_type_missing);
1292 }
1293 ConsumeToken();
1294 } else if (PP.LookAhead(0).is(tok::comma)) {
Samuel Antaof91b1632016-02-27 00:01:58 +00001295 if (IsMapClauseModifierToken(PP.LookAhead(1)) &&
Kelvin Li0bff7af2015-11-23 05:32:03 +00001296 PP.LookAhead(2).is(tok::colon)) {
1297 MapTypeModifier =
1298 static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
Samuel Antaof91b1632016-02-27 00:01:58 +00001299 Kind,
1300 IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : ""));
Kelvin Li0bff7af2015-11-23 05:32:03 +00001301 if (MapTypeModifier != OMPC_MAP_always) {
1302 Diag(Tok, diag::err_omp_unknown_map_type_modifier);
1303 MapTypeModifier = OMPC_MAP_unknown;
1304 } else {
1305 MapTypeModifierSpecified = true;
1306 }
1307
1308 ConsumeToken();
1309 ConsumeToken();
1310
1311 MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
Samuel Antaof91b1632016-02-27 00:01:58 +00001312 Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : ""));
Kelvin Li0bff7af2015-11-23 05:32:03 +00001313 if (MapType == OMPC_MAP_unknown || MapType == OMPC_MAP_always) {
1314 Diag(Tok, diag::err_omp_unknown_map_type);
1315 }
1316 ConsumeToken();
1317 } else {
1318 MapType = OMPC_MAP_tofrom;
Samuel Antao23abd722016-01-19 20:40:49 +00001319 MapTypeIsImplicit = true;
Kelvin Li0bff7af2015-11-23 05:32:03 +00001320 }
1321 } else {
1322 MapType = OMPC_MAP_tofrom;
Samuel Antao23abd722016-01-19 20:40:49 +00001323 MapTypeIsImplicit = true;
Kelvin Li0bff7af2015-11-23 05:32:03 +00001324 }
1325 } else {
Samuel Antao5de996e2016-01-22 20:21:36 +00001326 MapType = OMPC_MAP_tofrom;
1327 MapTypeIsImplicit = true;
Kelvin Li0bff7af2015-11-23 05:32:03 +00001328 }
1329
1330 if (Tok.is(tok::colon)) {
1331 ColonLoc = ConsumeToken();
1332 } else if (ColonExpected) {
1333 Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
1334 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00001335 }
1336
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001337 SmallVector<Expr *, 5> Vars;
Kelvin Li0bff7af2015-11-23 05:32:03 +00001338 bool IsComma =
1339 ((Kind != OMPC_reduction) && (Kind != OMPC_depend) &&
1340 (Kind != OMPC_map)) ||
1341 ((Kind == OMPC_reduction) && !InvalidReductionId) ||
Samuel Antao5de996e2016-01-22 20:21:36 +00001342 ((Kind == OMPC_map) && (MapType != OMPC_MAP_unknown) &&
Kelvin Li0bff7af2015-11-23 05:32:03 +00001343 (!MapTypeModifierSpecified ||
1344 (MapTypeModifierSpecified && MapTypeModifier == OMPC_MAP_always))) ||
1345 ((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001346 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
Alexander Musman8dba6642014-04-22 13:09:42 +00001347 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001348 Tok.isNot(tok::annot_pragma_openmp_end))) {
Alexander Musman8dba6642014-04-22 13:09:42 +00001349 ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001350 // Parse variable
Kaelyn Takata15867822014-11-21 18:48:04 +00001351 ExprResult VarExpr =
1352 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001353 if (VarExpr.isUsable()) {
Nikola Smiljanic01a75982014-05-29 10:55:11 +00001354 Vars.push_back(VarExpr.get());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001355 } else {
1356 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +00001357 StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001358 }
1359 // Skip ',' if any
1360 IsComma = Tok.is(tok::comma);
Alexander Musman8dba6642014-04-22 13:09:42 +00001361 if (IsComma)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001362 ConsumeToken();
Alexander Musman8dba6642014-04-22 13:09:42 +00001363 else if (Tok.isNot(tok::r_paren) &&
1364 Tok.isNot(tok::annot_pragma_openmp_end) &&
1365 (!MayHaveTail || Tok.isNot(tok::colon)))
Alexey Bataev6125da92014-07-21 11:26:11 +00001366 Diag(Tok, diag::err_omp_expected_punc)
1367 << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
1368 : getOpenMPClauseName(Kind))
1369 << (Kind == OMPC_flush);
Alexander Musman8dba6642014-04-22 13:09:42 +00001370 }
1371
Alexey Bataev182227b2015-08-20 10:54:39 +00001372 // Parse ')' for linear clause with modifier.
1373 if (NeedRParenForLinear)
1374 LinearT.consumeClose();
1375
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001376 // Parse ':' linear-step (or ':' alignment).
Craig Topper161e4db2014-05-21 06:02:52 +00001377 Expr *TailExpr = nullptr;
Alexander Musman8dba6642014-04-22 13:09:42 +00001378 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
1379 if (MustHaveTail) {
1380 ColonLoc = Tok.getLocation();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00001381 SourceLocation ELoc = ConsumeToken();
1382 ExprResult Tail = ParseAssignmentExpression();
1383 Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
Alexander Musman8dba6642014-04-22 13:09:42 +00001384 if (Tail.isUsable())
Nikola Smiljanic01a75982014-05-29 10:55:11 +00001385 TailExpr = Tail.get();
Alexander Musman8dba6642014-04-22 13:09:42 +00001386 else
1387 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1388 StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001389 }
1390
1391 // Parse ')'.
1392 T.consumeClose();
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001393 if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
Samuel Antao5de996e2016-01-22 20:21:36 +00001394 (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
1395 (MustHaveTail && !TailExpr) || InvalidReductionId) {
Craig Topper161e4db2014-05-21 06:02:52 +00001396 return nullptr;
Kelvin Li0bff7af2015-11-23 05:32:03 +00001397 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001398
Alexey Bataevc5e02582014-06-16 07:08:35 +00001399 return Actions.ActOnOpenMPVarListClause(
1400 Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
1401 ReductionIdScopeSpec,
1402 ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00001403 : DeclarationNameInfo(),
Samuel Antao23abd722016-01-19 20:40:49 +00001404 DepKind, LinearModifier, MapTypeModifier, MapType, MapTypeIsImplicit,
1405 DepLinMapLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001406}
1407