blob: 19acfe1158fbd9107fc42e2090f455435da05d4f [file] [log] [blame]
Alexey Bataeva769e072013-03-22 06:34:35 +00001//===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Alexey Bataeva769e072013-03-22 06:34:35 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00009/// This file implements parsing of all OpenMP directives and clauses.
Alexey Bataeva769e072013-03-22 06:34:35 +000010///
11//===----------------------------------------------------------------------===//
12
Alexey Bataev9959db52014-05-06 10:08:46 +000013#include "clang/AST/ASTContext.h"
Reid Klecknerba1ffd22020-04-03 12:35:30 -070014#include "clang/AST/OpenMPClause.h"
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000015#include "clang/AST/StmtOpenMP.h"
Alexey Bataev93dc40d2019-12-20 11:04:57 -050016#include "clang/Basic/OpenMPKinds.h"
Johannes Doerfertbefb4be2020-02-25 14:04:06 -080017#include "clang/Basic/TargetInfo.h"
Alexey Bataev1236eb62020-03-23 17:30:38 -040018#include "clang/Basic/TokenKinds.h"
Alexey Bataeva769e072013-03-22 06:34:35 +000019#include "clang/Parse/ParseDiagnostic.h"
Alexey Bataev6f6f3b42013-05-13 04:18:18 +000020#include "clang/Parse/Parser.h"
Vassil Vassilev11ad3392017-03-23 15:11:07 +000021#include "clang/Parse/RAIIObjectsForParser.h"
Alexey Bataev6f6f3b42013-05-13 04:18:18 +000022#include "clang/Sema/Scope.h"
23#include "llvm/ADT/PointerIntPair.h"
Alexey Bataev4513e93f2019-10-10 15:15:26 +000024#include "llvm/ADT/UniqueVector.h"
Johannes Doerfert1228d422019-12-19 20:42:12 -060025#include "llvm/Frontend/OpenMP/OMPContext.h"
Michael Wong65f367f2015-07-21 13:44:28 +000026
Alexey Bataeva769e072013-03-22 06:34:35 +000027using namespace clang;
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060028using namespace llvm::omp;
Alexey Bataeva769e072013-03-22 06:34:35 +000029
30//===----------------------------------------------------------------------===//
31// OpenMP declarative directives.
32//===----------------------------------------------------------------------===//
33
Dmitry Polukhin82478332016-02-13 06:53:38 +000034namespace {
35enum OpenMPDirectiveKindEx {
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060036 OMPD_cancellation = unsigned(OMPD_unknown) + 1,
Dmitry Polukhin82478332016-02-13 06:53:38 +000037 OMPD_data,
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000038 OMPD_declare,
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000039 OMPD_end,
40 OMPD_end_declare,
Dmitry Polukhin82478332016-02-13 06:53:38 +000041 OMPD_enter,
42 OMPD_exit,
43 OMPD_point,
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000044 OMPD_reduction,
Dmitry Polukhin82478332016-02-13 06:53:38 +000045 OMPD_target_enter,
Samuel Antao686c70c2016-05-26 17:30:50 +000046 OMPD_target_exit,
47 OMPD_update,
Kelvin Li579e41c2016-11-30 23:51:03 +000048 OMPD_distribute_parallel,
Kelvin Li80e8f562016-12-29 22:16:30 +000049 OMPD_teams_distribute_parallel,
Michael Kruse251e1482019-02-01 20:25:04 +000050 OMPD_target_teams_distribute_parallel,
51 OMPD_mapper,
Alexey Bataevd158cf62019-09-13 20:18:17 +000052 OMPD_variant,
Johannes Doerfert095cecb2020-02-20 19:50:47 -060053 OMPD_begin,
54 OMPD_begin_declare,
Dmitry Polukhin82478332016-02-13 06:53:38 +000055};
Dmitry Polukhind69b5052016-05-09 14:59:13 +000056
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060057// Helper to unify the enum class OpenMPDirectiveKind with its extension
58// the OpenMPDirectiveKindEx enum which allows to use them together as if they
59// are unsigned values.
60struct OpenMPDirectiveKindExWrapper {
61 OpenMPDirectiveKindExWrapper(unsigned Value) : Value(Value) {}
62 OpenMPDirectiveKindExWrapper(OpenMPDirectiveKind DK) : Value(unsigned(DK)) {}
63 bool operator==(OpenMPDirectiveKind V) const { return Value == unsigned(V); }
64 bool operator!=(OpenMPDirectiveKind V) const { return Value != unsigned(V); }
65 bool operator<(OpenMPDirectiveKind V) const { return Value < unsigned(V); }
66 operator unsigned() const { return Value; }
67 operator OpenMPDirectiveKind() const { return OpenMPDirectiveKind(Value); }
68 unsigned Value;
69};
70
Alexey Bataev25ed0c02019-03-07 17:54:44 +000071class DeclDirectiveListParserHelper final {
Dmitry Polukhind69b5052016-05-09 14:59:13 +000072 SmallVector<Expr *, 4> Identifiers;
73 Parser *P;
Alexey Bataev25ed0c02019-03-07 17:54:44 +000074 OpenMPDirectiveKind Kind;
Dmitry Polukhind69b5052016-05-09 14:59:13 +000075
76public:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000077 DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
78 : P(P), Kind(Kind) {}
Dmitry Polukhind69b5052016-05-09 14:59:13 +000079 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
Alexey Bataev25ed0c02019-03-07 17:54:44 +000080 ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
81 P->getCurScope(), SS, NameInfo, Kind);
Dmitry Polukhind69b5052016-05-09 14:59:13 +000082 if (Res.isUsable())
83 Identifiers.push_back(Res.get());
84 }
85 llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
86};
Dmitry Polukhin82478332016-02-13 06:53:38 +000087} // namespace
88
89// Map token string to extended OMP token kind that are
90// OpenMPDirectiveKind + OpenMPDirectiveKindEx.
91static unsigned getOpenMPDirectiveKindEx(StringRef S) {
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060092 OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
Dmitry Polukhin82478332016-02-13 06:53:38 +000093 if (DKind != OMPD_unknown)
94 return DKind;
95
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060096 return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
Dmitry Polukhin82478332016-02-13 06:53:38 +000097 .Case("cancellation", OMPD_cancellation)
98 .Case("data", OMPD_data)
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000099 .Case("declare", OMPD_declare)
Dmitry Polukhin0b0da292016-04-06 11:38:59 +0000100 .Case("end", OMPD_end)
Dmitry Polukhin82478332016-02-13 06:53:38 +0000101 .Case("enter", OMPD_enter)
102 .Case("exit", OMPD_exit)
103 .Case("point", OMPD_point)
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000104 .Case("reduction", OMPD_reduction)
Samuel Antao686c70c2016-05-26 17:30:50 +0000105 .Case("update", OMPD_update)
Michael Kruse251e1482019-02-01 20:25:04 +0000106 .Case("mapper", OMPD_mapper)
Alexey Bataevd158cf62019-09-13 20:18:17 +0000107 .Case("variant", OMPD_variant)
Johannes Doerfert095cecb2020-02-20 19:50:47 -0600108 .Case("begin", OMPD_begin)
Dmitry Polukhin82478332016-02-13 06:53:38 +0000109 .Default(OMPD_unknown);
110}
111
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600112static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
Alexander Musmanf82886e2014-09-18 05:12:34 +0000113 // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
114 // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
115 // TODO: add other combined directives in topological order.
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600116 static const OpenMPDirectiveKindExWrapper F[][3] = {
Johannes Doerfert095cecb2020-02-20 19:50:47 -0600117 {OMPD_begin, OMPD_declare, OMPD_begin_declare},
118 {OMPD_end, OMPD_declare, OMPD_end_declare},
Alexey Bataev61908f652018-04-23 19:53:05 +0000119 {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
120 {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
Michael Kruse251e1482019-02-01 20:25:04 +0000121 {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
Alexey Bataev61908f652018-04-23 19:53:05 +0000122 {OMPD_declare, OMPD_simd, OMPD_declare_simd},
123 {OMPD_declare, OMPD_target, OMPD_declare_target},
Alexey Bataevd158cf62019-09-13 20:18:17 +0000124 {OMPD_declare, OMPD_variant, OMPD_declare_variant},
Johannes Doerfert095cecb2020-02-20 19:50:47 -0600125 {OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},
126 {OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},
Alexey Bataev61908f652018-04-23 19:53:05 +0000127 {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
128 {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
129 {OMPD_distribute_parallel_for, OMPD_simd,
130 OMPD_distribute_parallel_for_simd},
131 {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
Alexey Bataev61908f652018-04-23 19:53:05 +0000132 {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
133 {OMPD_target, OMPD_data, OMPD_target_data},
134 {OMPD_target, OMPD_enter, OMPD_target_enter},
135 {OMPD_target, OMPD_exit, OMPD_target_exit},
136 {OMPD_target, OMPD_update, OMPD_target_update},
137 {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
138 {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
139 {OMPD_for, OMPD_simd, OMPD_for_simd},
140 {OMPD_parallel, OMPD_for, OMPD_parallel_for},
141 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
142 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
143 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
144 {OMPD_target, OMPD_parallel, OMPD_target_parallel},
145 {OMPD_target, OMPD_simd, OMPD_target_simd},
146 {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
147 {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
148 {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
149 {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
150 {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
151 {OMPD_teams_distribute_parallel, OMPD_for,
152 OMPD_teams_distribute_parallel_for},
153 {OMPD_teams_distribute_parallel_for, OMPD_simd,
154 OMPD_teams_distribute_parallel_for_simd},
155 {OMPD_target, OMPD_teams, OMPD_target_teams},
156 {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
157 {OMPD_target_teams_distribute, OMPD_parallel,
158 OMPD_target_teams_distribute_parallel},
159 {OMPD_target_teams_distribute, OMPD_simd,
160 OMPD_target_teams_distribute_simd},
161 {OMPD_target_teams_distribute_parallel, OMPD_for,
162 OMPD_target_teams_distribute_parallel_for},
163 {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
Alexey Bataev60e51c42019-10-10 20:13:02 +0000164 OMPD_target_teams_distribute_parallel_for_simd},
Alexey Bataev5bbcead2019-10-14 17:17:41 +0000165 {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
Alexey Bataevb8552ab2019-10-18 16:47:35 +0000166 {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
Alexey Bataev5bbcead2019-10-14 17:17:41 +0000167 {OMPD_parallel, OMPD_master, OMPD_parallel_master},
Alexey Bataev14a388f2019-10-25 10:27:13 -0400168 {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
169 {OMPD_parallel_master_taskloop, OMPD_simd,
170 OMPD_parallel_master_taskloop_simd}};
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000171 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
Alexey Bataev61908f652018-04-23 19:53:05 +0000172 Token Tok = P.getCurToken();
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600173 OpenMPDirectiveKindExWrapper DKind =
Alexey Bataev4acb8592014-07-07 13:01:15 +0000174 Tok.isAnnotation()
Dmitry Polukhin82478332016-02-13 06:53:38 +0000175 ? static_cast<unsigned>(OMPD_unknown)
176 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
177 if (DKind == OMPD_unknown)
178 return OMPD_unknown;
Michael Wong65f367f2015-07-21 13:44:28 +0000179
Alexey Bataev61908f652018-04-23 19:53:05 +0000180 for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
181 if (DKind != F[I][0])
Dmitry Polukhin82478332016-02-13 06:53:38 +0000182 continue;
Michael Wong65f367f2015-07-21 13:44:28 +0000183
Dmitry Polukhin82478332016-02-13 06:53:38 +0000184 Tok = P.getPreprocessor().LookAhead(0);
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600185 OpenMPDirectiveKindExWrapper SDKind =
Dmitry Polukhin82478332016-02-13 06:53:38 +0000186 Tok.isAnnotation()
187 ? static_cast<unsigned>(OMPD_unknown)
188 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
189 if (SDKind == OMPD_unknown)
190 continue;
Michael Wong65f367f2015-07-21 13:44:28 +0000191
Alexey Bataev61908f652018-04-23 19:53:05 +0000192 if (SDKind == F[I][1]) {
Dmitry Polukhin82478332016-02-13 06:53:38 +0000193 P.ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +0000194 DKind = F[I][2];
Alexey Bataev4acb8592014-07-07 13:01:15 +0000195 }
196 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000197 return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
198 : OMPD_unknown;
199}
200
201static DeclarationName parseOpenMPReductionId(Parser &P) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000202 Token Tok = P.getCurToken();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000203 Sema &Actions = P.getActions();
204 OverloadedOperatorKind OOK = OO_None;
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000205 // Allow to use 'operator' keyword for C++ operators
206 bool WithOperator = false;
207 if (Tok.is(tok::kw_operator)) {
208 P.ConsumeToken();
209 Tok = P.getCurToken();
210 WithOperator = true;
211 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000212 switch (Tok.getKind()) {
213 case tok::plus: // '+'
214 OOK = OO_Plus;
215 break;
216 case tok::minus: // '-'
217 OOK = OO_Minus;
218 break;
219 case tok::star: // '*'
220 OOK = OO_Star;
221 break;
222 case tok::amp: // '&'
223 OOK = OO_Amp;
224 break;
225 case tok::pipe: // '|'
226 OOK = OO_Pipe;
227 break;
228 case tok::caret: // '^'
229 OOK = OO_Caret;
230 break;
231 case tok::ampamp: // '&&'
232 OOK = OO_AmpAmp;
233 break;
234 case tok::pipepipe: // '||'
235 OOK = OO_PipePipe;
236 break;
237 case tok::identifier: // identifier
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000238 if (!WithOperator)
239 break;
Galina Kistanova474f2ce2017-06-01 21:26:38 +0000240 LLVM_FALLTHROUGH;
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000241 default:
242 P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
243 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
244 Parser::StopBeforeMatch);
245 return DeclarationName();
246 }
247 P.ConsumeToken();
248 auto &DeclNames = Actions.getASTContext().DeclarationNames;
249 return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
250 : DeclNames.getCXXOperatorName(OOK);
251}
252
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000253/// Parse 'omp declare reduction' construct.
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000254///
255/// declare-reduction-directive:
256/// annot_pragma_openmp 'declare' 'reduction'
257/// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
258/// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
259/// annot_pragma_openmp_end
260/// <reduction_id> is either a base language identifier or one of the following
261/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
262///
263Parser::DeclGroupPtrTy
264Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
265 // Parse '('.
266 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600267 if (T.expectAndConsume(
268 diag::err_expected_lparen_after,
269 getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000270 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
271 return DeclGroupPtrTy();
272 }
273
274 DeclarationName Name = parseOpenMPReductionId(*this);
275 if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
276 return DeclGroupPtrTy();
277
278 // Consume ':'.
279 bool IsCorrect = !ExpectAndConsume(tok::colon);
280
281 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
282 return DeclGroupPtrTy();
283
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000284 IsCorrect = IsCorrect && !Name.isEmpty();
285
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000286 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
287 Diag(Tok.getLocation(), diag::err_expected_type);
288 IsCorrect = false;
289 }
290
291 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
292 return DeclGroupPtrTy();
293
294 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
295 // Parse list of types until ':' token.
296 do {
297 ColonProtectionRAIIObject ColonRAII(*this);
298 SourceRange Range;
Faisal Vali421b2d12017-12-29 05:41:00 +0000299 TypeResult TR =
300 ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000301 if (TR.isUsable()) {
Alexey Bataev61908f652018-04-23 19:53:05 +0000302 QualType ReductionType =
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000303 Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
304 if (!ReductionType.isNull()) {
305 ReductionTypes.push_back(
306 std::make_pair(ReductionType, Range.getBegin()));
307 }
308 } else {
309 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
310 StopBeforeMatch);
311 }
312
313 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
314 break;
315
316 // Consume ','.
317 if (ExpectAndConsume(tok::comma)) {
318 IsCorrect = false;
319 if (Tok.is(tok::annot_pragma_openmp_end)) {
320 Diag(Tok.getLocation(), diag::err_expected_type);
321 return DeclGroupPtrTy();
322 }
323 }
324 } while (Tok.isNot(tok::annot_pragma_openmp_end));
325
326 if (ReductionTypes.empty()) {
327 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
328 return DeclGroupPtrTy();
329 }
330
331 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
332 return DeclGroupPtrTy();
333
334 // Consume ':'.
335 if (ExpectAndConsume(tok::colon))
336 IsCorrect = false;
337
338 if (Tok.is(tok::annot_pragma_openmp_end)) {
339 Diag(Tok.getLocation(), diag::err_expected_expression);
340 return DeclGroupPtrTy();
341 }
342
343 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
344 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
345
346 // Parse <combiner> expression and then parse initializer if any for each
347 // correct type.
348 unsigned I = 0, E = ReductionTypes.size();
Alexey Bataev61908f652018-04-23 19:53:05 +0000349 for (Decl *D : DRD.get()) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000350 TentativeParsingAction TPA(*this);
351 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
Momchil Velikov57c681f2017-08-10 15:43:06 +0000352 Scope::CompoundStmtScope |
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000353 Scope::OpenMPDirectiveScope);
354 // Parse <combiner> expression.
355 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
Alexey Bataevc74a8ad2020-01-08 09:39:44 -0500356 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
357 ParseExpression().get(), D->getLocation(), /*DiscardedValue*/ false);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000358 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
359
360 if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
361 Tok.isNot(tok::annot_pragma_openmp_end)) {
362 TPA.Commit();
363 IsCorrect = false;
364 break;
365 }
366 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
367 ExprResult InitializerResult;
368 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
369 // Parse <initializer> expression.
370 if (Tok.is(tok::identifier) &&
Alexey Bataev61908f652018-04-23 19:53:05 +0000371 Tok.getIdentifierInfo()->isStr("initializer")) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000372 ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +0000373 } else {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000374 Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
375 TPA.Commit();
376 IsCorrect = false;
377 break;
378 }
379 // Parse '('.
380 BalancedDelimiterTracker T(*this, tok::l_paren,
381 tok::annot_pragma_openmp_end);
382 IsCorrect =
383 !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
384 IsCorrect;
385 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
386 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
Momchil Velikov57c681f2017-08-10 15:43:06 +0000387 Scope::CompoundStmtScope |
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000388 Scope::OpenMPDirectiveScope);
389 // Parse expression.
Alexey Bataev070f43a2017-09-06 14:49:58 +0000390 VarDecl *OmpPrivParm =
391 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
392 D);
393 // Check if initializer is omp_priv <init_expr> or something else.
394 if (Tok.is(tok::identifier) &&
395 Tok.getIdentifierInfo()->isStr("omp_priv")) {
Alexey Bataev3c676e32019-11-12 11:19:26 -0500396 ConsumeToken();
397 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
Alexey Bataev070f43a2017-09-06 14:49:58 +0000398 } else {
399 InitializerResult = Actions.ActOnFinishFullExpr(
400 ParseAssignmentExpression().get(), D->getLocation(),
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +0000401 /*DiscardedValue*/ false);
Alexey Bataev070f43a2017-09-06 14:49:58 +0000402 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000403 Actions.ActOnOpenMPDeclareReductionInitializerEnd(
Alexey Bataev070f43a2017-09-06 14:49:58 +0000404 D, InitializerResult.get(), OmpPrivParm);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000405 if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
406 Tok.isNot(tok::annot_pragma_openmp_end)) {
407 TPA.Commit();
408 IsCorrect = false;
409 break;
410 }
411 IsCorrect =
412 !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
413 }
414 }
415
416 ++I;
417 // Revert parsing if not the last type, otherwise accept it, we're done with
418 // parsing.
419 if (I != E)
420 TPA.Revert();
421 else
422 TPA.Commit();
423 }
424 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
425 IsCorrect);
Alexey Bataev4acb8592014-07-07 13:01:15 +0000426}
427
Alexey Bataev070f43a2017-09-06 14:49:58 +0000428void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
429 // Parse declarator '=' initializer.
430 // If a '==' or '+=' is found, suggest a fixit to '='.
431 if (isTokenEqualOrEqualTypo()) {
432 ConsumeToken();
433
434 if (Tok.is(tok::code_completion)) {
435 Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
436 Actions.FinalizeDeclaration(OmpPrivParm);
437 cutOffParsing();
438 return;
439 }
440
Alexey Bataev3c676e32019-11-12 11:19:26 -0500441 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
Alexey Bataev1fcc9b62020-01-02 15:49:08 -0500442 ExprResult Init = ParseInitializer();
Alexey Bataev070f43a2017-09-06 14:49:58 +0000443
444 if (Init.isInvalid()) {
445 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
446 Actions.ActOnInitializerError(OmpPrivParm);
447 } else {
448 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
449 /*DirectInit=*/false);
450 }
451 } else if (Tok.is(tok::l_paren)) {
452 // Parse C++ direct initializer: '(' expression-list ')'
453 BalancedDelimiterTracker T(*this, tok::l_paren);
454 T.consumeOpen();
455
456 ExprVector Exprs;
457 CommaLocsTy CommaLocs;
458
Ilya Biryukov2fab2352018-08-30 13:08:03 +0000459 SourceLocation LParLoc = T.getOpenLocation();
Ilya Biryukovff2a9972019-02-26 11:01:50 +0000460 auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
461 QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
462 getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
463 OmpPrivParm->getLocation(), Exprs, LParLoc);
464 CalledSignatureHelp = true;
465 return PreferredType;
466 };
467 if (ParseExpressionList(Exprs, CommaLocs, [&] {
468 PreferredType.enterFunctionArgument(Tok.getLocation(),
469 RunSignatureHelp);
470 })) {
471 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
472 RunSignatureHelp();
Alexey Bataev070f43a2017-09-06 14:49:58 +0000473 Actions.ActOnInitializerError(OmpPrivParm);
474 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
475 } else {
476 // Match the ')'.
Alexey Bataevdbc72c92018-07-06 19:35:42 +0000477 SourceLocation RLoc = Tok.getLocation();
478 if (!T.consumeClose())
479 RLoc = T.getCloseLocation();
Alexey Bataev070f43a2017-09-06 14:49:58 +0000480
481 assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
482 "Unexpected number of commas!");
483
Alexey Bataevdbc72c92018-07-06 19:35:42 +0000484 ExprResult Initializer =
485 Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
Alexey Bataev070f43a2017-09-06 14:49:58 +0000486 Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
487 /*DirectInit=*/true);
488 }
489 } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
490 // Parse C++0x braced-init-list.
491 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
492
493 ExprResult Init(ParseBraceInitializer());
494
495 if (Init.isInvalid()) {
496 Actions.ActOnInitializerError(OmpPrivParm);
497 } else {
498 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
499 /*DirectInit=*/true);
500 }
501 } else {
502 Actions.ActOnUninitializedDecl(OmpPrivParm);
503 }
504}
505
Michael Kruse251e1482019-02-01 20:25:04 +0000506/// Parses 'omp declare mapper' directive.
507///
508/// declare-mapper-directive:
509/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
510/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
511/// annot_pragma_openmp_end
512/// <mapper-identifier> and <var> are base language identifiers.
513///
514Parser::DeclGroupPtrTy
515Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
516 bool IsCorrect = true;
517 // Parse '('
518 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
519 if (T.expectAndConsume(diag::err_expected_lparen_after,
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600520 getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
Michael Kruse251e1482019-02-01 20:25:04 +0000521 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
522 return DeclGroupPtrTy();
523 }
524
525 // Parse <mapper-identifier>
526 auto &DeclNames = Actions.getASTContext().DeclarationNames;
527 DeclarationName MapperId;
528 if (PP.LookAhead(0).is(tok::colon)) {
529 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
530 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
531 IsCorrect = false;
532 } else {
533 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
534 }
535 ConsumeToken();
536 // Consume ':'.
537 ExpectAndConsume(tok::colon);
538 } else {
539 // If no mapper identifier is provided, its name is "default" by default
540 MapperId =
541 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
542 }
543
544 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
545 return DeclGroupPtrTy();
546
547 // Parse <type> <var>
548 DeclarationName VName;
549 QualType MapperType;
550 SourceRange Range;
551 TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
552 if (ParsedType.isUsable())
553 MapperType =
554 Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
555 if (MapperType.isNull())
556 IsCorrect = false;
557 if (!IsCorrect) {
558 SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
559 return DeclGroupPtrTy();
560 }
561
562 // Consume ')'.
563 IsCorrect &= !T.consumeClose();
564 if (!IsCorrect) {
565 SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
566 return DeclGroupPtrTy();
567 }
568
569 // Enter scope.
570 OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
571 getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
572 Range.getBegin(), VName, AS);
573 DeclarationNameInfo DirName;
574 SourceLocation Loc = Tok.getLocation();
575 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
576 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
577 ParseScope OMPDirectiveScope(this, ScopeFlags);
578 Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
579
580 // Add the mapper variable declaration.
581 Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
582 DMD, getCurScope(), MapperType, Range.getBegin(), VName);
583
584 // Parse map clauses.
585 SmallVector<OMPClause *, 6> Clauses;
586 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
587 OpenMPClauseKind CKind = Tok.isAnnotation()
588 ? OMPC_unknown
589 : getOpenMPClauseKind(PP.getSpelling(Tok));
590 Actions.StartOpenMPClause(CKind);
591 OMPClause *Clause =
592 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
593 if (Clause)
594 Clauses.push_back(Clause);
595 else
596 IsCorrect = false;
597 // Skip ',' if any.
598 if (Tok.is(tok::comma))
599 ConsumeToken();
600 Actions.EndOpenMPClause();
601 }
602 if (Clauses.empty()) {
603 Diag(Tok, diag::err_omp_expected_clause)
604 << getOpenMPDirectiveName(OMPD_declare_mapper);
605 IsCorrect = false;
606 }
607
608 // Exit scope.
609 Actions.EndOpenMPDSABlock(nullptr);
610 OMPDirectiveScope.Exit();
611
612 DeclGroupPtrTy DGP =
613 Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
614 if (!IsCorrect)
615 return DeclGroupPtrTy();
616 return DGP;
617}
618
619TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
620 DeclarationName &Name,
621 AccessSpecifier AS) {
622 // Parse the common declaration-specifiers piece.
623 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
624 DeclSpec DS(AttrFactory);
625 ParseSpecifierQualifierList(DS, AS, DSC);
626
627 // Parse the declarator.
628 DeclaratorContext Context = DeclaratorContext::PrototypeContext;
629 Declarator DeclaratorInfo(DS, Context);
630 ParseDeclarator(DeclaratorInfo);
631 Range = DeclaratorInfo.getSourceRange();
632 if (DeclaratorInfo.getIdentifier() == nullptr) {
633 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
634 return true;
635 }
636 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
637
638 return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
639}
640
Alexey Bataev2af33e32016-04-07 12:45:37 +0000641namespace {
642/// RAII that recreates function context for correct parsing of clauses of
643/// 'declare simd' construct.
644/// OpenMP, 2.8.2 declare simd Construct
645/// The expressions appearing in the clauses of this directive are evaluated in
646/// the scope of the arguments of the function declaration or definition.
647class FNContextRAII final {
648 Parser &P;
649 Sema::CXXThisScopeRAII *ThisScope;
650 Parser::ParseScope *TempScope;
651 Parser::ParseScope *FnScope;
652 bool HasTemplateScope = false;
653 bool HasFunScope = false;
654 FNContextRAII() = delete;
655 FNContextRAII(const FNContextRAII &) = delete;
656 FNContextRAII &operator=(const FNContextRAII &) = delete;
657
658public:
659 FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
660 Decl *D = *Ptr.get().begin();
661 NamedDecl *ND = dyn_cast<NamedDecl>(D);
662 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
663 Sema &Actions = P.getActions();
664
665 // Allow 'this' within late-parsed attributes.
Mikael Nilsson9d2872d2018-12-13 10:15:27 +0000666 ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
Alexey Bataev2af33e32016-04-07 12:45:37 +0000667 ND && ND->isCXXInstanceMember());
668
669 // If the Decl is templatized, add template parameters to scope.
670 HasTemplateScope = D->isTemplateDecl();
671 TempScope =
672 new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
673 if (HasTemplateScope)
674 Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
675
676 // If the Decl is on a function, add function parameters to the scope.
677 HasFunScope = D->isFunctionOrFunctionTemplate();
Momchil Velikov57c681f2017-08-10 15:43:06 +0000678 FnScope = new Parser::ParseScope(
679 &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
680 HasFunScope);
Alexey Bataev2af33e32016-04-07 12:45:37 +0000681 if (HasFunScope)
682 Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
683 }
684 ~FNContextRAII() {
685 if (HasFunScope) {
686 P.getActions().ActOnExitFunctionContext();
687 FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
688 }
689 if (HasTemplateScope)
690 TempScope->Exit();
691 delete FnScope;
692 delete TempScope;
693 delete ThisScope;
694 }
695};
696} // namespace
697
Alexey Bataevd93d3762016-04-12 09:35:56 +0000698/// Parses clauses for 'declare simd' directive.
699/// clause:
700/// 'inbranch' | 'notinbranch'
701/// 'simdlen' '(' <expr> ')'
702/// { 'uniform' '(' <argument_list> ')' }
703/// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
Alexey Bataevecba70f2016-04-12 11:02:11 +0000704/// { 'linear '(' <argument_list> [ ':' <step> ] ')' }
705static bool parseDeclareSimdClauses(
706 Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
707 SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
708 SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
709 SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
Alexey Bataevd93d3762016-04-12 09:35:56 +0000710 SourceRange BSRange;
711 const Token &Tok = P.getCurToken();
712 bool IsError = false;
713 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
714 if (Tok.isNot(tok::identifier))
715 break;
716 OMPDeclareSimdDeclAttr::BranchStateTy Out;
717 IdentifierInfo *II = Tok.getIdentifierInfo();
718 StringRef ClauseName = II->getName();
719 // Parse 'inranch|notinbranch' clauses.
720 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
721 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
722 P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
723 << ClauseName
724 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
725 IsError = true;
726 }
727 BS = Out;
728 BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
729 P.ConsumeToken();
730 } else if (ClauseName.equals("simdlen")) {
731 if (SimdLen.isUsable()) {
732 P.Diag(Tok, diag::err_omp_more_one_clause)
733 << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
734 IsError = true;
735 }
736 P.ConsumeToken();
737 SourceLocation RLoc;
738 SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
739 if (SimdLen.isInvalid())
740 IsError = true;
741 } else {
742 OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
Alexey Bataevecba70f2016-04-12 11:02:11 +0000743 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
744 CKind == OMPC_linear) {
Alexey Bataevd93d3762016-04-12 09:35:56 +0000745 Parser::OpenMPVarListDataTy Data;
Alexey Bataev61908f652018-04-23 19:53:05 +0000746 SmallVectorImpl<Expr *> *Vars = &Uniforms;
Alexey Bataev3732f4e2019-12-24 16:02:58 -0500747 if (CKind == OMPC_aligned) {
Alexey Bataevd93d3762016-04-12 09:35:56 +0000748 Vars = &Aligneds;
Alexey Bataev3732f4e2019-12-24 16:02:58 -0500749 } else if (CKind == OMPC_linear) {
750 Data.ExtraModifier = OMPC_LINEAR_val;
Alexey Bataevecba70f2016-04-12 11:02:11 +0000751 Vars = &Linears;
Alexey Bataev3732f4e2019-12-24 16:02:58 -0500752 }
Alexey Bataevd93d3762016-04-12 09:35:56 +0000753
754 P.ConsumeToken();
755 if (P.ParseOpenMPVarList(OMPD_declare_simd,
756 getOpenMPClauseKind(ClauseName), *Vars, Data))
757 IsError = true;
Alexey Bataev61908f652018-04-23 19:53:05 +0000758 if (CKind == OMPC_aligned) {
Alexey Bataev13a15042020-04-01 15:06:38 -0400759 Alignments.append(Aligneds.size() - Alignments.size(),
760 Data.DepModOrTailExpr);
Alexey Bataev61908f652018-04-23 19:53:05 +0000761 } else if (CKind == OMPC_linear) {
Alexey Bataev3732f4e2019-12-24 16:02:58 -0500762 assert(0 <= Data.ExtraModifier &&
763 Data.ExtraModifier <= OMPC_LINEAR_unknown &&
764 "Unexpected linear modifier.");
Alexey Bataev93dc40d2019-12-20 11:04:57 -0500765 if (P.getActions().CheckOpenMPLinearModifier(
766 static_cast<OpenMPLinearClauseKind>(Data.ExtraModifier),
Alexey Bataev1236eb62020-03-23 17:30:38 -0400767 Data.ExtraModifierLoc))
Alexey Bataev93dc40d2019-12-20 11:04:57 -0500768 Data.ExtraModifier = OMPC_LINEAR_val;
Alexey Bataevecba70f2016-04-12 11:02:11 +0000769 LinModifiers.append(Linears.size() - LinModifiers.size(),
Alexey Bataev93dc40d2019-12-20 11:04:57 -0500770 Data.ExtraModifier);
Alexey Bataev13a15042020-04-01 15:06:38 -0400771 Steps.append(Linears.size() - Steps.size(), Data.DepModOrTailExpr);
Alexey Bataevecba70f2016-04-12 11:02:11 +0000772 }
Alexey Bataevd93d3762016-04-12 09:35:56 +0000773 } else
774 // TODO: add parsing of other clauses.
775 break;
776 }
777 // Skip ',' if any.
778 if (Tok.is(tok::comma))
779 P.ConsumeToken();
780 }
781 return IsError;
782}
783
Alexey Bataev2af33e32016-04-07 12:45:37 +0000784/// Parse clauses for '#pragma omp declare simd'.
785Parser::DeclGroupPtrTy
786Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
787 CachedTokens &Toks, SourceLocation Loc) {
Ilya Biryukov929af672019-05-17 09:32:05 +0000788 PP.EnterToken(Tok, /*IsReinject*/ true);
789 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
790 /*IsReinject*/ true);
Alexey Bataev2af33e32016-04-07 12:45:37 +0000791 // Consume the previously pushed token.
792 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
Alexey Bataevd158cf62019-09-13 20:18:17 +0000793 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
Alexey Bataev2af33e32016-04-07 12:45:37 +0000794
795 FNContextRAII FnContext(*this, Ptr);
796 OMPDeclareSimdDeclAttr::BranchStateTy BS =
797 OMPDeclareSimdDeclAttr::BS_Undefined;
798 ExprResult Simdlen;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +0000799 SmallVector<Expr *, 4> Uniforms;
Alexey Bataevd93d3762016-04-12 09:35:56 +0000800 SmallVector<Expr *, 4> Aligneds;
801 SmallVector<Expr *, 4> Alignments;
Alexey Bataevecba70f2016-04-12 11:02:11 +0000802 SmallVector<Expr *, 4> Linears;
803 SmallVector<unsigned, 4> LinModifiers;
804 SmallVector<Expr *, 4> Steps;
805 bool IsError =
806 parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
807 Alignments, Linears, LinModifiers, Steps);
Johannes Doerfert56d15532020-02-21 13:48:56 -0600808 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
Alexey Bataev2af33e32016-04-07 12:45:37 +0000809 // Skip the last annot_pragma_openmp_end.
Richard Smithaf3b3252017-05-18 19:21:48 +0000810 SourceLocation EndLoc = ConsumeAnnotationToken();
Alexey Bataev61908f652018-04-23 19:53:05 +0000811 if (IsError)
812 return Ptr;
813 return Actions.ActOnOpenMPDeclareSimdDirective(
814 Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
815 LinModifiers, Steps, SourceRange(Loc, EndLoc));
Alexey Bataev20dfd772016-04-04 10:12:15 +0000816}
817
Johannes Doerfert1228d422019-12-19 20:42:12 -0600818namespace {
819/// Constant used in the diagnostics to distinguish the levels in an OpenMP
820/// contexts: selector-set={selector(trait, ...), ...}, ....
821enum OMPContextLvl {
822 CONTEXT_SELECTOR_SET_LVL = 0,
823 CONTEXT_SELECTOR_LVL = 1,
824 CONTEXT_TRAIT_LVL = 2,
825};
826
827static StringRef stringLiteralParser(Parser &P) {
828 ExprResult Res = P.ParseStringLiteralExpression(true);
829 return Res.isUsable() ? Res.getAs<StringLiteral>()->getString() : "";
830}
831
832static StringRef getNameFromIdOrString(Parser &P, Token &Tok,
833 OMPContextLvl Lvl) {
834 if (Tok.is(tok::identifier)) {
835 llvm::SmallString<16> Buffer;
836 StringRef Name = P.getPreprocessor().getSpelling(Tok, Buffer);
837 (void)P.ConsumeToken();
838 return Name;
839 }
840
841 if (tok::isStringLiteral(Tok.getKind()))
842 return stringLiteralParser(P);
843
844 P.Diag(Tok.getLocation(),
845 diag::warn_omp_declare_variant_string_literal_or_identifier)
846 << Lvl;
847 return "";
848}
849
850static bool checkForDuplicates(Parser &P, StringRef Name,
851 SourceLocation NameLoc,
852 llvm::StringMap<SourceLocation> &Seen,
853 OMPContextLvl Lvl) {
854 auto Res = Seen.try_emplace(Name, NameLoc);
855 if (Res.second)
856 return false;
857
858 // Each trait-set-selector-name, trait-selector-name and trait-name can
859 // only be specified once.
860 P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
861 << Lvl << Name;
862 P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
863 << Lvl << Name;
864 return true;
865}
866} // namespace
867
868void Parser::parseOMPTraitPropertyKind(
Reid Klecknerba1ffd22020-04-03 12:35:30 -0700869 OMPTraitProperty &TIProperty, llvm::omp::TraitSet Set,
Johannes Doerfert1228d422019-12-19 20:42:12 -0600870 llvm::omp::TraitSelector Selector, llvm::StringMap<SourceLocation> &Seen) {
871 TIProperty.Kind = TraitProperty::invalid;
872
873 SourceLocation NameLoc = Tok.getLocation();
874 StringRef Name =
875 getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
876 if (Name.empty()) {
877 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
878 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
879 return;
880 }
881
882 TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Name);
883 if (TIProperty.Kind != TraitProperty::invalid) {
884 if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
885 TIProperty.Kind = TraitProperty::invalid;
886 return;
887 }
888
889 // It follows diagnosis and helping notes.
890 // FIXME: We should move the diagnosis string generation into libFrontend.
891 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
892 << Name << getOpenMPContextTraitSelectorName(Selector)
893 << getOpenMPContextTraitSetName(Set);
894
895 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
896 if (SetForName != TraitSet::invalid) {
897 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
898 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
899 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
900 << Name << "<selector-name>"
901 << "(<property-name>)";
902 return;
903 }
904 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
905 if (SelectorForName != TraitSelector::invalid) {
906 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
907 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
908 bool AllowsTraitScore = false;
909 bool RequiresProperty = false;
910 isValidTraitSelectorForTraitSet(
911 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
912 AllowsTraitScore, RequiresProperty);
913 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
914 << getOpenMPContextTraitSetName(
915 getOpenMPContextTraitSetForSelector(SelectorForName))
916 << Name << (RequiresProperty ? "(<property-name>)" : "");
917 return;
918 }
919 for (const auto &PotentialSet :
920 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
921 TraitSet::device}) {
922 TraitProperty PropertyForName =
923 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
924 if (PropertyForName == TraitProperty::invalid)
925 continue;
926 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
927 << getOpenMPContextTraitSetName(
928 getOpenMPContextTraitSetForProperty(PropertyForName))
929 << getOpenMPContextTraitSelectorName(
930 getOpenMPContextTraitSelectorForProperty(PropertyForName))
931 << ("(" + Name + ")").str();
932 return;
933 }
934 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
935 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
936}
937
Johannes Doerferta19eb1d2020-04-03 11:29:53 -0500938static bool checkExtensionProperty(Parser &P, SourceLocation Loc,
939 OMPTraitProperty &TIProperty,
940 OMPTraitSelector &TISelector,
941 llvm::StringMap<SourceLocation> &Seen) {
942 assert(TISelector.Kind ==
943 llvm::omp::TraitSelector::implementation_extension &&
944 "Only for extension properties, e.g., "
945 "`implementation={extension(PROPERTY)}`");
946 if (TIProperty.Kind == TraitProperty::invalid)
947 return false;
948
949 auto IsMatchExtension = [](OMPTraitProperty &TP) {
950 return (TP.Kind ==
951 llvm::omp::TraitProperty::implementation_extension_match_all ||
952 TP.Kind ==
953 llvm::omp::TraitProperty::implementation_extension_match_any ||
954 TP.Kind ==
955 llvm::omp::TraitProperty::implementation_extension_match_none);
956 };
957
958 if (IsMatchExtension(TIProperty)) {
959 for (OMPTraitProperty &SeenProp : TISelector.Properties)
960 if (IsMatchExtension(SeenProp)) {
961 P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
962 StringRef SeenName =
963 llvm::omp::getOpenMPContextTraitPropertyName(SeenProp.Kind);
964 SourceLocation SeenLoc = Seen[SeenName];
965 P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
966 << CONTEXT_TRAIT_LVL << SeenName;
967 return false;
968 }
969 return true;
970 }
971
972 llvm_unreachable("Unknown extension property!");
973}
974
Reid Klecknerba1ffd22020-04-03 12:35:30 -0700975void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
Johannes Doerfert1228d422019-12-19 20:42:12 -0600976 llvm::omp::TraitSet Set,
977 llvm::StringMap<SourceLocation> &Seen) {
978 assert(TISelector.Kind != TraitSelector::user_condition &&
979 "User conditions are special properties not handled here!");
980
981 SourceLocation PropertyLoc = Tok.getLocation();
Reid Klecknerba1ffd22020-04-03 12:35:30 -0700982 OMPTraitProperty TIProperty;
Johannes Doerfert1228d422019-12-19 20:42:12 -0600983 parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen);
984
Johannes Doerferta19eb1d2020-04-03 11:29:53 -0500985 if (TISelector.Kind == llvm::omp::TraitSelector::implementation_extension)
986 if (!checkExtensionProperty(*this, Tok.getLocation(), TIProperty,
987 TISelector, Seen))
988 TIProperty.Kind = TraitProperty::invalid;
989
Johannes Doerfert1228d422019-12-19 20:42:12 -0600990 // If we have an invalid property here we already issued a warning.
991 if (TIProperty.Kind == TraitProperty::invalid) {
992 if (PropertyLoc != Tok.getLocation())
993 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
994 << CONTEXT_TRAIT_LVL;
995 return;
996 }
997
998 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind,
999 TISelector.Kind, Set)) {
Johannes Doerferta19eb1d2020-04-03 11:29:53 -05001000
Johannes Doerfert1228d422019-12-19 20:42:12 -06001001 // If we make it here the property, selector, set, score, condition, ... are
1002 // all valid (or have been corrected). Thus we can record the property.
1003 TISelector.Properties.push_back(TIProperty);
1004 return;
1005 }
1006
1007 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
1008 << getOpenMPContextTraitPropertyName(TIProperty.Kind)
1009 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1010 << getOpenMPContextTraitSetName(Set);
1011 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1012 << getOpenMPContextTraitPropertyName(TIProperty.Kind)
1013 << getOpenMPContextTraitSelectorName(
1014 getOpenMPContextTraitSelectorForProperty(TIProperty.Kind))
1015 << getOpenMPContextTraitSetName(
1016 getOpenMPContextTraitSetForProperty(TIProperty.Kind));
1017 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1018 << CONTEXT_TRAIT_LVL;
1019}
1020
1021void Parser::parseOMPTraitSelectorKind(
Reid Klecknerba1ffd22020-04-03 12:35:30 -07001022 OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
Johannes Doerfert1228d422019-12-19 20:42:12 -06001023 llvm::StringMap<SourceLocation> &Seen) {
1024 TISelector.Kind = TraitSelector::invalid;
1025
1026 SourceLocation NameLoc = Tok.getLocation();
1027 StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_LVL
1028 );
1029 if (Name.empty()) {
1030 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1031 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1032 return;
1033 }
1034
1035 TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
1036 if (TISelector.Kind != TraitSelector::invalid) {
1037 if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1038 TISelector.Kind = TraitSelector::invalid;
1039 return;
1040 }
1041
1042 // It follows diagnosis and helping notes.
1043 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1044 << Name << getOpenMPContextTraitSetName(Set);
1045
1046 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1047 if (SetForName != TraitSet::invalid) {
1048 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1049 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1050 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1051 << Name << "<selector-name>"
1052 << "<property-name>";
1053 return;
1054 }
1055 for (const auto &PotentialSet :
1056 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1057 TraitSet::device}) {
1058 TraitProperty PropertyForName =
1059 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
1060 if (PropertyForName == TraitProperty::invalid)
1061 continue;
1062 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1063 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1064 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1065 << getOpenMPContextTraitSetName(
1066 getOpenMPContextTraitSetForProperty(PropertyForName))
1067 << getOpenMPContextTraitSelectorName(
1068 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1069 << ("(" + Name + ")").str();
1070 return;
1071 }
1072 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1073 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1074}
1075
Alexey Bataeva15a1412019-10-02 18:19:02 +00001076/// Parse optional 'score' '(' <expr> ')' ':'.
1077static ExprResult parseContextScore(Parser &P) {
1078 ExprResult ScoreExpr;
Johannes Doerfert1228d422019-12-19 20:42:12 -06001079 llvm::SmallString<16> Buffer;
Alexey Bataeva15a1412019-10-02 18:19:02 +00001080 StringRef SelectorName =
1081 P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
Alexey Bataevdcec2ac2019-11-05 15:33:18 -05001082 if (!SelectorName.equals("score"))
Alexey Bataeva15a1412019-10-02 18:19:02 +00001083 return ScoreExpr;
Alexey Bataeva15a1412019-10-02 18:19:02 +00001084 (void)P.ConsumeToken();
1085 SourceLocation RLoc;
1086 ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
1087 // Parse ':'
1088 if (P.getCurToken().is(tok::colon))
1089 (void)P.ConsumeAnyToken();
1090 else
Johannes Doerfert1228d422019-12-19 20:42:12 -06001091 P.Diag(P.getCurToken(), diag::warn_omp_declare_variant_expected)
1092 << "':'"
1093 << "score expression";
Alexey Bataeva15a1412019-10-02 18:19:02 +00001094 return ScoreExpr;
1095}
1096
Johannes Doerfert1228d422019-12-19 20:42:12 -06001097/// Parses an OpenMP context selector.
1098///
1099/// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
1100void Parser::parseOMPContextSelector(
Reid Klecknerba1ffd22020-04-03 12:35:30 -07001101 OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
Johannes Doerfert1228d422019-12-19 20:42:12 -06001102 llvm::StringMap<SourceLocation> &SeenSelectors) {
1103 unsigned short OuterPC = ParenCount;
Alexey Bataev9ff34742019-09-25 19:43:37 +00001104
Johannes Doerfert1228d422019-12-19 20:42:12 -06001105 // If anything went wrong we issue an error or warning and then skip the rest
1106 // of the selector. However, commas are ambiguous so we look for the nesting
1107 // of parentheses here as well.
1108 auto FinishSelector = [OuterPC, this]() -> void {
1109 bool Done = false;
1110 while (!Done) {
1111 while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1112 tok::annot_pragma_openmp_end},
1113 StopBeforeMatch))
1114 ;
1115 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1116 (void)ConsumeParen();
1117 if (OuterPC <= ParenCount) {
1118 Done = true;
1119 break;
Alexey Bataev4e8231b2019-11-05 15:13:30 -05001120 }
Johannes Doerfert1228d422019-12-19 20:42:12 -06001121 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1122 Done = true;
1123 break;
Alexey Bataev4e8231b2019-11-05 15:13:30 -05001124 }
Johannes Doerfert1228d422019-12-19 20:42:12 -06001125 (void)ConsumeAnyToken();
1126 }
1127 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1128 << CONTEXT_SELECTOR_LVL;
1129 };
Alexey Bataev4e8231b2019-11-05 15:13:30 -05001130
Johannes Doerfert1228d422019-12-19 20:42:12 -06001131 SourceLocation SelectorLoc = Tok.getLocation();
1132 parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1133 if (TISelector.Kind == TraitSelector::invalid)
1134 return FinishSelector();
1135
1136 bool AllowsTraitScore = false;
1137 bool RequiresProperty = false;
1138 if (!isValidTraitSelectorForTraitSet(TISelector.Kind, Set, AllowsTraitScore,
1139 RequiresProperty)) {
1140 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1141 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1142 << getOpenMPContextTraitSetName(Set);
1143 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1144 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1145 << getOpenMPContextTraitSetName(
1146 getOpenMPContextTraitSetForSelector(TISelector.Kind))
1147 << RequiresProperty;
1148 return FinishSelector();
1149 }
1150
1151 if (!RequiresProperty) {
1152 TISelector.Properties.push_back(
1153 {getOpenMPContextTraitPropertyForSelector(TISelector.Kind)});
1154 return;
1155 }
1156
1157 if (!Tok.is(tok::l_paren)) {
1158 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1159 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1160 << getOpenMPContextTraitSetName(Set);
1161 return FinishSelector();
1162 }
1163
1164 if (TISelector.Kind == TraitSelector::user_condition) {
1165 SourceLocation RLoc;
1166 ExprResult Condition = ParseOpenMPParensExpr("user condition", RLoc);
1167 if (!Condition.isUsable())
1168 return FinishSelector();
1169 TISelector.ScoreOrCondition = Condition.get();
1170 TISelector.Properties.push_back({TraitProperty::user_condition_unknown});
1171 return;
1172 }
1173
1174 BalancedDelimiterTracker BDT(*this, tok::l_paren,
1175 tok::annot_pragma_openmp_end);
1176 // Parse '('.
1177 (void)BDT.consumeOpen();
1178
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001179 SourceLocation ScoreLoc = Tok.getLocation();
Johannes Doerfert1228d422019-12-19 20:42:12 -06001180 ExprResult Score = parseContextScore(*this);
1181
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001182 if (!AllowsTraitScore && !Score.isUnset()) {
1183 if (Score.isUsable()) {
1184 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1185 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1186 << getOpenMPContextTraitSetName(Set) << Score.get();
1187 } else {
1188 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1189 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1190 << getOpenMPContextTraitSetName(Set) << "<invalid>";
1191 }
Johannes Doerfert1228d422019-12-19 20:42:12 -06001192 Score = ExprResult();
1193 }
1194
1195 if (Score.isUsable())
1196 TISelector.ScoreOrCondition = Score.get();
1197
1198 llvm::StringMap<SourceLocation> SeenProperties;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001199 do {
Johannes Doerfert1228d422019-12-19 20:42:12 -06001200 parseOMPContextProperty(TISelector, Set, SeenProperties);
1201 } while (TryConsumeToken(tok::comma));
1202
1203 // Parse ')'.
1204 BDT.consumeClose();
1205}
1206
Reid Klecknerba1ffd22020-04-03 12:35:30 -07001207void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
Johannes Doerfert1228d422019-12-19 20:42:12 -06001208 llvm::StringMap<SourceLocation> &Seen) {
1209 TISet.Kind = TraitSet::invalid;
1210
1211 SourceLocation NameLoc = Tok.getLocation();
1212 StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_SET_LVL
1213 );
1214 if (Name.empty()) {
1215 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1216 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1217 return;
1218 }
1219
1220 TISet.Kind = getOpenMPContextTraitSetKind(Name);
1221 if (TISet.Kind != TraitSet::invalid) {
1222 if (checkForDuplicates(*this, Name, NameLoc, Seen,
1223 CONTEXT_SELECTOR_SET_LVL))
1224 TISet.Kind = TraitSet::invalid;
1225 return;
1226 }
1227
1228 // It follows diagnosis and helping notes.
1229 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1230
1231 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1232 if (SelectorForName != TraitSelector::invalid) {
1233 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1234 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1235 bool AllowsTraitScore = false;
1236 bool RequiresProperty = false;
1237 isValidTraitSelectorForTraitSet(
1238 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1239 AllowsTraitScore, RequiresProperty);
1240 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1241 << getOpenMPContextTraitSetName(
1242 getOpenMPContextTraitSetForSelector(SelectorForName))
1243 << Name << (RequiresProperty ? "(<property-name>)" : "");
1244 return;
1245 }
1246 for (const auto &PotentialSet :
1247 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1248 TraitSet::device}) {
1249 TraitProperty PropertyForName =
1250 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
1251 if (PropertyForName == TraitProperty::invalid)
1252 continue;
1253 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1254 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1255 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1256 << getOpenMPContextTraitSetName(
1257 getOpenMPContextTraitSetForProperty(PropertyForName))
1258 << getOpenMPContextTraitSelectorName(
1259 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1260 << ("(" + Name + ")").str();
1261 return;
1262 }
1263 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1264 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1265}
1266
1267/// Parses an OpenMP context selector set.
1268///
1269/// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
1270void Parser::parseOMPContextSelectorSet(
Reid Klecknerba1ffd22020-04-03 12:35:30 -07001271 OMPTraitSet &TISet,
Johannes Doerfert1228d422019-12-19 20:42:12 -06001272 llvm::StringMap<SourceLocation> &SeenSets) {
1273 auto OuterBC = BraceCount;
1274
1275 // If anything went wrong we issue an error or warning and then skip the rest
1276 // of the set. However, commas are ambiguous so we look for the nesting
1277 // of braces here as well.
1278 auto FinishSelectorSet = [this, OuterBC]() -> void {
1279 bool Done = false;
1280 while (!Done) {
1281 while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1282 tok::annot_pragma_openmp_end},
1283 StopBeforeMatch))
1284 ;
1285 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1286 (void)ConsumeBrace();
1287 if (OuterBC <= BraceCount) {
1288 Done = true;
1289 break;
1290 }
1291 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1292 Done = true;
1293 break;
1294 }
1295 (void)ConsumeAnyToken();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001296 }
Johannes Doerfert1228d422019-12-19 20:42:12 -06001297 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1298 << CONTEXT_SELECTOR_SET_LVL;
1299 };
1300
1301 parseOMPTraitSetKind(TISet, SeenSets);
1302 if (TISet.Kind == TraitSet::invalid)
1303 return FinishSelectorSet();
1304
1305 // Parse '='.
1306 if (!TryConsumeToken(tok::equal))
1307 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1308 << "="
1309 << ("context set name \"" + getOpenMPContextTraitSetName(TISet.Kind) +
1310 "\"")
1311 .str();
1312
1313 // Parse '{'.
1314 if (Tok.is(tok::l_brace)) {
1315 (void)ConsumeBrace();
1316 } else {
1317 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1318 << "{"
1319 << ("'=' that follows the context set name \"" +
1320 getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1321 .str();
1322 }
1323
1324 llvm::StringMap<SourceLocation> SeenSelectors;
1325 do {
Reid Klecknerba1ffd22020-04-03 12:35:30 -07001326 OMPTraitSelector TISelector;
Johannes Doerfert1228d422019-12-19 20:42:12 -06001327 parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors);
1328 if (TISelector.Kind != TraitSelector::invalid &&
1329 !TISelector.Properties.empty())
1330 TISet.Selectors.push_back(TISelector);
1331 } while (TryConsumeToken(tok::comma));
1332
1333 // Parse '}'.
1334 if (Tok.is(tok::r_brace)) {
1335 (void)ConsumeBrace();
1336 } else {
1337 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1338 << "}"
1339 << ("context selectors for the context set \"" +
1340 getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1341 .str();
1342 }
1343}
1344
1345/// Parse OpenMP context selectors:
1346///
1347/// <trait-set-selector> [, <trait-set-selector>]*
Reid Klecknerba1ffd22020-04-03 12:35:30 -07001348bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo& TI) {
Johannes Doerfert1228d422019-12-19 20:42:12 -06001349 llvm::StringMap<SourceLocation> SeenSets;
1350 do {
Reid Klecknerba1ffd22020-04-03 12:35:30 -07001351 OMPTraitSet TISet;
Johannes Doerfert1228d422019-12-19 20:42:12 -06001352 parseOMPContextSelectorSet(TISet, SeenSets);
1353 if (TISet.Kind != TraitSet::invalid && !TISet.Selectors.empty())
1354 TI.Sets.push_back(TISet);
1355 } while (TryConsumeToken(tok::comma));
1356
Alexey Bataevd158cf62019-09-13 20:18:17 +00001357 return false;
1358}
1359
1360/// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001361void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
1362 CachedTokens &Toks,
1363 SourceLocation Loc) {
Alexey Bataevd158cf62019-09-13 20:18:17 +00001364 PP.EnterToken(Tok, /*IsReinject*/ true);
1365 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1366 /*IsReinject*/ true);
1367 // Consume the previously pushed token.
1368 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1369 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1370
1371 FNContextRAII FnContext(*this, Ptr);
1372 // Parse function declaration id.
1373 SourceLocation RLoc;
1374 // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs
1375 // instead of MemberExprs.
Alexey Bataev02d04d52019-12-10 16:12:53 -05001376 ExprResult AssociatedFunction;
1377 {
1378 // Do not mark function as is used to prevent its emission if this is the
1379 // only place where it is used.
1380 EnterExpressionEvaluationContext Unevaluated(
1381 Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1382 AssociatedFunction = ParseOpenMPParensExpr(
1383 getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1384 /*IsAddressOfOperand=*/true);
1385 }
Alexey Bataevd158cf62019-09-13 20:18:17 +00001386 if (!AssociatedFunction.isUsable()) {
1387 if (!Tok.is(tok::annot_pragma_openmp_end))
1388 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1389 ;
1390 // Skip the last annot_pragma_openmp_end.
1391 (void)ConsumeAnnotationToken();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001392 return;
1393 }
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001394
Johannes Doerfertbefb4be2020-02-25 14:04:06 -08001395 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001396 if (parseOMPDeclareVariantMatchClause(Loc, TI))
1397 return;
1398
1399 Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1400 Actions.checkOpenMPDeclareVariantFunction(
1401 Ptr, AssociatedFunction.get(), TI,
1402 SourceRange(Loc, Tok.getLocation()));
1403
1404 // Skip last tokens.
1405 while (Tok.isNot(tok::annot_pragma_openmp_end))
1406 ConsumeAnyToken();
1407 if (DeclVarData && !TI.Sets.empty())
1408 Actions.ActOnOpenMPDeclareVariantDirective(
1409 DeclVarData->first, DeclVarData->second, TI,
1410 SourceRange(Loc, Tok.getLocation()));
1411
1412 // Skip the last annot_pragma_openmp_end.
1413 (void)ConsumeAnnotationToken();
1414}
1415
1416bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
1417 OMPTraitInfo &TI) {
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001418 // Parse 'match'.
Alexey Bataevdba792c2019-09-23 18:13:31 +00001419 OpenMPClauseKind CKind = Tok.isAnnotation()
1420 ? OMPC_unknown
1421 : getOpenMPClauseKind(PP.getSpelling(Tok));
1422 if (CKind != OMPC_match) {
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001423 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
Alexey Bataevdba792c2019-09-23 18:13:31 +00001424 << getOpenMPClauseName(OMPC_match);
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001425 while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
1426 ;
1427 // Skip the last annot_pragma_openmp_end.
1428 (void)ConsumeAnnotationToken();
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001429 return true;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001430 }
1431 (void)ConsumeToken();
1432 // Parse '('.
1433 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Alexey Bataevdba792c2019-09-23 18:13:31 +00001434 if (T.expectAndConsume(diag::err_expected_lparen_after,
Johannes Doerfert419a5592020-03-30 19:58:40 -05001435 getOpenMPClauseName(OMPC_match).data())) {
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001436 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1437 ;
1438 // Skip the last annot_pragma_openmp_end.
1439 (void)ConsumeAnnotationToken();
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001440 return true;
Alexey Bataevd158cf62019-09-13 20:18:17 +00001441 }
1442
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001443 // Parse inner context selectors.
Johannes Doerfertb86bf832020-02-15 18:07:42 -06001444 parseOMPContextSelectors(Loc, TI);
Johannes Doerfert1228d422019-12-19 20:42:12 -06001445
1446 // Parse ')'
1447 (void)T.consumeClose();
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001448 return false;
Alexey Bataevd158cf62019-09-13 20:18:17 +00001449}
1450
Alexey Bataev729e2422019-08-23 16:11:14 +00001451/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1452///
1453/// default-clause:
1454/// 'default' '(' 'none' | 'shared' ')
1455///
1456/// proc_bind-clause:
1457/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
1458///
1459/// device_type-clause:
1460/// 'device_type' '(' 'host' | 'nohost' | 'any' )'
1461namespace {
1462 struct SimpleClauseData {
1463 unsigned Type;
1464 SourceLocation Loc;
1465 SourceLocation LOpen;
1466 SourceLocation TypeLoc;
1467 SourceLocation RLoc;
1468 SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1469 SourceLocation TypeLoc, SourceLocation RLoc)
1470 : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1471 };
1472} // anonymous namespace
1473
1474static Optional<SimpleClauseData>
1475parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) {
1476 const Token &Tok = P.getCurToken();
1477 SourceLocation Loc = Tok.getLocation();
1478 SourceLocation LOpen = P.ConsumeToken();
1479 // Parse '('.
1480 BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
1481 if (T.expectAndConsume(diag::err_expected_lparen_after,
Johannes Doerfert419a5592020-03-30 19:58:40 -05001482 getOpenMPClauseName(Kind).data()))
Alexey Bataev729e2422019-08-23 16:11:14 +00001483 return llvm::None;
1484
1485 unsigned Type = getOpenMPSimpleClauseType(
1486 Kind, Tok.isAnnotation() ? "" : P.getPreprocessor().getSpelling(Tok));
1487 SourceLocation TypeLoc = Tok.getLocation();
1488 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1489 Tok.isNot(tok::annot_pragma_openmp_end))
1490 P.ConsumeAnyToken();
1491
1492 // Parse ')'.
1493 SourceLocation RLoc = Tok.getLocation();
1494 if (!T.consumeClose())
1495 RLoc = T.getCloseLocation();
1496
1497 return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc);
1498}
1499
Kelvin Lie0502752018-11-21 20:15:57 +00001500Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
1501 // OpenMP 4.5 syntax with list of entities.
1502 Sema::NamedDeclSetType SameDirectiveDecls;
Alexey Bataev729e2422019-08-23 16:11:14 +00001503 SmallVector<std::tuple<OMPDeclareTargetDeclAttr::MapTypeTy, SourceLocation,
1504 NamedDecl *>,
1505 4>
1506 DeclareTargetDecls;
1507 OMPDeclareTargetDeclAttr::DevTypeTy DT = OMPDeclareTargetDeclAttr::DT_Any;
1508 SourceLocation DeviceTypeLoc;
Kelvin Lie0502752018-11-21 20:15:57 +00001509 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1510 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1511 if (Tok.is(tok::identifier)) {
1512 IdentifierInfo *II = Tok.getIdentifierInfo();
1513 StringRef ClauseName = II->getName();
Alexey Bataev729e2422019-08-23 16:11:14 +00001514 bool IsDeviceTypeClause =
1515 getLangOpts().OpenMP >= 50 &&
1516 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1517 // Parse 'to|link|device_type' clauses.
1518 if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT) &&
1519 !IsDeviceTypeClause) {
1520 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1521 << ClauseName << (getLangOpts().OpenMP >= 50 ? 1 : 0);
Kelvin Lie0502752018-11-21 20:15:57 +00001522 break;
1523 }
Alexey Bataev729e2422019-08-23 16:11:14 +00001524 // Parse 'device_type' clause and go to next clause if any.
1525 if (IsDeviceTypeClause) {
1526 Optional<SimpleClauseData> DevTypeData =
1527 parseOpenMPSimpleClause(*this, OMPC_device_type);
1528 if (DevTypeData.hasValue()) {
1529 if (DeviceTypeLoc.isValid()) {
1530 // We already saw another device_type clause, diagnose it.
1531 Diag(DevTypeData.getValue().Loc,
1532 diag::warn_omp_more_one_device_type_clause);
1533 }
1534 switch(static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) {
1535 case OMPC_DEVICE_TYPE_any:
1536 DT = OMPDeclareTargetDeclAttr::DT_Any;
1537 break;
1538 case OMPC_DEVICE_TYPE_host:
1539 DT = OMPDeclareTargetDeclAttr::DT_Host;
1540 break;
1541 case OMPC_DEVICE_TYPE_nohost:
1542 DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1543 break;
1544 case OMPC_DEVICE_TYPE_unknown:
1545 llvm_unreachable("Unexpected device_type");
1546 }
1547 DeviceTypeLoc = DevTypeData.getValue().Loc;
1548 }
1549 continue;
1550 }
Kelvin Lie0502752018-11-21 20:15:57 +00001551 ConsumeToken();
1552 }
Alexey Bataev729e2422019-08-23 16:11:14 +00001553 auto &&Callback = [this, MT, &DeclareTargetDecls, &SameDirectiveDecls](
1554 CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
1555 NamedDecl *ND = Actions.lookupOpenMPDeclareTargetName(
1556 getCurScope(), SS, NameInfo, SameDirectiveDecls);
1557 if (ND)
1558 DeclareTargetDecls.emplace_back(MT, NameInfo.getLoc(), ND);
Kelvin Lie0502752018-11-21 20:15:57 +00001559 };
1560 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1561 /*AllowScopeSpecifier=*/true))
1562 break;
1563
1564 // Consume optional ','.
1565 if (Tok.is(tok::comma))
1566 ConsumeToken();
1567 }
1568 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1569 ConsumeAnyToken();
Alexey Bataev729e2422019-08-23 16:11:14 +00001570 for (auto &MTLocDecl : DeclareTargetDecls) {
1571 OMPDeclareTargetDeclAttr::MapTypeTy MT;
1572 SourceLocation Loc;
1573 NamedDecl *ND;
1574 std::tie(MT, Loc, ND) = MTLocDecl;
1575 // device_type clause is applied only to functions.
1576 Actions.ActOnOpenMPDeclareTargetName(
1577 ND, Loc, MT, isa<VarDecl>(ND) ? OMPDeclareTargetDeclAttr::DT_Any : DT);
1578 }
Kelvin Lie0502752018-11-21 20:15:57 +00001579 SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
1580 SameDirectiveDecls.end());
1581 if (Decls.empty())
1582 return DeclGroupPtrTy();
1583 return Actions.BuildDeclaratorGroup(Decls);
1584}
1585
Johannes Doerfert56d15532020-02-21 13:48:56 -06001586void Parser::skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind) {
1587 // The last seen token is annot_pragma_openmp_end - need to check for
1588 // extra tokens.
1589 if (Tok.is(tok::annot_pragma_openmp_end))
1590 return;
1591
1592 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1593 << getOpenMPDirectiveName(DKind);
1594 while (Tok.isNot(tok::annot_pragma_openmp_end))
1595 ConsumeAnyToken();
1596}
1597
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001598void Parser::parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
1599 OpenMPDirectiveKind ExpectedKind,
1600 OpenMPDirectiveKind FoundKind,
1601 SourceLocation BeginLoc,
1602 SourceLocation FoundLoc,
1603 bool SkipUntilOpenMPEnd) {
1604 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1605
1606 if (FoundKind == ExpectedKind) {
1607 ConsumeAnyToken();
1608 skipUntilPragmaOpenMPEnd(ExpectedKind);
Kelvin Lie0502752018-11-21 20:15:57 +00001609 return;
1610 }
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001611
1612 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1613 << DiagSelection;
1614 Diag(BeginLoc, diag::note_matching)
1615 << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind) + "'").str();
1616 if (SkipUntilOpenMPEnd)
1617 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1618}
1619
1620void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
1621 SourceLocation DKLoc) {
1622 parseOMPEndDirective(OMPD_declare_target, OMPD_end_declare_target, DKind,
1623 DKLoc, Tok.getLocation(),
1624 /* SkipUntilOpenMPEnd */ false);
Kelvin Lie0502752018-11-21 20:15:57 +00001625 // Skip the last annot_pragma_openmp_end.
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001626 if (Tok.is(tok::annot_pragma_openmp_end))
1627 ConsumeAnnotationToken();
Kelvin Lie0502752018-11-21 20:15:57 +00001628}
1629
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001630/// Parsing of declarative OpenMP directives.
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001631///
1632/// threadprivate-directive:
1633/// annot_pragma_openmp 'threadprivate' simple-variable-list
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001634/// annot_pragma_openmp_end
Alexey Bataeva769e072013-03-22 06:34:35 +00001635///
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001636/// allocate-directive:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001637/// annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001638/// annot_pragma_openmp_end
1639///
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001640/// declare-reduction-directive:
1641/// annot_pragma_openmp 'declare' 'reduction' [...]
1642/// annot_pragma_openmp_end
1643///
Michael Kruse251e1482019-02-01 20:25:04 +00001644/// declare-mapper-directive:
1645/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1646/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
1647/// annot_pragma_openmp_end
1648///
Alexey Bataev587e1de2016-03-30 10:43:55 +00001649/// declare-simd-directive:
1650/// annot_pragma_openmp 'declare simd' {<clause> [,]}
1651/// annot_pragma_openmp_end
1652/// <function declaration/definition>
1653///
Kelvin Li1408f912018-09-26 04:28:39 +00001654/// requires directive:
1655/// annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
1656/// annot_pragma_openmp_end
1657///
Alexey Bataev587e1de2016-03-30 10:43:55 +00001658Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
Alexey Bataevc972f6f2020-01-07 13:39:18 -05001659 AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
Alexey Bataev587e1de2016-03-30 10:43:55 +00001660 DeclSpec::TST TagType, Decl *Tag) {
Alexey Bataeva769e072013-03-22 06:34:35 +00001661 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
Alexey Bataev8035bb42019-12-13 16:05:30 -05001662 ParsingOpenMPDirectiveRAII DirScope(*this);
Alexey Bataevee6507d2013-11-18 08:17:37 +00001663 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Alexey Bataeva769e072013-03-22 06:34:35 +00001664
Alexey Bataevc972f6f2020-01-07 13:39:18 -05001665 SourceLocation Loc;
1666 OpenMPDirectiveKind DKind;
1667 if (Delayed) {
1668 TentativeParsingAction TPA(*this);
1669 Loc = ConsumeAnnotationToken();
1670 DKind = parseOpenMPDirectiveKind(*this);
1671 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1672 // Need to delay parsing until completion of the parent class.
1673 TPA.Revert();
1674 CachedTokens Toks;
1675 unsigned Cnt = 1;
1676 Toks.push_back(Tok);
1677 while (Cnt && Tok.isNot(tok::eof)) {
1678 (void)ConsumeAnyToken();
1679 if (Tok.is(tok::annot_pragma_openmp))
1680 ++Cnt;
1681 else if (Tok.is(tok::annot_pragma_openmp_end))
1682 --Cnt;
1683 Toks.push_back(Tok);
1684 }
1685 // Skip last annot_pragma_openmp_end.
1686 if (Cnt == 0)
1687 (void)ConsumeAnyToken();
1688 auto *LP = new LateParsedPragma(this, AS);
1689 LP->takeToks(Toks);
1690 getCurrentClass().LateParsedDeclarations.push_back(LP);
1691 return nullptr;
1692 }
1693 TPA.Commit();
1694 } else {
1695 Loc = ConsumeAnnotationToken();
1696 DKind = parseOpenMPDirectiveKind(*this);
1697 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001698
1699 switch (DKind) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001700 case OMPD_threadprivate: {
Alexey Bataeva769e072013-03-22 06:34:35 +00001701 ConsumeToken();
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001702 DeclDirectiveListParserHelper Helper(this, DKind);
1703 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1704 /*AllowScopeSpecifier=*/true)) {
Johannes Doerfert56d15532020-02-21 13:48:56 -06001705 skipUntilPragmaOpenMPEnd(DKind);
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001706 // Skip the last annot_pragma_openmp_end.
Richard Smithaf3b3252017-05-18 19:21:48 +00001707 ConsumeAnnotationToken();
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001708 return Actions.ActOnOpenMPThreadprivateDirective(Loc,
1709 Helper.getIdentifiers());
Alexey Bataeva769e072013-03-22 06:34:35 +00001710 }
1711 break;
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001712 }
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001713 case OMPD_allocate: {
1714 ConsumeToken();
1715 DeclDirectiveListParserHelper Helper(this, DKind);
1716 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1717 /*AllowScopeSpecifier=*/true)) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001718 SmallVector<OMPClause *, 1> Clauses;
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001719 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001720 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
Johannes Doerfert419a5592020-03-30 19:58:40 -05001721 unsigned(OMPC_unknown) + 1>
1722 FirstClauses(unsigned(OMPC_unknown) + 1);
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001723 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1724 OpenMPClauseKind CKind =
1725 Tok.isAnnotation() ? OMPC_unknown
1726 : getOpenMPClauseKind(PP.getSpelling(Tok));
1727 Actions.StartOpenMPClause(CKind);
Johannes Doerfert419a5592020-03-30 19:58:40 -05001728 OMPClause *Clause = ParseOpenMPClause(
1729 OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001730 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1731 StopBeforeMatch);
Johannes Doerfert419a5592020-03-30 19:58:40 -05001732 FirstClauses[unsigned(CKind)].setInt(true);
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001733 if (Clause != nullptr)
1734 Clauses.push_back(Clause);
1735 if (Tok.is(tok::annot_pragma_openmp_end)) {
1736 Actions.EndOpenMPClause();
1737 break;
1738 }
1739 // Skip ',' if any.
1740 if (Tok.is(tok::comma))
1741 ConsumeToken();
1742 Actions.EndOpenMPClause();
1743 }
Johannes Doerfert56d15532020-02-21 13:48:56 -06001744 skipUntilPragmaOpenMPEnd(DKind);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001745 }
1746 // Skip the last annot_pragma_openmp_end.
1747 ConsumeAnnotationToken();
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001748 return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
1749 Clauses);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001750 }
1751 break;
1752 }
Kelvin Li1408f912018-09-26 04:28:39 +00001753 case OMPD_requires: {
1754 SourceLocation StartLoc = ConsumeToken();
1755 SmallVector<OMPClause *, 5> Clauses;
Johannes Doerfert419a5592020-03-30 19:58:40 -05001756 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1757 unsigned(OMPC_unknown) + 1>
1758 FirstClauses(unsigned(OMPC_unknown) + 1);
Kelvin Li1408f912018-09-26 04:28:39 +00001759 if (Tok.is(tok::annot_pragma_openmp_end)) {
Ilya Biryukovff2a9972019-02-26 11:01:50 +00001760 Diag(Tok, diag::err_omp_expected_clause)
Kelvin Li1408f912018-09-26 04:28:39 +00001761 << getOpenMPDirectiveName(OMPD_requires);
1762 break;
1763 }
1764 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1765 OpenMPClauseKind CKind = Tok.isAnnotation()
1766 ? OMPC_unknown
1767 : getOpenMPClauseKind(PP.getSpelling(Tok));
1768 Actions.StartOpenMPClause(CKind);
Johannes Doerfert419a5592020-03-30 19:58:40 -05001769 OMPClause *Clause = ParseOpenMPClause(
1770 OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt());
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001771 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1772 StopBeforeMatch);
Johannes Doerfert419a5592020-03-30 19:58:40 -05001773 FirstClauses[unsigned(CKind)].setInt(true);
Kelvin Li1408f912018-09-26 04:28:39 +00001774 if (Clause != nullptr)
1775 Clauses.push_back(Clause);
1776 if (Tok.is(tok::annot_pragma_openmp_end)) {
1777 Actions.EndOpenMPClause();
1778 break;
1779 }
1780 // Skip ',' if any.
1781 if (Tok.is(tok::comma))
1782 ConsumeToken();
1783 Actions.EndOpenMPClause();
1784 }
1785 // Consume final annot_pragma_openmp_end
Alexey Bataev2d4f80f2020-02-11 15:15:21 -05001786 if (Clauses.empty()) {
Kelvin Li1408f912018-09-26 04:28:39 +00001787 Diag(Tok, diag::err_omp_expected_clause)
1788 << getOpenMPDirectiveName(OMPD_requires);
1789 ConsumeAnnotationToken();
1790 return nullptr;
1791 }
1792 ConsumeAnnotationToken();
1793 return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
1794 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001795 case OMPD_declare_reduction:
1796 ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +00001797 if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
Johannes Doerfert56d15532020-02-21 13:48:56 -06001798 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001799 // Skip the last annot_pragma_openmp_end.
Richard Smithaf3b3252017-05-18 19:21:48 +00001800 ConsumeAnnotationToken();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001801 return Res;
1802 }
1803 break;
Michael Kruse251e1482019-02-01 20:25:04 +00001804 case OMPD_declare_mapper: {
1805 ConsumeToken();
1806 if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1807 // Skip the last annot_pragma_openmp_end.
1808 ConsumeAnnotationToken();
1809 return Res;
1810 }
1811 break;
1812 }
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001813 case OMPD_begin_declare_variant: {
1814 // The syntax is:
1815 // { #pragma omp begin declare variant clause }
1816 // <function-declaration-or-definition-sequence>
1817 // { #pragma omp end declare variant }
1818 //
1819 ConsumeToken();
1820 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
1821 if (parseOMPDeclareVariantMatchClause(Loc, TI))
1822 break;
1823
1824 // Skip last tokens.
1825 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
1826
1827 VariantMatchInfo VMI;
1828 ASTContext &ASTCtx = Actions.getASTContext();
Johannes Doerferta19eb1d2020-04-03 11:29:53 -05001829 TI.getAsVariantMatchInfo(ASTCtx, VMI);
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001830 OMPContext OMPCtx(ASTCtx.getLangOpts().OpenMPIsDevice,
1831 ASTCtx.getTargetInfo().getTriple());
1832
Johannes Doerferta19eb1d2020-04-03 11:29:53 -05001833 if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
Johannes Doerfertbefb4be2020-02-25 14:04:06 -08001834 Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI);
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001835 break;
Johannes Doerfertbefb4be2020-02-25 14:04:06 -08001836 }
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001837
1838 // Elide all the code till the matching end declare variant was found.
1839 unsigned Nesting = 1;
1840 SourceLocation DKLoc;
1841 OpenMPDirectiveKind DK = OMPD_unknown;
1842 do {
1843 DKLoc = Tok.getLocation();
1844 DK = parseOpenMPDirectiveKind(*this);
1845 if (DK == OMPD_end_declare_variant)
1846 --Nesting;
1847 else if (DK == OMPD_begin_declare_variant)
1848 ++Nesting;
1849 if (!Nesting || isEofOrEom())
1850 break;
1851 ConsumeAnyToken();
1852 } while (true);
1853
1854 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
1855 DK, Loc, DKLoc, /* SkipUntilOpenMPEnd */ true);
1856 if (isEofOrEom())
1857 return nullptr;
1858 break;
1859 }
Johannes Doerfertbefb4be2020-02-25 14:04:06 -08001860 case OMPD_end_declare_variant: {
1861 if (Actions.isInOpenMPDeclareVariantScope())
1862 Actions.ActOnOpenMPEndDeclareVariant();
1863 else
1864 Diag(Loc, diag::err_expected_begin_declare_variant);
Johannes Doerfert095cecb2020-02-20 19:50:47 -06001865 ConsumeToken();
1866 break;
Johannes Doerfertbefb4be2020-02-25 14:04:06 -08001867 }
Alexey Bataevd158cf62019-09-13 20:18:17 +00001868 case OMPD_declare_variant:
Alexey Bataev587e1de2016-03-30 10:43:55 +00001869 case OMPD_declare_simd: {
1870 // The syntax is:
Alexey Bataevd158cf62019-09-13 20:18:17 +00001871 // { #pragma omp declare {simd|variant} }
Alexey Bataev587e1de2016-03-30 10:43:55 +00001872 // <function-declaration-or-definition>
1873 //
Alexey Bataev2af33e32016-04-07 12:45:37 +00001874 CachedTokens Toks;
Alexey Bataevd158cf62019-09-13 20:18:17 +00001875 Toks.push_back(Tok);
1876 ConsumeToken();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00001877 while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1878 Toks.push_back(Tok);
1879 ConsumeAnyToken();
1880 }
1881 Toks.push_back(Tok);
1882 ConsumeAnyToken();
Alexey Bataev587e1de2016-03-30 10:43:55 +00001883
1884 DeclGroupPtrTy Ptr;
Alexey Bataev61908f652018-04-23 19:53:05 +00001885 if (Tok.is(tok::annot_pragma_openmp)) {
Alexey Bataevc972f6f2020-01-07 13:39:18 -05001886 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
1887 TagType, Tag);
Alexey Bataev61908f652018-04-23 19:53:05 +00001888 } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
Alexey Bataev587e1de2016-03-30 10:43:55 +00001889 // Here we expect to see some function declaration.
1890 if (AS == AS_none) {
1891 assert(TagType == DeclSpec::TST_unspecified);
1892 MaybeParseCXX11Attributes(Attrs);
Alexey Bataev587e1de2016-03-30 10:43:55 +00001893 ParsingDeclSpec PDS(*this);
1894 Ptr = ParseExternalDeclaration(Attrs, &PDS);
1895 } else {
1896 Ptr =
1897 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1898 }
1899 }
1900 if (!Ptr) {
Alexey Bataevd158cf62019-09-13 20:18:17 +00001901 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
1902 << (DKind == OMPD_declare_simd ? 0 : 1);
Alexey Bataev587e1de2016-03-30 10:43:55 +00001903 return DeclGroupPtrTy();
1904 }
Alexey Bataevd158cf62019-09-13 20:18:17 +00001905 if (DKind == OMPD_declare_simd)
1906 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1907 assert(DKind == OMPD_declare_variant &&
1908 "Expected declare variant directive only");
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001909 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
1910 return Ptr;
Alexey Bataev587e1de2016-03-30 10:43:55 +00001911 }
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001912 case OMPD_declare_target: {
1913 SourceLocation DTLoc = ConsumeAnyToken();
1914 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Kelvin Lie0502752018-11-21 20:15:57 +00001915 return ParseOMPDeclareTargetClauses();
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001916 }
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001917
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001918 // Skip the last annot_pragma_openmp_end.
1919 ConsumeAnyToken();
1920
1921 if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1922 return DeclGroupPtrTy();
1923
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001924 llvm::SmallVector<Decl *, 4> Decls;
Alexey Bataev61908f652018-04-23 19:53:05 +00001925 DKind = parseOpenMPDirectiveKind(*this);
Kelvin Libc38e632018-09-10 02:07:09 +00001926 while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
1927 Tok.isNot(tok::r_brace)) {
Alexey Bataev502ec492017-10-03 20:00:00 +00001928 DeclGroupPtrTy Ptr;
1929 // Here we expect to see some function declaration.
1930 if (AS == AS_none) {
1931 assert(TagType == DeclSpec::TST_unspecified);
1932 MaybeParseCXX11Attributes(Attrs);
1933 ParsingDeclSpec PDS(*this);
1934 Ptr = ParseExternalDeclaration(Attrs, &PDS);
1935 } else {
1936 Ptr =
1937 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1938 }
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001939 if (Ptr) {
1940 DeclGroupRef Ref = Ptr.get();
1941 Decls.append(Ref.begin(), Ref.end());
1942 }
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001943 if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
1944 TentativeParsingAction TPA(*this);
Richard Smithaf3b3252017-05-18 19:21:48 +00001945 ConsumeAnnotationToken();
Alexey Bataev61908f652018-04-23 19:53:05 +00001946 DKind = parseOpenMPDirectiveKind(*this);
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001947 if (DKind != OMPD_end_declare_target)
1948 TPA.Revert();
1949 else
1950 TPA.Commit();
1951 }
1952 }
1953
Kelvin Lie0502752018-11-21 20:15:57 +00001954 ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001955 Actions.ActOnFinishOpenMPDeclareTargetDirective();
Alexey Bataev34f8a702018-03-28 14:28:54 +00001956 return Actions.BuildDeclaratorGroup(Decls);
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001957 }
Alexey Bataeva769e072013-03-22 06:34:35 +00001958 case OMPD_unknown:
1959 Diag(Tok, diag::err_omp_unknown_directive);
1960 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001961 case OMPD_parallel:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001962 case OMPD_simd:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001963 case OMPD_task:
Alexey Bataev68446b72014-07-18 07:47:19 +00001964 case OMPD_taskyield:
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001965 case OMPD_barrier:
Alexey Bataev2df347a2014-07-18 10:17:07 +00001966 case OMPD_taskwait:
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001967 case OMPD_taskgroup:
Alexey Bataev6125da92014-07-21 11:26:11 +00001968 case OMPD_flush:
Alexey Bataevc112e942020-02-28 09:52:15 -05001969 case OMPD_depobj:
Alexey Bataevfcba7c32020-03-20 07:03:01 -04001970 case OMPD_scan:
Alexey Bataevf29276e2014-06-18 04:14:57 +00001971 case OMPD_for:
Alexander Musmanf82886e2014-09-18 05:12:34 +00001972 case OMPD_for_simd:
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001973 case OMPD_sections:
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001974 case OMPD_section:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001975 case OMPD_single:
Alexander Musman80c22892014-07-17 08:54:58 +00001976 case OMPD_master:
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001977 case OMPD_ordered:
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001978 case OMPD_critical:
Alexey Bataev4acb8592014-07-07 13:01:15 +00001979 case OMPD_parallel_for:
Alexander Musmane4e893b2014-09-23 09:33:00 +00001980 case OMPD_parallel_for_simd:
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001981 case OMPD_parallel_sections:
cchen47d60942019-12-05 13:43:48 -05001982 case OMPD_parallel_master:
Alexey Bataev0162e452014-07-22 10:10:35 +00001983 case OMPD_atomic:
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001984 case OMPD_target:
Alexey Bataev13314bf2014-10-09 04:18:56 +00001985 case OMPD_teams:
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001986 case OMPD_cancellation_point:
Alexey Bataev80909872015-07-02 11:25:17 +00001987 case OMPD_cancel:
Samuel Antao5b0688e2015-07-22 16:02:46 +00001988 case OMPD_target_data:
Samuel Antaodf67fc42016-01-19 19:15:56 +00001989 case OMPD_target_enter_data:
Samuel Antao72590762016-01-19 20:04:50 +00001990 case OMPD_target_exit_data:
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001991 case OMPD_target_parallel:
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00001992 case OMPD_target_parallel_for:
Alexey Bataev49f6e782015-12-01 04:18:41 +00001993 case OMPD_taskloop:
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001994 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +00001995 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00001996 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +00001997 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -04001998 case OMPD_parallel_master_taskloop_simd:
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001999 case OMPD_distribute:
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00002000 case OMPD_end_declare_target:
Samuel Antao686c70c2016-05-26 17:30:50 +00002001 case OMPD_target_update:
Carlo Bertolli9925f152016-06-27 14:55:37 +00002002 case OMPD_distribute_parallel_for:
Kelvin Li4a39add2016-07-05 05:00:15 +00002003 case OMPD_distribute_parallel_for_simd:
Kelvin Li787f3fc2016-07-06 04:45:38 +00002004 case OMPD_distribute_simd:
Kelvin Lia579b912016-07-14 02:54:56 +00002005 case OMPD_target_parallel_for_simd:
Kelvin Li986330c2016-07-20 22:57:10 +00002006 case OMPD_target_simd:
Kelvin Li02532872016-08-05 14:37:37 +00002007 case OMPD_teams_distribute:
Kelvin Li4e325f72016-10-25 12:50:55 +00002008 case OMPD_teams_distribute_simd:
Kelvin Li579e41c2016-11-30 23:51:03 +00002009 case OMPD_teams_distribute_parallel_for_simd:
Kelvin Li7ade93f2016-12-09 03:24:30 +00002010 case OMPD_teams_distribute_parallel_for:
Kelvin Libf594a52016-12-17 05:48:59 +00002011 case OMPD_target_teams:
Kelvin Li83c451e2016-12-25 04:52:54 +00002012 case OMPD_target_teams_distribute:
Kelvin Li80e8f562016-12-29 22:16:30 +00002013 case OMPD_target_teams_distribute_parallel_for:
Kelvin Li1851df52017-01-03 05:23:48 +00002014 case OMPD_target_teams_distribute_parallel_for_simd:
Kelvin Lida681182017-01-10 18:08:18 +00002015 case OMPD_target_teams_distribute_simd:
Alexey Bataeva769e072013-03-22 06:34:35 +00002016 Diag(Tok, diag::err_omp_unexpected_directive)
Alexey Bataev96dae812018-02-16 18:36:44 +00002017 << 1 << getOpenMPDirectiveName(DKind);
Alexey Bataeva769e072013-03-22 06:34:35 +00002018 break;
2019 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002020 while (Tok.isNot(tok::annot_pragma_openmp_end))
2021 ConsumeAnyToken();
2022 ConsumeAnyToken();
David Blaikie0403cb12016-01-15 23:43:25 +00002023 return nullptr;
Alexey Bataeva769e072013-03-22 06:34:35 +00002024}
2025
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002026/// Parsing of declarative or executable OpenMP directives.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002027///
2028/// threadprivate-directive:
2029/// annot_pragma_openmp 'threadprivate' simple-variable-list
2030/// annot_pragma_openmp_end
2031///
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002032/// allocate-directive:
2033/// annot_pragma_openmp 'allocate' simple-variable-list
2034/// annot_pragma_openmp_end
2035///
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002036/// declare-reduction-directive:
2037/// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
2038/// <type> {',' <type>} ':' <expression> ')' ['initializer' '('
2039/// ('omp_priv' '=' <expression>|<function_call>) ')']
2040/// annot_pragma_openmp_end
2041///
Michael Kruse251e1482019-02-01 20:25:04 +00002042/// declare-mapper-directive:
2043/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2044/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
2045/// annot_pragma_openmp_end
2046///
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002047/// executable-directive:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002048/// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002049/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
cchen47d60942019-12-05 13:43:48 -05002050/// 'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
2051/// 'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
2052/// 'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
2053/// data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
2054/// 'master taskloop' | 'master taskloop simd' | 'parallel master
2055/// taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
2056/// enter data' | 'target exit data' | 'target parallel' | 'target
2057/// parallel for' | 'target update' | 'distribute parallel for' |
2058/// 'distribute paralle for simd' | 'distribute simd' | 'target parallel
2059/// for simd' | 'target simd' | 'teams distribute' | 'teams distribute
2060/// simd' | 'teams distribute parallel for simd' | 'teams distribute
2061/// parallel for' | 'target teams' | 'target teams distribute' | 'target
2062/// teams distribute parallel for' | 'target teams distribute parallel
2063/// for simd' | 'target teams distribute simd' {clause}
Alexey Bataev14a388f2019-10-25 10:27:13 -04002064/// annot_pragma_openmp_end
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002065///
Richard Smitha6e8d5e2019-02-15 00:27:53 +00002066StmtResult
2067Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002068 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
Alexey Bataev8035bb42019-12-13 16:05:30 -05002069 ParsingOpenMPDirectiveRAII DirScope(*this);
Alexey Bataevee6507d2013-11-18 08:17:37 +00002070 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002071 SmallVector<OMPClause *, 5> Clauses;
Johannes Doerfert419a5592020-03-30 19:58:40 -05002072 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2073 unsigned(OMPC_unknown) + 1>
2074 FirstClauses(unsigned(OMPC_unknown) + 1);
Momchil Velikov57c681f2017-08-10 15:43:06 +00002075 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
2076 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
Richard Smithaf3b3252017-05-18 19:21:48 +00002077 SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
Alexey Bataev61908f652018-04-23 19:53:05 +00002078 OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002079 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
Alexey Bataev758e55e2013-09-06 18:03:48 +00002080 // Name of critical directive.
2081 DeclarationNameInfo DirName;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002082 StmtResult Directive = StmtError();
Alexey Bataev68446b72014-07-18 07:47:19 +00002083 bool HasAssociatedStatement = true;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002084
2085 switch (DKind) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002086 case OMPD_threadprivate: {
Richard Smitha6e8d5e2019-02-15 00:27:53 +00002087 // FIXME: Should this be permitted in C++?
2088 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2089 ParsedStmtContext()) {
Alexey Bataevc4fad652016-01-13 11:18:54 +00002090 Diag(Tok, diag::err_omp_immediate_directive)
2091 << getOpenMPDirectiveName(DKind) << 0;
2092 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002093 ConsumeToken();
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002094 DeclDirectiveListParserHelper Helper(this, DKind);
2095 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2096 /*AllowScopeSpecifier=*/false)) {
Johannes Doerfert56d15532020-02-21 13:48:56 -06002097 skipUntilPragmaOpenMPEnd(DKind);
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002098 DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
2099 Loc, Helper.getIdentifiers());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002100 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2101 }
Alp Tokerd751fa72013-12-18 19:10:49 +00002102 SkipUntil(tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002103 break;
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002104 }
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002105 case OMPD_allocate: {
2106 // FIXME: Should this be permitted in C++?
2107 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2108 ParsedStmtContext()) {
2109 Diag(Tok, diag::err_omp_immediate_directive)
2110 << getOpenMPDirectiveName(DKind) << 0;
2111 }
2112 ConsumeToken();
2113 DeclDirectiveListParserHelper Helper(this, DKind);
2114 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2115 /*AllowScopeSpecifier=*/false)) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002116 SmallVector<OMPClause *, 1> Clauses;
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002117 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002118 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
Johannes Doerfert419a5592020-03-30 19:58:40 -05002119 unsigned(OMPC_unknown) + 1>
2120 FirstClauses(unsigned(OMPC_unknown) + 1);
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002121 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2122 OpenMPClauseKind CKind =
2123 Tok.isAnnotation() ? OMPC_unknown
2124 : getOpenMPClauseKind(PP.getSpelling(Tok));
2125 Actions.StartOpenMPClause(CKind);
Johannes Doerfert419a5592020-03-30 19:58:40 -05002126 OMPClause *Clause = ParseOpenMPClause(
2127 OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002128 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2129 StopBeforeMatch);
Johannes Doerfert419a5592020-03-30 19:58:40 -05002130 FirstClauses[unsigned(CKind)].setInt(true);
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002131 if (Clause != nullptr)
2132 Clauses.push_back(Clause);
2133 if (Tok.is(tok::annot_pragma_openmp_end)) {
2134 Actions.EndOpenMPClause();
2135 break;
2136 }
2137 // Skip ',' if any.
2138 if (Tok.is(tok::comma))
2139 ConsumeToken();
2140 Actions.EndOpenMPClause();
2141 }
Johannes Doerfert56d15532020-02-21 13:48:56 -06002142 skipUntilPragmaOpenMPEnd(DKind);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002143 }
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002144 DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2145 Loc, Helper.getIdentifiers(), Clauses);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002146 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2147 }
2148 SkipUntil(tok::annot_pragma_openmp_end);
2149 break;
2150 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002151 case OMPD_declare_reduction:
2152 ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +00002153 if (DeclGroupPtrTy Res =
2154 ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
Johannes Doerfert56d15532020-02-21 13:48:56 -06002155 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002156 ConsumeAnyToken();
2157 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
Alexey Bataev61908f652018-04-23 19:53:05 +00002158 } else {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002159 SkipUntil(tok::annot_pragma_openmp_end);
Alexey Bataev61908f652018-04-23 19:53:05 +00002160 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002161 break;
Michael Kruse251e1482019-02-01 20:25:04 +00002162 case OMPD_declare_mapper: {
2163 ConsumeToken();
2164 if (DeclGroupPtrTy Res =
2165 ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2166 // Skip the last annot_pragma_openmp_end.
2167 ConsumeAnnotationToken();
2168 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2169 } else {
2170 SkipUntil(tok::annot_pragma_openmp_end);
2171 }
2172 break;
2173 }
Alexey Bataev6125da92014-07-21 11:26:11 +00002174 case OMPD_flush:
Alexey Bataevc112e942020-02-28 09:52:15 -05002175 case OMPD_depobj:
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002176 case OMPD_scan:
Alexey Bataev68446b72014-07-18 07:47:19 +00002177 case OMPD_taskyield:
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002178 case OMPD_barrier:
Alexey Bataev2df347a2014-07-18 10:17:07 +00002179 case OMPD_taskwait:
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002180 case OMPD_cancellation_point:
Alexey Bataev80909872015-07-02 11:25:17 +00002181 case OMPD_cancel:
Samuel Antaodf67fc42016-01-19 19:15:56 +00002182 case OMPD_target_enter_data:
Samuel Antao72590762016-01-19 20:04:50 +00002183 case OMPD_target_exit_data:
Samuel Antao686c70c2016-05-26 17:30:50 +00002184 case OMPD_target_update:
Richard Smitha6e8d5e2019-02-15 00:27:53 +00002185 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2186 ParsedStmtContext()) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002187 Diag(Tok, diag::err_omp_immediate_directive)
Alexey Bataeveb482352015-12-18 05:05:56 +00002188 << getOpenMPDirectiveName(DKind) << 0;
Alexey Bataev68446b72014-07-18 07:47:19 +00002189 }
2190 HasAssociatedStatement = false;
Alexey Bataev6125da92014-07-21 11:26:11 +00002191 // Fall through for further analysis.
Galina Kistanova474f2ce2017-06-01 21:26:38 +00002192 LLVM_FALLTHROUGH;
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002193 case OMPD_parallel:
Alexey Bataevf29276e2014-06-18 04:14:57 +00002194 case OMPD_simd:
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002195 case OMPD_for:
Alexander Musmanf82886e2014-09-18 05:12:34 +00002196 case OMPD_for_simd:
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002197 case OMPD_sections:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002198 case OMPD_single:
Alexey Bataev4acb8592014-07-07 13:01:15 +00002199 case OMPD_section:
Alexander Musman80c22892014-07-17 08:54:58 +00002200 case OMPD_master:
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002201 case OMPD_critical:
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002202 case OMPD_parallel_for:
Alexander Musmane4e893b2014-09-23 09:33:00 +00002203 case OMPD_parallel_for_simd:
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002204 case OMPD_parallel_sections:
cchen47d60942019-12-05 13:43:48 -05002205 case OMPD_parallel_master:
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002206 case OMPD_task:
Alexey Bataev0162e452014-07-22 10:10:35 +00002207 case OMPD_ordered:
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002208 case OMPD_atomic:
Alexey Bataev13314bf2014-10-09 04:18:56 +00002209 case OMPD_target:
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002210 case OMPD_teams:
Michael Wong65f367f2015-07-21 13:44:28 +00002211 case OMPD_taskgroup:
Alexey Bataev49f6e782015-12-01 04:18:41 +00002212 case OMPD_target_data:
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002213 case OMPD_target_parallel:
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002214 case OMPD_target_parallel_for:
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002215 case OMPD_taskloop:
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002216 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +00002217 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002218 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002219 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -04002220 case OMPD_parallel_master_taskloop_simd:
Carlo Bertolli9925f152016-06-27 14:55:37 +00002221 case OMPD_distribute:
Kelvin Li4a39add2016-07-05 05:00:15 +00002222 case OMPD_distribute_parallel_for:
Kelvin Li787f3fc2016-07-06 04:45:38 +00002223 case OMPD_distribute_parallel_for_simd:
Kelvin Lia579b912016-07-14 02:54:56 +00002224 case OMPD_distribute_simd:
Kelvin Li986330c2016-07-20 22:57:10 +00002225 case OMPD_target_parallel_for_simd:
Kelvin Li02532872016-08-05 14:37:37 +00002226 case OMPD_target_simd:
Kelvin Li4e325f72016-10-25 12:50:55 +00002227 case OMPD_teams_distribute:
Kelvin Li579e41c2016-11-30 23:51:03 +00002228 case OMPD_teams_distribute_simd:
Kelvin Li7ade93f2016-12-09 03:24:30 +00002229 case OMPD_teams_distribute_parallel_for_simd:
Kelvin Libf594a52016-12-17 05:48:59 +00002230 case OMPD_teams_distribute_parallel_for:
Kelvin Li83c451e2016-12-25 04:52:54 +00002231 case OMPD_target_teams:
Kelvin Li80e8f562016-12-29 22:16:30 +00002232 case OMPD_target_teams_distribute:
Kelvin Li1851df52017-01-03 05:23:48 +00002233 case OMPD_target_teams_distribute_parallel_for:
Kelvin Lida681182017-01-10 18:08:18 +00002234 case OMPD_target_teams_distribute_parallel_for_simd:
2235 case OMPD_target_teams_distribute_simd: {
Alexey Bataevc112e942020-02-28 09:52:15 -05002236 // Special processing for flush and depobj clauses.
2237 Token ImplicitTok;
2238 bool ImplicitClauseAllowed = false;
2239 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2240 ImplicitTok = Tok;
2241 ImplicitClauseAllowed = true;
2242 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002243 ConsumeToken();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002244 // Parse directive name of the 'critical' directive if any.
2245 if (DKind == OMPD_critical) {
2246 BalancedDelimiterTracker T(*this, tok::l_paren,
2247 tok::annot_pragma_openmp_end);
2248 if (!T.consumeOpen()) {
2249 if (Tok.isAnyIdentifier()) {
2250 DirName =
2251 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2252 ConsumeAnyToken();
2253 } else {
2254 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2255 }
2256 T.consumeClose();
2257 }
Alexey Bataev80909872015-07-02 11:25:17 +00002258 } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
Alexey Bataev61908f652018-04-23 19:53:05 +00002259 CancelRegion = parseOpenMPDirectiveKind(*this);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002260 if (Tok.isNot(tok::annot_pragma_openmp_end))
2261 ConsumeToken();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002262 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002263
Alexey Bataevf29276e2014-06-18 04:14:57 +00002264 if (isOpenMPLoopDirective(DKind))
2265 ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2266 if (isOpenMPSimdDirective(DKind))
2267 ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2268 ParseScope OMPDirectiveScope(this, ScopeFlags);
Alexey Bataevbae9a792014-06-27 10:37:06 +00002269 Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002270
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002271 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataevc112e942020-02-28 09:52:15 -05002272 bool HasImplicitClause = false;
2273 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2274 HasImplicitClause = true;
Alexey Bataevea9166b2020-02-06 16:30:23 -05002275 // Push copy of the current token back to stream to properly parse
Alexey Bataevc112e942020-02-28 09:52:15 -05002276 // pseudo-clause OMPFlushClause or OMPDepobjClause.
Alexey Bataevea9166b2020-02-06 16:30:23 -05002277 PP.EnterToken(Tok, /*IsReinject*/ true);
Alexey Bataevc112e942020-02-28 09:52:15 -05002278 PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
Alexey Bataevea9166b2020-02-06 16:30:23 -05002279 ConsumeAnyToken();
2280 }
Alexey Bataevc112e942020-02-28 09:52:15 -05002281 OpenMPClauseKind CKind = Tok.isAnnotation()
2282 ? OMPC_unknown
2283 : getOpenMPClauseKind(PP.getSpelling(Tok));
2284 if (HasImplicitClause) {
2285 assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2286 if (DKind == OMPD_flush) {
2287 CKind = OMPC_flush;
2288 } else {
2289 assert(DKind == OMPD_depobj &&
2290 "Expected flush or depobj directives.");
2291 CKind = OMPC_depobj;
2292 }
2293 }
2294 // No more implicit clauses allowed.
2295 ImplicitClauseAllowed = false;
Alexey Bataevaac108a2015-06-23 04:51:00 +00002296 Actions.StartOpenMPClause(CKind);
Alexey Bataevc112e942020-02-28 09:52:15 -05002297 HasImplicitClause = false;
Johannes Doerfert419a5592020-03-30 19:58:40 -05002298 OMPClause *Clause = ParseOpenMPClause(
2299 DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
2300 FirstClauses[unsigned(CKind)].setInt(true);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002301 if (Clause) {
Johannes Doerfert419a5592020-03-30 19:58:40 -05002302 FirstClauses[unsigned(CKind)].setPointer(Clause);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002303 Clauses.push_back(Clause);
2304 }
2305
2306 // Skip ',' if any.
2307 if (Tok.is(tok::comma))
2308 ConsumeToken();
Alexey Bataevaac108a2015-06-23 04:51:00 +00002309 Actions.EndOpenMPClause();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002310 }
2311 // End location of the directive.
2312 EndLoc = Tok.getLocation();
2313 // Consume final annot_pragma_openmp_end.
Richard Smithaf3b3252017-05-18 19:21:48 +00002314 ConsumeAnnotationToken();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002315
Alexey Bataeveb482352015-12-18 05:05:56 +00002316 // OpenMP [2.13.8, ordered Construct, Syntax]
2317 // If the depend clause is specified, the ordered construct is a stand-alone
2318 // directive.
Johannes Doerfert419a5592020-03-30 19:58:40 -05002319 if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) {
Richard Smitha6e8d5e2019-02-15 00:27:53 +00002320 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2321 ParsedStmtContext()) {
Alexey Bataeveb482352015-12-18 05:05:56 +00002322 Diag(Loc, diag::err_omp_immediate_directive)
2323 << getOpenMPDirectiveName(DKind) << 1
2324 << getOpenMPClauseName(OMPC_depend);
2325 }
2326 HasAssociatedStatement = false;
2327 }
2328
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002329 StmtResult AssociatedStmt;
Alexey Bataev68446b72014-07-18 07:47:19 +00002330 if (HasAssociatedStatement) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002331 // The body is a block scope like in Lambdas and Blocks.
Alexey Bataevbae9a792014-06-27 10:37:06 +00002332 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
Richard Smith6eb9b9e2018-02-03 00:44:57 +00002333 // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2334 // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2335 // should have at least one compound statement scope within it.
2336 AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00002337 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
Alexey Bataev7828b252017-11-21 17:08:48 +00002338 } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2339 DKind == OMPD_target_exit_data) {
Alexey Bataev7828b252017-11-21 17:08:48 +00002340 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
Richard Smith6eb9b9e2018-02-03 00:44:57 +00002341 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2342 Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2343 /*isStmtExpr=*/false));
Alexey Bataev7828b252017-11-21 17:08:48 +00002344 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002345 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002346 Directive = Actions.ActOnOpenMPExecutableDirective(
2347 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2348 EndLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002349
2350 // Exit scope.
Alexey Bataev758e55e2013-09-06 18:03:48 +00002351 Actions.EndOpenMPDSABlock(Directive.get());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002352 OMPDirectiveScope.Exit();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002353 break;
Alexey Bataeva55ed262014-05-28 06:15:33 +00002354 }
Alexey Bataev587e1de2016-03-30 10:43:55 +00002355 case OMPD_declare_simd:
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00002356 case OMPD_declare_target:
2357 case OMPD_end_declare_target:
Kelvin Li1408f912018-09-26 04:28:39 +00002358 case OMPD_requires:
Johannes Doerfert095cecb2020-02-20 19:50:47 -06002359 case OMPD_begin_declare_variant:
2360 case OMPD_end_declare_variant:
Alexey Bataevd158cf62019-09-13 20:18:17 +00002361 case OMPD_declare_variant:
Alexey Bataev587e1de2016-03-30 10:43:55 +00002362 Diag(Tok, diag::err_omp_unexpected_directive)
Alexey Bataev96dae812018-02-16 18:36:44 +00002363 << 1 << getOpenMPDirectiveName(DKind);
Alexey Bataev587e1de2016-03-30 10:43:55 +00002364 SkipUntil(tok::annot_pragma_openmp_end);
2365 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002366 case OMPD_unknown:
2367 Diag(Tok, diag::err_omp_unknown_directive);
Alp Tokerd751fa72013-12-18 19:10:49 +00002368 SkipUntil(tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002369 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002370 }
2371 return Directive;
2372}
2373
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002374// Parses simple list:
2375// simple-variable-list:
2376// '(' id-expression {, id-expression} ')'
2377//
2378bool Parser::ParseOpenMPSimpleVarList(
2379 OpenMPDirectiveKind Kind,
2380 const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
2381 Callback,
2382 bool AllowScopeSpecifier) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002383 // Parse '('.
Alp Tokerd751fa72013-12-18 19:10:49 +00002384 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002385 if (T.expectAndConsume(diag::err_expected_lparen_after,
Johannes Doerferteb3e81f2019-11-04 22:00:49 -06002386 getOpenMPDirectiveName(Kind).data()))
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002387 return true;
2388 bool IsCorrect = true;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002389 bool NoIdentIsFound = true;
Alexey Bataeva769e072013-03-22 06:34:35 +00002390
2391 // Read tokens while ')' or annot_pragma_openmp_end is not found.
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002392 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002393 CXXScopeSpec SS;
Alexey Bataeva769e072013-03-22 06:34:35 +00002394 UnqualifiedId Name;
2395 // Read var name.
2396 Token PrevTok = Tok;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002397 NoIdentIsFound = false;
Alexey Bataeva769e072013-03-22 06:34:35 +00002398
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002399 if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
Haojian Wu0dd0b102020-03-19 09:12:29 +01002400 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2401 /*ObjectHadErrors=*/false, false)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002402 IsCorrect = false;
2403 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +00002404 StopBeforeMatch);
Haojian Wu0dd0b102020-03-19 09:12:29 +01002405 } else if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
2406 /*ObjectHadErrors=*/false, false, false,
2407 false, false, nullptr, Name)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002408 IsCorrect = false;
2409 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +00002410 StopBeforeMatch);
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002411 } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2412 Tok.isNot(tok::annot_pragma_openmp_end)) {
2413 IsCorrect = false;
2414 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +00002415 StopBeforeMatch);
Alp Tokerec543272013-12-24 09:48:30 +00002416 Diag(PrevTok.getLocation(), diag::err_expected)
2417 << tok::identifier
2418 << SourceRange(PrevTok.getLocation(), PrevTokLocation);
Alexey Bataeva769e072013-03-22 06:34:35 +00002419 } else {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002420 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
Alexey Bataeva769e072013-03-22 06:34:35 +00002421 }
2422 // Consume ','.
2423 if (Tok.is(tok::comma)) {
2424 ConsumeToken();
2425 }
Alexey Bataeva769e072013-03-22 06:34:35 +00002426 }
2427
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002428 if (NoIdentIsFound) {
Alp Tokerec543272013-12-24 09:48:30 +00002429 Diag(Tok, diag::err_expected) << tok::identifier;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002430 IsCorrect = false;
2431 }
2432
2433 // Parse ')'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002434 IsCorrect = !T.consumeClose() && IsCorrect;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002435
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002436 return !IsCorrect;
Alexey Bataeva769e072013-03-22 06:34:35 +00002437}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002438
Alexey Bataevb5be1c52020-04-21 13:21:00 -04002439OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
2440 SourceLocation Loc = Tok.getLocation();
2441 ConsumeAnyToken();
2442
2443 // Parse '('.
2444 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2445 if (T.expectAndConsume(diag::err_expected_lparen_after, "uses_allocator"))
2446 return nullptr;
2447 SmallVector<Sema::UsesAllocatorsData, 4> Data;
2448 do {
2449 ExprResult Allocator = ParseCXXIdExpression();
2450 if (Allocator.isInvalid()) {
2451 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2452 StopBeforeMatch);
2453 break;
2454 }
2455 Sema::UsesAllocatorsData &D = Data.emplace_back();
2456 D.Allocator = Allocator.get();
2457 if (Tok.is(tok::l_paren)) {
2458 BalancedDelimiterTracker T(*this, tok::l_paren,
2459 tok::annot_pragma_openmp_end);
2460 T.consumeOpen();
2461 ExprResult AllocatorTraits = ParseCXXIdExpression();
2462 T.consumeClose();
2463 if (AllocatorTraits.isInvalid()) {
2464 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2465 StopBeforeMatch);
2466 break;
2467 }
2468 D.AllocatorTraits = AllocatorTraits.get();
2469 D.LParenLoc = T.getOpenLocation();
2470 D.RParenLoc = T.getCloseLocation();
2471 }
2472 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
2473 Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;
2474 // Parse ','
2475 if (Tok.is(tok::comma))
2476 ConsumeAnyToken();
2477 } while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end));
2478 T.consumeClose();
2479 return Actions.ActOnOpenMPUsesAllocatorClause(Loc, T.getOpenLocation(),
2480 T.getCloseLocation(), Data);
2481}
2482
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002483/// Parsing of OpenMP clauses.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002484///
2485/// clause:
Alexey Bataev3778b602014-07-17 07:32:53 +00002486/// if-clause | final-clause | num_threads-clause | safelen-clause |
2487/// default-clause | private-clause | firstprivate-clause | shared-clause
2488/// | linear-clause | aligned-clause | collapse-clause |
2489/// lastprivate-clause | reduction-clause | proc_bind-clause |
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002490/// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
Alexey Bataev67a4f222014-07-23 10:25:33 +00002491/// mergeable-clause | flush-clause | read-clause | write-clause |
Alexey Bataev66b15b52015-08-21 11:14:16 +00002492/// update-clause | capture-clause | seq_cst-clause | device-clause |
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002493/// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002494/// thread_limit-clause | priority-clause | grainsize-clause |
Samuel Antaoec172c62016-05-26 17:49:04 +00002495/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
Alexey Bataevfa312f32017-07-21 18:48:21 +00002496/// from-clause | is_device_ptr-clause | task_reduction-clause |
Alexey Bataevea9166b2020-02-06 16:30:23 -05002497/// in_reduction-clause | allocator-clause | allocate-clause |
Alexey Bataevc112e942020-02-28 09:52:15 -05002498/// acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
Alexey Bataev63828a32020-03-23 10:41:08 -04002499/// depobj-clause | destroy-clause | detach-clause | inclusive-clause |
Alexey Bataevb5be1c52020-04-21 13:21:00 -04002500/// exclusive-clause | uses_allocators-clause
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002501///
2502OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
2503 OpenMPClauseKind CKind, bool FirstClause) {
Craig Topper161e4db2014-05-21 06:02:52 +00002504 OMPClause *Clause = nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002505 bool ErrorFound = false;
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002506 bool WrongDirective = false;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002507 // Check if clause is allowed for the given directive.
Alexey Bataevd08c0562019-11-19 12:07:54 -05002508 if (CKind != OMPC_unknown &&
2509 !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
Alexey Bataeva55ed262014-05-28 06:15:33 +00002510 Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
2511 << getOpenMPDirectiveName(DKind);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002512 ErrorFound = true;
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002513 WrongDirective = true;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002514 }
2515
2516 switch (CKind) {
Alexey Bataev3778b602014-07-17 07:32:53 +00002517 case OMPC_final:
Alexey Bataev568a8332014-03-06 06:15:19 +00002518 case OMPC_num_threads:
Alexey Bataev62c87d22014-03-21 04:51:18 +00002519 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +00002520 case OMPC_simdlen:
Alexander Musman8bd31e62014-05-27 15:12:19 +00002521 case OMPC_collapse:
Alexey Bataev10e775f2015-07-30 11:36:16 +00002522 case OMPC_ordered:
Kelvin Li099bb8c2015-11-24 20:50:12 +00002523 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002524 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +00002525 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002526 case OMPC_grainsize:
Alexey Bataev382967a2015-12-08 12:06:20 +00002527 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +00002528 case OMPC_hint:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002529 case OMPC_allocator:
Alexey Bataevc112e942020-02-28 09:52:15 -05002530 case OMPC_depobj:
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002531 case OMPC_detach:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002532 // OpenMP [2.5, Restrictions]
Alexey Bataev568a8332014-03-06 06:15:19 +00002533 // At most one num_threads clause can appear on the directive.
Alexey Bataev62c87d22014-03-21 04:51:18 +00002534 // OpenMP [2.8.1, simd construct, Restrictions]
Alexander Musman8bd31e62014-05-27 15:12:19 +00002535 // Only one safelen clause can appear on a simd directive.
Alexey Bataev66b15b52015-08-21 11:14:16 +00002536 // Only one simdlen clause can appear on a simd directive.
Alexander Musman8bd31e62014-05-27 15:12:19 +00002537 // Only one collapse clause can appear on a simd directive.
Alexey Bataev3778b602014-07-17 07:32:53 +00002538 // OpenMP [2.11.1, task Construct, Restrictions]
2539 // At most one if clause can appear on the directive.
2540 // At most one final clause can appear on the directive.
Kelvin Li099bb8c2015-11-24 20:50:12 +00002541 // OpenMP [teams Construct, Restrictions]
2542 // At most one num_teams clause can appear on the directive.
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002543 // At most one thread_limit clause can appear on the directive.
Alexey Bataeva0569352015-12-01 10:17:31 +00002544 // OpenMP [2.9.1, task Construct, Restrictions]
2545 // At most one priority clause can appear on the directive.
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002546 // OpenMP [2.9.2, taskloop Construct, Restrictions]
2547 // At most one grainsize clause can appear on the directive.
Alexey Bataev382967a2015-12-08 12:06:20 +00002548 // OpenMP [2.9.2, taskloop Construct, Restrictions]
2549 // At most one num_tasks clause can appear on the directive.
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002550 // OpenMP [2.11.3, allocate Directive, Restrictions]
2551 // At most one allocator clause can appear on the directive.
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002552 // OpenMP 5.0, 2.10.1 task Construct, Restrictions.
2553 // At most one detach clause can appear on the directive.
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002554 if (!FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002555 Diag(Tok, diag::err_omp_more_one_clause)
2556 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +00002557 ErrorFound = true;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002558 }
2559
Alexey Bataev10e775f2015-07-30 11:36:16 +00002560 if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002561 Clause = ParseOpenMPClause(CKind, WrongDirective);
Alexey Bataev10e775f2015-07-30 11:36:16 +00002562 else
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002563 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002564 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002565 case OMPC_default:
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002566 case OMPC_proc_bind:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002567 case OMPC_atomic_default_mem_order:
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002568 case OMPC_order:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002569 // OpenMP [2.14.3.1, Restrictions]
2570 // Only a single default clause may be specified on a parallel, task or
2571 // teams directive.
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002572 // OpenMP [2.5, parallel Construct, Restrictions]
2573 // At most one proc_bind clause can appear on the directive.
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002574 // OpenMP [5.0, Requires directive, Restrictions]
2575 // At most one atomic_default_mem_order clause can appear
2576 // on the directive
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002577 if (!FirstClause && CKind != OMPC_order) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002578 Diag(Tok, diag::err_omp_more_one_clause)
2579 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +00002580 ErrorFound = true;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002581 }
2582
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002583 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002584 break;
Alexey Bataev2f8894a2020-03-18 15:01:15 -04002585 case OMPC_device:
Alexey Bataev56dafe82014-06-20 07:16:17 +00002586 case OMPC_schedule:
Carlo Bertollib4adf552016-01-15 18:50:31 +00002587 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002588 case OMPC_defaultmap:
Alexey Bataev56dafe82014-06-20 07:16:17 +00002589 // OpenMP [2.7.1, Restrictions, p. 3]
2590 // Only one schedule clause can appear on a loop directive.
cchene06f3e02019-11-15 13:02:06 -05002591 // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002592 // At most one defaultmap clause can appear on the directive.
Alexey Bataev2f8894a2020-03-18 15:01:15 -04002593 // OpenMP 5.0 [2.12.5, target construct, Restrictions]
2594 // At most one device clause can appear on the directive.
cchene06f3e02019-11-15 13:02:06 -05002595 if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
2596 !FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002597 Diag(Tok, diag::err_omp_more_one_clause)
2598 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +00002599 ErrorFound = true;
Alexey Bataev56dafe82014-06-20 07:16:17 +00002600 }
Galina Kistanova474f2ce2017-06-01 21:26:38 +00002601 LLVM_FALLTHROUGH;
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002602 case OMPC_if:
Alexey Bataev2f8894a2020-03-18 15:01:15 -04002603 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002604 break;
Alexey Bataev236070f2014-06-20 11:19:47 +00002605 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002606 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002607 case OMPC_mergeable:
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002608 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +00002609 case OMPC_write:
Alexey Bataev459dec02014-07-24 06:46:57 +00002610 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002611 case OMPC_seq_cst:
Alexey Bataevea9166b2020-02-06 16:30:23 -05002612 case OMPC_acq_rel:
Alexey Bataev04a830f2020-02-10 14:30:39 -05002613 case OMPC_acquire:
Alexey Bataev95598342020-02-10 15:49:05 -05002614 case OMPC_release:
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002615 case OMPC_relaxed:
Alexey Bataev346265e2015-09-25 10:37:12 +00002616 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002617 case OMPC_simd:
Alexey Bataevb825de12015-12-07 10:51:44 +00002618 case OMPC_nogroup:
Kelvin Li1408f912018-09-26 04:28:39 +00002619 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +00002620 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002621 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002622 case OMPC_dynamic_allocators:
Alexey Bataev375437a2020-03-02 14:21:20 -05002623 case OMPC_destroy:
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002624 // OpenMP [2.7.1, Restrictions, p. 9]
2625 // Only one ordered clause can appear on a loop directive.
Alexey Bataev236070f2014-06-20 11:19:47 +00002626 // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
2627 // Only one nowait clause can appear on a for directive.
Kelvin Li1408f912018-09-26 04:28:39 +00002628 // OpenMP [5.0, Requires directive, Restrictions]
2629 // Each of the requires clauses can appear at most once on the directive.
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002630 if (!FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002631 Diag(Tok, diag::err_omp_more_one_clause)
2632 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +00002633 ErrorFound = true;
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002634 }
2635
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002636 Clause = ParseOpenMPClause(CKind, WrongDirective);
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002637 break;
Alexey Bataev82f7c202020-03-03 13:22:35 -05002638 case OMPC_update:
2639 if (!FirstClause) {
2640 Diag(Tok, diag::err_omp_more_one_clause)
2641 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2642 ErrorFound = true;
2643 }
2644
2645 Clause = (DKind == OMPD_depobj)
2646 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
2647 : ParseOpenMPClause(CKind, WrongDirective);
2648 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002649 case OMPC_private:
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002650 case OMPC_firstprivate:
Alexander Musman1bb328c2014-06-04 13:06:39 +00002651 case OMPC_lastprivate:
Alexey Bataev758e55e2013-09-06 18:03:48 +00002652 case OMPC_shared:
Alexey Bataevc5e02582014-06-16 07:08:35 +00002653 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +00002654 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +00002655 case OMPC_in_reduction:
Alexander Musman8dba6642014-04-22 13:09:42 +00002656 case OMPC_linear:
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002657 case OMPC_aligned:
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002658 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +00002659 case OMPC_copyprivate:
Alexey Bataev6125da92014-07-21 11:26:11 +00002660 case OMPC_flush:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002661 case OMPC_depend:
Kelvin Li0bff7af2015-11-23 05:32:03 +00002662 case OMPC_map:
Samuel Antao661c0902016-05-26 17:39:58 +00002663 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +00002664 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +00002665 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +00002666 case OMPC_is_device_ptr:
Alexey Bataeve04483e2019-03-27 14:14:31 +00002667 case OMPC_allocate:
Alexey Bataevb6e70842019-12-16 15:54:17 -05002668 case OMPC_nontemporal:
Alexey Bataev06dea732020-03-20 09:41:22 -04002669 case OMPC_inclusive:
Alexey Bataev63828a32020-03-23 10:41:08 -04002670 case OMPC_exclusive:
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002671 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002672 break;
Alexey Bataevb5be1c52020-04-21 13:21:00 -04002673 case OMPC_uses_allocators:
2674 Clause = ParseOpenMPUsesAllocatorClause(DKind);
2675 break;
Alexey Bataev729e2422019-08-23 16:11:14 +00002676 case OMPC_device_type:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002677 case OMPC_unknown:
Johannes Doerfert56d15532020-02-21 13:48:56 -06002678 skipUntilPragmaOpenMPEnd(DKind);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002679 break;
2680 case OMPC_threadprivate:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002681 case OMPC_uniform:
Alexey Bataevdba792c2019-09-23 18:13:31 +00002682 case OMPC_match:
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002683 if (!WrongDirective)
2684 Diag(Tok, diag::err_omp_unexpected_clause)
2685 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
Alp Tokerd751fa72013-12-18 19:10:49 +00002686 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002687 break;
2688 }
Craig Topper161e4db2014-05-21 06:02:52 +00002689 return ErrorFound ? nullptr : Clause;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002690}
2691
Alexey Bataev2af33e32016-04-07 12:45:37 +00002692/// Parses simple expression in parens for single-expression clauses of OpenMP
2693/// constructs.
2694/// \param RLoc Returned location of right paren.
2695ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
Alexey Bataevd158cf62019-09-13 20:18:17 +00002696 SourceLocation &RLoc,
2697 bool IsAddressOfOperand) {
Alexey Bataev2af33e32016-04-07 12:45:37 +00002698 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2699 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
2700 return ExprError();
2701
2702 SourceLocation ELoc = Tok.getLocation();
Saar Razb65b1f32020-01-09 15:07:51 +02002703 ExprResult LHS(ParseCastExpression(AnyCastExpr, IsAddressOfOperand,
2704 NotTypeCast));
Alexey Bataev2af33e32016-04-07 12:45:37 +00002705 ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00002706 Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataev2af33e32016-04-07 12:45:37 +00002707
2708 // Parse ')'.
Alexey Bataevdbc72c92018-07-06 19:35:42 +00002709 RLoc = Tok.getLocation();
2710 if (!T.consumeClose())
2711 RLoc = T.getCloseLocation();
Alexey Bataev2af33e32016-04-07 12:45:37 +00002712
Alexey Bataev2af33e32016-04-07 12:45:37 +00002713 return Val;
2714}
2715
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002716/// Parsing of OpenMP clauses with single expressions like 'final',
Alexey Bataeva0569352015-12-01 10:17:31 +00002717/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002718/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
2719/// 'detach'.
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002720///
Alexey Bataev3778b602014-07-17 07:32:53 +00002721/// final-clause:
2722/// 'final' '(' expression ')'
2723///
Alexey Bataev62c87d22014-03-21 04:51:18 +00002724/// num_threads-clause:
2725/// 'num_threads' '(' expression ')'
2726///
2727/// safelen-clause:
2728/// 'safelen' '(' expression ')'
2729///
Alexey Bataev66b15b52015-08-21 11:14:16 +00002730/// simdlen-clause:
2731/// 'simdlen' '(' expression ')'
2732///
Alexander Musman8bd31e62014-05-27 15:12:19 +00002733/// collapse-clause:
2734/// 'collapse' '(' expression ')'
2735///
Alexey Bataeva0569352015-12-01 10:17:31 +00002736/// priority-clause:
2737/// 'priority' '(' expression ')'
2738///
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002739/// grainsize-clause:
2740/// 'grainsize' '(' expression ')'
2741///
Alexey Bataev382967a2015-12-08 12:06:20 +00002742/// num_tasks-clause:
2743/// 'num_tasks' '(' expression ')'
2744///
Alexey Bataev28c75412015-12-15 08:19:24 +00002745/// hint-clause:
2746/// 'hint' '(' expression ')'
2747///
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002748/// allocator-clause:
2749/// 'allocator' '(' expression ')'
2750///
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002751/// detach-clause:
2752/// 'detach' '(' event-handler-expression ')'
2753///
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002754OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
2755 bool ParseOnly) {
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002756 SourceLocation Loc = ConsumeToken();
Alexey Bataev2af33e32016-04-07 12:45:37 +00002757 SourceLocation LLoc = Tok.getLocation();
2758 SourceLocation RLoc;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002759
Alexey Bataev2af33e32016-04-07 12:45:37 +00002760 ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002761
2762 if (Val.isInvalid())
Craig Topper161e4db2014-05-21 06:02:52 +00002763 return nullptr;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002764
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002765 if (ParseOnly)
2766 return nullptr;
Alexey Bataev2af33e32016-04-07 12:45:37 +00002767 return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002768}
2769
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002770/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002771///
2772/// default-clause:
Alexey Bataev82f7c202020-03-03 13:22:35 -05002773/// 'default' '(' 'none' | 'shared' ')'
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002774///
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002775/// proc_bind-clause:
Alexey Bataev82f7c202020-03-03 13:22:35 -05002776/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')'
2777///
2778/// update-clause:
2779/// 'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002780///
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002781OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
2782 bool ParseOnly) {
Alexey Bataev729e2422019-08-23 16:11:14 +00002783 llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
2784 if (!Val || ParseOnly)
Craig Topper161e4db2014-05-21 06:02:52 +00002785 return nullptr;
Alexey Bataev729e2422019-08-23 16:11:14 +00002786 return Actions.ActOnOpenMPSimpleClause(
2787 Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
2788 Val.getValue().Loc, Val.getValue().RLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002789}
2790
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002791/// Parsing of OpenMP clauses like 'ordered'.
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002792///
2793/// ordered-clause:
2794/// 'ordered'
2795///
Alexey Bataev236070f2014-06-20 11:19:47 +00002796/// nowait-clause:
2797/// 'nowait'
2798///
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002799/// untied-clause:
2800/// 'untied'
2801///
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002802/// mergeable-clause:
2803/// 'mergeable'
2804///
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002805/// read-clause:
2806/// 'read'
2807///
Alexey Bataev346265e2015-09-25 10:37:12 +00002808/// threads-clause:
2809/// 'threads'
2810///
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002811/// simd-clause:
2812/// 'simd'
2813///
Alexey Bataevb825de12015-12-07 10:51:44 +00002814/// nogroup-clause:
2815/// 'nogroup'
2816///
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002817OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002818 SourceLocation Loc = Tok.getLocation();
2819 ConsumeAnyToken();
2820
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002821 if (ParseOnly)
2822 return nullptr;
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002823 return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
2824}
2825
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002826/// Parsing of OpenMP clauses with single expressions and some additional
Alexey Bataev56dafe82014-06-20 07:16:17 +00002827/// argument like 'schedule' or 'dist_schedule'.
2828///
2829/// schedule-clause:
Alexey Bataev6402bca2015-12-28 07:25:51 +00002830/// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
2831/// ')'
Alexey Bataev56dafe82014-06-20 07:16:17 +00002832///
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002833/// if-clause:
2834/// 'if' '(' [ directive-name-modifier ':' ] expression ')'
2835///
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002836/// defaultmap:
Alexey Bataevec275272020-04-08 15:19:54 -04002837/// 'defaultmap' '(' modifier [ ':' kind ] ')'
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002838///
Alexey Bataev2f8894a2020-03-18 15:01:15 -04002839/// device-clause:
2840/// 'device' '(' [ device-modifier ':' ] expression ')'
2841///
2842OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
2843 OpenMPClauseKind Kind,
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002844 bool ParseOnly) {
Alexey Bataev56dafe82014-06-20 07:16:17 +00002845 SourceLocation Loc = ConsumeToken();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002846 SourceLocation DelimLoc;
Alexey Bataev56dafe82014-06-20 07:16:17 +00002847 // Parse '('.
2848 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2849 if (T.expectAndConsume(diag::err_expected_lparen_after,
Johannes Doerfert419a5592020-03-30 19:58:40 -05002850 getOpenMPClauseName(Kind).data()))
Alexey Bataev56dafe82014-06-20 07:16:17 +00002851 return nullptr;
2852
2853 ExprResult Val;
Alexey Bataev6402bca2015-12-28 07:25:51 +00002854 SmallVector<unsigned, 4> Arg;
2855 SmallVector<SourceLocation, 4> KLoc;
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002856 if (Kind == OMPC_schedule) {
Alexey Bataev6402bca2015-12-28 07:25:51 +00002857 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
2858 Arg.resize(NumberOfElements);
2859 KLoc.resize(NumberOfElements);
2860 Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
2861 Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
2862 Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
Alexey Bataev61908f652018-04-23 19:53:05 +00002863 unsigned KindModifier = getOpenMPSimpleClauseType(
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002864 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
Alexey Bataev6402bca2015-12-28 07:25:51 +00002865 if (KindModifier > OMPC_SCHEDULE_unknown) {
2866 // Parse 'modifier'
2867 Arg[Modifier1] = KindModifier;
2868 KLoc[Modifier1] = Tok.getLocation();
2869 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2870 Tok.isNot(tok::annot_pragma_openmp_end))
2871 ConsumeAnyToken();
2872 if (Tok.is(tok::comma)) {
2873 // Parse ',' 'modifier'
2874 ConsumeAnyToken();
2875 KindModifier = getOpenMPSimpleClauseType(
2876 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2877 Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
2878 ? KindModifier
Aaron Ballmanad8a1042015-12-28 15:52:46 +00002879 : (unsigned)OMPC_SCHEDULE_unknown;
Alexey Bataev6402bca2015-12-28 07:25:51 +00002880 KLoc[Modifier2] = Tok.getLocation();
2881 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2882 Tok.isNot(tok::annot_pragma_openmp_end))
2883 ConsumeAnyToken();
2884 }
2885 // Parse ':'
2886 if (Tok.is(tok::colon))
2887 ConsumeAnyToken();
2888 else
2889 Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
2890 KindModifier = getOpenMPSimpleClauseType(
2891 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2892 }
2893 Arg[ScheduleKind] = KindModifier;
2894 KLoc[ScheduleKind] = Tok.getLocation();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002895 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2896 Tok.isNot(tok::annot_pragma_openmp_end))
2897 ConsumeAnyToken();
Alexey Bataev6402bca2015-12-28 07:25:51 +00002898 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
2899 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
2900 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002901 Tok.is(tok::comma))
2902 DelimLoc = ConsumeAnyToken();
Carlo Bertollib4adf552016-01-15 18:50:31 +00002903 } else if (Kind == OMPC_dist_schedule) {
2904 Arg.push_back(getOpenMPSimpleClauseType(
2905 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
2906 KLoc.push_back(Tok.getLocation());
2907 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2908 Tok.isNot(tok::annot_pragma_openmp_end))
2909 ConsumeAnyToken();
2910 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
2911 DelimLoc = ConsumeAnyToken();
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002912 } else if (Kind == OMPC_defaultmap) {
2913 // Get a defaultmap modifier
cchene06f3e02019-11-15 13:02:06 -05002914 unsigned Modifier = getOpenMPSimpleClauseType(
2915 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2916 // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
2917 // pointer
2918 if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
2919 Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
2920 Arg.push_back(Modifier);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002921 KLoc.push_back(Tok.getLocation());
2922 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2923 Tok.isNot(tok::annot_pragma_openmp_end))
2924 ConsumeAnyToken();
2925 // Parse ':'
Alexey Bataevec275272020-04-08 15:19:54 -04002926 if (Tok.is(tok::colon) || getLangOpts().OpenMP < 50) {
2927 if (Tok.is(tok::colon))
2928 ConsumeAnyToken();
2929 else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
2930 Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
2931 // Get a defaultmap kind
2932 Arg.push_back(getOpenMPSimpleClauseType(
2933 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
2934 KLoc.push_back(Tok.getLocation());
2935 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2936 Tok.isNot(tok::annot_pragma_openmp_end))
2937 ConsumeAnyToken();
2938 } else {
2939 Arg.push_back(OMPC_DEFAULTMAP_unknown);
2940 KLoc.push_back(SourceLocation());
2941 }
Alexey Bataev2f8894a2020-03-18 15:01:15 -04002942 } else if (Kind == OMPC_device) {
2943 // Only target executable directives support extended device construct.
2944 if (isOpenMPTargetExecutionDirective(DKind) && getLangOpts().OpenMP >= 50 &&
2945 NextToken().is(tok::colon)) {
2946 // Parse optional <device modifier> ':'
2947 Arg.push_back(getOpenMPSimpleClauseType(
2948 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
2949 KLoc.push_back(Tok.getLocation());
2950 ConsumeAnyToken();
2951 // Parse ':'
2952 ConsumeAnyToken();
2953 } else {
2954 Arg.push_back(OMPC_DEVICE_unknown);
2955 KLoc.emplace_back();
2956 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002957 } else {
2958 assert(Kind == OMPC_if);
Alexey Bataev6402bca2015-12-28 07:25:51 +00002959 KLoc.push_back(Tok.getLocation());
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002960 TentativeParsingAction TPA(*this);
Johannes Doerferteb3e81f2019-11-04 22:00:49 -06002961 auto DK = parseOpenMPDirectiveKind(*this);
2962 Arg.push_back(DK);
2963 if (DK != OMPD_unknown) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002964 ConsumeToken();
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002965 if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
2966 TPA.Commit();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002967 DelimLoc = ConsumeToken();
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002968 } else {
2969 TPA.Revert();
Johannes Doerferteb3e81f2019-11-04 22:00:49 -06002970 Arg.back() = unsigned(OMPD_unknown);
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002971 }
Alexey Bataev61908f652018-04-23 19:53:05 +00002972 } else {
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002973 TPA.Revert();
Alexey Bataev61908f652018-04-23 19:53:05 +00002974 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002975 }
Alexey Bataev56dafe82014-06-20 07:16:17 +00002976
Carlo Bertollib4adf552016-01-15 18:50:31 +00002977 bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
2978 (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
Alexey Bataev2f8894a2020-03-18 15:01:15 -04002979 Kind == OMPC_if || Kind == OMPC_device;
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002980 if (NeedAnExpression) {
2981 SourceLocation ELoc = Tok.getLocation();
Saar Razb65b1f32020-01-09 15:07:51 +02002982 ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
Alexey Bataev56dafe82014-06-20 07:16:17 +00002983 Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00002984 Val =
2985 Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002986 }
2987
2988 // Parse ')'.
Alexey Bataevdbc72c92018-07-06 19:35:42 +00002989 SourceLocation RLoc = Tok.getLocation();
2990 if (!T.consumeClose())
2991 RLoc = T.getCloseLocation();
Alexey Bataev56dafe82014-06-20 07:16:17 +00002992
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002993 if (NeedAnExpression && Val.isInvalid())
2994 return nullptr;
2995
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002996 if (ParseOnly)
2997 return nullptr;
Alexey Bataev56dafe82014-06-20 07:16:17 +00002998 return Actions.ActOnOpenMPSingleExprWithArgClause(
Alexey Bataevdbc72c92018-07-06 19:35:42 +00002999 Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
Alexey Bataev56dafe82014-06-20 07:16:17 +00003000}
3001
Alexey Bataevc5e02582014-06-16 07:08:35 +00003002static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
3003 UnqualifiedId &ReductionId) {
Alexey Bataevc5e02582014-06-16 07:08:35 +00003004 if (ReductionIdScopeSpec.isEmpty()) {
3005 auto OOK = OO_None;
3006 switch (P.getCurToken().getKind()) {
3007 case tok::plus:
3008 OOK = OO_Plus;
3009 break;
3010 case tok::minus:
3011 OOK = OO_Minus;
3012 break;
3013 case tok::star:
3014 OOK = OO_Star;
3015 break;
3016 case tok::amp:
3017 OOK = OO_Amp;
3018 break;
3019 case tok::pipe:
3020 OOK = OO_Pipe;
3021 break;
3022 case tok::caret:
3023 OOK = OO_Caret;
3024 break;
3025 case tok::ampamp:
3026 OOK = OO_AmpAmp;
3027 break;
3028 case tok::pipepipe:
3029 OOK = OO_PipePipe;
3030 break;
3031 default:
3032 break;
3033 }
3034 if (OOK != OO_None) {
3035 SourceLocation OpLoc = P.ConsumeToken();
Alexey Bataev23b69422014-06-18 07:08:49 +00003036 SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
Alexey Bataevc5e02582014-06-16 07:08:35 +00003037 ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
3038 return false;
3039 }
3040 }
Haojian Wu0dd0b102020-03-19 09:12:29 +01003041 return P.ParseUnqualifiedId(
3042 ReductionIdScopeSpec, /*ObjectType=*/nullptr,
3043 /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
3044 /*AllowDestructorName*/ false,
3045 /*AllowConstructorName*/ false,
3046 /*AllowDeductionGuide*/ false, nullptr, ReductionId);
Alexey Bataevc5e02582014-06-16 07:08:35 +00003047}
3048
Kelvin Lief579432018-12-18 22:18:41 +00003049/// Checks if the token is a valid map-type-modifier.
3050static OpenMPMapModifierKind isMapModifier(Parser &P) {
3051 Token Tok = P.getCurToken();
3052 if (!Tok.is(tok::identifier))
3053 return OMPC_MAP_MODIFIER_unknown;
3054
3055 Preprocessor &PP = P.getPreprocessor();
3056 OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
3057 getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
3058 return TypeModifier;
3059}
3060
Michael Kruse01f670d2019-02-22 22:29:42 +00003061/// Parse the mapper modifier in map, to, and from clauses.
3062bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
3063 // Parse '('.
3064 BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
3065 if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
3066 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3067 StopBeforeMatch);
3068 return true;
3069 }
3070 // Parse mapper-identifier
3071 if (getLangOpts().CPlusPlus)
3072 ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3073 /*ObjectType=*/nullptr,
Haojian Wu0dd0b102020-03-19 09:12:29 +01003074 /*ObjectHadErrors=*/false,
Michael Kruse01f670d2019-02-22 22:29:42 +00003075 /*EnteringContext=*/false);
3076 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
3077 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
3078 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3079 StopBeforeMatch);
3080 return true;
3081 }
3082 auto &DeclNames = Actions.getASTContext().DeclarationNames;
3083 Data.ReductionOrMapperId = DeclarationNameInfo(
3084 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
3085 ConsumeToken();
3086 // Parse ')'.
3087 return T.consumeClose();
3088}
3089
Kelvin Lief579432018-12-18 22:18:41 +00003090/// Parse map-type-modifiers in map clause.
3091/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
Michael Kruse4304e9d2019-02-19 16:38:20 +00003092/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
3093bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
3094 while (getCurToken().isNot(tok::colon)) {
3095 OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
Kelvin Lief579432018-12-18 22:18:41 +00003096 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
3097 TypeModifier == OMPC_MAP_MODIFIER_close) {
3098 Data.MapTypeModifiers.push_back(TypeModifier);
3099 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
Michael Kruse4304e9d2019-02-19 16:38:20 +00003100 ConsumeToken();
3101 } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
3102 Data.MapTypeModifiers.push_back(TypeModifier);
3103 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3104 ConsumeToken();
Michael Kruse01f670d2019-02-22 22:29:42 +00003105 if (parseMapperModifier(Data))
Michael Kruse4304e9d2019-02-19 16:38:20 +00003106 return true;
Kelvin Lief579432018-12-18 22:18:41 +00003107 } else {
3108 // For the case of unknown map-type-modifier or a map-type.
3109 // Map-type is followed by a colon; the function returns when it
3110 // encounters a token followed by a colon.
3111 if (Tok.is(tok::comma)) {
Michael Kruse4304e9d2019-02-19 16:38:20 +00003112 Diag(Tok, diag::err_omp_map_type_modifier_missing);
3113 ConsumeToken();
Kelvin Lief579432018-12-18 22:18:41 +00003114 continue;
3115 }
3116 // Potential map-type token as it is followed by a colon.
3117 if (PP.LookAhead(0).is(tok::colon))
Michael Kruse4304e9d2019-02-19 16:38:20 +00003118 return false;
3119 Diag(Tok, diag::err_omp_unknown_map_type_modifier);
3120 ConsumeToken();
Kelvin Lief579432018-12-18 22:18:41 +00003121 }
Michael Kruse4304e9d2019-02-19 16:38:20 +00003122 if (getCurToken().is(tok::comma))
3123 ConsumeToken();
Kelvin Lief579432018-12-18 22:18:41 +00003124 }
Michael Kruse4304e9d2019-02-19 16:38:20 +00003125 return false;
Kelvin Lief579432018-12-18 22:18:41 +00003126}
3127
3128/// Checks if the token is a valid map-type.
3129static OpenMPMapClauseKind isMapType(Parser &P) {
3130 Token Tok = P.getCurToken();
3131 // The map-type token can be either an identifier or the C++ delete keyword.
3132 if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
3133 return OMPC_MAP_unknown;
3134 Preprocessor &PP = P.getPreprocessor();
3135 OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
3136 getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
3137 return MapType;
3138}
3139
3140/// Parse map-type in map clause.
3141/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
Ilya Biryukovff2a9972019-02-26 11:01:50 +00003142/// where, map-type ::= to | from | tofrom | alloc | release | delete
Kelvin Lief579432018-12-18 22:18:41 +00003143static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
3144 Token Tok = P.getCurToken();
3145 if (Tok.is(tok::colon)) {
3146 P.Diag(Tok, diag::err_omp_map_type_missing);
3147 return;
3148 }
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003149 Data.ExtraModifier = isMapType(P);
3150 if (Data.ExtraModifier == OMPC_MAP_unknown)
Kelvin Lief579432018-12-18 22:18:41 +00003151 P.Diag(Tok, diag::err_omp_unknown_map_type);
3152 P.ConsumeToken();
3153}
3154
Alexey Bataev13a15042020-04-01 15:06:38 -04003155/// Parses simple expression in parens for single-expression clauses of OpenMP
3156/// constructs.
3157/// \param RLoc Returned location of right paren.
3158ExprResult Parser::ParseOpenMPIteratorsExpr() {
3159 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
3160 "Expected 'iterator' token.");
3161 SourceLocation IteratorKwLoc = ConsumeToken();
3162
3163 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3164 if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator"))
3165 return ExprError();
3166
3167 SourceLocation LLoc = T.getOpenLocation();
3168 SmallVector<Sema::OMPIteratorData, 4> Data;
3169 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
3170 // Check if the type parsing is required.
3171 ParsedType IteratorType;
3172 if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) {
3173 // identifier '=' is not found - parse type.
3174 TypeResult TR = ParseTypeName();
3175 if (TR.isInvalid()) {
3176 T.skipToEnd();
3177 return ExprError();
3178 }
3179 IteratorType = TR.get();
3180 }
3181
3182 // Parse identifier.
3183 IdentifierInfo *II = nullptr;
3184 SourceLocation IdLoc;
3185 if (Tok.is(tok::identifier)) {
3186 II = Tok.getIdentifierInfo();
3187 IdLoc = ConsumeToken();
3188 } else {
3189 Diag(Tok, diag::err_expected_unqualified_id) << 0;
3190 }
3191
3192 // Parse '='.
3193 SourceLocation AssignLoc;
3194 if (Tok.is(tok::equal))
3195 AssignLoc = ConsumeToken();
3196 else
3197 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
3198
3199 // Parse range-specification - <begin> ':' <end> [ ':' <step> ]
3200 ColonProtectionRAIIObject ColonRAII(*this);
3201 // Parse <begin>
3202 SourceLocation Loc = Tok.getLocation();
3203 ExprResult LHS = ParseCastExpression(AnyCastExpr);
3204 ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
3205 ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3206 Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
3207 /*DiscardedValue=*/false);
3208 // Parse ':'.
3209 SourceLocation ColonLoc;
3210 if (Tok.is(tok::colon))
3211 ColonLoc = ConsumeToken();
3212
3213 // Parse <end>
3214 Loc = Tok.getLocation();
3215 LHS = ParseCastExpression(AnyCastExpr);
3216 ExprResult End = Actions.CorrectDelayedTyposInExpr(
3217 ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3218 End = Actions.ActOnFinishFullExpr(End.get(), Loc,
3219 /*DiscardedValue=*/false);
3220
3221 SourceLocation SecColonLoc;
3222 ExprResult Step;
3223 // Parse optional step.
3224 if (Tok.is(tok::colon)) {
3225 // Parse ':'
3226 SecColonLoc = ConsumeToken();
3227 // Parse <step>
3228 Loc = Tok.getLocation();
3229 LHS = ParseCastExpression(AnyCastExpr);
3230 Step = Actions.CorrectDelayedTyposInExpr(
3231 ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3232 Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
3233 /*DiscardedValue=*/false);
3234 }
3235
3236 // Parse ',' or ')'
3237 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
3238 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
3239 if (Tok.is(tok::comma))
3240 ConsumeToken();
3241
3242 Sema::OMPIteratorData &D = Data.emplace_back();
3243 D.DeclIdent = II;
3244 D.DeclIdentLoc = IdLoc;
3245 D.Type = IteratorType;
3246 D.AssignLoc = AssignLoc;
3247 D.ColonLoc = ColonLoc;
3248 D.SecColonLoc = SecColonLoc;
3249 D.Range.Begin = Begin.get();
3250 D.Range.End = End.get();
3251 D.Range.Step = Step.get();
3252 }
3253
3254 // Parse ')'.
3255 SourceLocation RLoc = Tok.getLocation();
3256 if (!T.consumeClose())
3257 RLoc = T.getCloseLocation();
3258
3259 return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc,
3260 Data);
3261}
3262
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003263/// Parses clauses with list.
3264bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
3265 OpenMPClauseKind Kind,
3266 SmallVectorImpl<Expr *> &Vars,
3267 OpenMPVarListDataTy &Data) {
3268 UnqualifiedId UnqualifiedReductionId;
3269 bool InvalidReductionId = false;
Michael Kruse01f670d2019-02-22 22:29:42 +00003270 bool IsInvalidMapperModifier = false;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003271
3272 // Parse '('.
3273 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3274 if (T.expectAndConsume(diag::err_expected_lparen_after,
Johannes Doerfert419a5592020-03-30 19:58:40 -05003275 getOpenMPClauseName(Kind).data()))
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003276 return true;
3277
Alexey Bataev13a15042020-04-01 15:06:38 -04003278 bool DependWithIterator = false;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003279 bool NeedRParenForLinear = false;
3280 BalancedDelimiterTracker LinearT(*this, tok::l_paren,
3281 tok::annot_pragma_openmp_end);
3282 // Handle reduction-identifier for reduction clause.
Alexey Bataevfa312f32017-07-21 18:48:21 +00003283 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
3284 Kind == OMPC_in_reduction) {
Alexey Bataev1236eb62020-03-23 17:30:38 -04003285 Data.ExtraModifier = OMPC_REDUCTION_unknown;
3286 if (Kind == OMPC_reduction && getLangOpts().OpenMP >= 50 &&
3287 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
3288 NextToken().is(tok::comma)) {
3289 // Parse optional reduction modifier.
3290 Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
3291 Data.ExtraModifierLoc = Tok.getLocation();
3292 ConsumeToken();
3293 assert(Tok.is(tok::comma) && "Expected comma.");
3294 (void)ConsumeToken();
3295 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003296 ColonProtectionRAIIObject ColonRAII(*this);
3297 if (getLangOpts().CPlusPlus)
Michael Kruse4304e9d2019-02-19 16:38:20 +00003298 ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003299 /*ObjectType=*/nullptr,
Haojian Wu0dd0b102020-03-19 09:12:29 +01003300 /*ObjectHadErrors=*/false,
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003301 /*EnteringContext=*/false);
Michael Kruse4304e9d2019-02-19 16:38:20 +00003302 InvalidReductionId = ParseReductionId(
3303 *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003304 if (InvalidReductionId) {
3305 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3306 StopBeforeMatch);
3307 }
3308 if (Tok.is(tok::colon))
3309 Data.ColonLoc = ConsumeToken();
3310 else
3311 Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
3312 if (!InvalidReductionId)
Michael Kruse4304e9d2019-02-19 16:38:20 +00003313 Data.ReductionOrMapperId =
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003314 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
3315 } else if (Kind == OMPC_depend) {
Alexey Bataev13a15042020-04-01 15:06:38 -04003316 if (getLangOpts().OpenMP >= 50) {
3317 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") {
3318 // Handle optional dependence modifier.
3319 // iterator(iterators-definition)
3320 // where iterators-definition is iterator-specifier [,
3321 // iterators-definition ]
3322 // where iterator-specifier is [ iterator-type ] identifier =
3323 // range-specification
3324 DependWithIterator = true;
3325 EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3326 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
3327 Data.DepModOrTailExpr = IteratorRes.get();
3328 // Parse ','
3329 ExpectAndConsume(tok::comma);
3330 }
3331 }
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003332 // Handle dependency type for depend clause.
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003333 ColonProtectionRAIIObject ColonRAII(*this);
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003334 Data.ExtraModifier = getOpenMPSimpleClauseType(
3335 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "");
Alexey Bataev1236eb62020-03-23 17:30:38 -04003336 Data.ExtraModifierLoc = Tok.getLocation();
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003337 if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003338 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3339 StopBeforeMatch);
3340 } else {
3341 ConsumeToken();
3342 // Special processing for depend(source) clause.
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003343 if (DKind == OMPD_ordered && Data.ExtraModifier == OMPC_DEPEND_source) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003344 // Parse ')'.
3345 T.consumeClose();
3346 return false;
3347 }
3348 }
Alexey Bataev61908f652018-04-23 19:53:05 +00003349 if (Tok.is(tok::colon)) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003350 Data.ColonLoc = ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +00003351 } else {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003352 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
3353 : diag::warn_pragma_expected_colon)
3354 << "dependency type";
3355 }
3356 } else if (Kind == OMPC_linear) {
3357 // Try to parse modifier if any.
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003358 Data.ExtraModifier = OMPC_LINEAR_val;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003359 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003360 Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
Alexey Bataev1236eb62020-03-23 17:30:38 -04003361 Data.ExtraModifierLoc = ConsumeToken();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003362 LinearT.consumeOpen();
3363 NeedRParenForLinear = true;
3364 }
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003365 } else if (Kind == OMPC_lastprivate) {
3366 // Try to parse modifier if any.
3367 Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
3368 // Conditional modifier allowed only in OpenMP 5.0 and not supported in
3369 // distribute and taskloop based directives.
3370 if ((getLangOpts().OpenMP >= 50 && !isOpenMPDistributeDirective(DKind) &&
3371 !isOpenMPTaskLoopDirective(DKind)) &&
3372 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
3373 Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
Alexey Bataev1236eb62020-03-23 17:30:38 -04003374 Data.ExtraModifierLoc = Tok.getLocation();
3375 ConsumeToken();
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003376 assert(Tok.is(tok::colon) && "Expected colon.");
3377 Data.ColonLoc = ConsumeToken();
3378 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003379 } else if (Kind == OMPC_map) {
3380 // Handle map type for map clause.
3381 ColonProtectionRAIIObject ColonRAII(*this);
3382
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003383 // The first identifier may be a list item, a map-type or a
Kelvin Lief579432018-12-18 22:18:41 +00003384 // map-type-modifier. The map-type can also be delete which has the same
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003385 // spelling of the C++ delete keyword.
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003386 Data.ExtraModifier = OMPC_MAP_unknown;
Alexey Bataev1236eb62020-03-23 17:30:38 -04003387 Data.ExtraModifierLoc = Tok.getLocation();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003388
Kelvin Lief579432018-12-18 22:18:41 +00003389 // Check for presence of a colon in the map clause.
3390 TentativeParsingAction TPA(*this);
3391 bool ColonPresent = false;
3392 if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3393 StopBeforeMatch)) {
3394 if (Tok.is(tok::colon))
3395 ColonPresent = true;
3396 }
3397 TPA.Revert();
3398 // Only parse map-type-modifier[s] and map-type if a colon is present in
3399 // the map clause.
3400 if (ColonPresent) {
Michael Kruse01f670d2019-02-22 22:29:42 +00003401 IsInvalidMapperModifier = parseMapTypeModifiers(Data);
3402 if (!IsInvalidMapperModifier)
Michael Kruse4304e9d2019-02-19 16:38:20 +00003403 parseMapType(*this, Data);
Michael Kruse01f670d2019-02-22 22:29:42 +00003404 else
3405 SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
Kelvin Lief579432018-12-18 22:18:41 +00003406 }
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003407 if (Data.ExtraModifier == OMPC_MAP_unknown) {
3408 Data.ExtraModifier = OMPC_MAP_tofrom;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003409 Data.IsMapTypeImplicit = true;
3410 }
3411
3412 if (Tok.is(tok::colon))
3413 Data.ColonLoc = ConsumeToken();
Michael Kruse0336c752019-02-25 20:34:15 +00003414 } else if (Kind == OMPC_to || Kind == OMPC_from) {
Michael Kruse01f670d2019-02-22 22:29:42 +00003415 if (Tok.is(tok::identifier)) {
3416 bool IsMapperModifier = false;
Michael Kruse0336c752019-02-25 20:34:15 +00003417 if (Kind == OMPC_to) {
3418 auto Modifier = static_cast<OpenMPToModifierKind>(
3419 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
3420 if (Modifier == OMPC_TO_MODIFIER_mapper)
3421 IsMapperModifier = true;
3422 } else {
3423 auto Modifier = static_cast<OpenMPFromModifierKind>(
3424 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
3425 if (Modifier == OMPC_FROM_MODIFIER_mapper)
3426 IsMapperModifier = true;
3427 }
Michael Kruse01f670d2019-02-22 22:29:42 +00003428 if (IsMapperModifier) {
3429 // Parse the mapper modifier.
3430 ConsumeToken();
3431 IsInvalidMapperModifier = parseMapperModifier(Data);
3432 if (Tok.isNot(tok::colon)) {
3433 if (!IsInvalidMapperModifier)
3434 Diag(Tok, diag::warn_pragma_expected_colon) << ")";
3435 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3436 StopBeforeMatch);
3437 }
3438 // Consume ':'.
3439 if (Tok.is(tok::colon))
3440 ConsumeToken();
3441 }
3442 }
Alexey Bataeve04483e2019-03-27 14:14:31 +00003443 } else if (Kind == OMPC_allocate) {
3444 // Handle optional allocator expression followed by colon delimiter.
3445 ColonProtectionRAIIObject ColonRAII(*this);
3446 TentativeParsingAction TPA(*this);
3447 ExprResult Tail =
3448 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3449 Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
3450 /*DiscardedValue=*/false);
3451 if (Tail.isUsable()) {
3452 if (Tok.is(tok::colon)) {
Alexey Bataev13a15042020-04-01 15:06:38 -04003453 Data.DepModOrTailExpr = Tail.get();
Alexey Bataeve04483e2019-03-27 14:14:31 +00003454 Data.ColonLoc = ConsumeToken();
3455 TPA.Commit();
3456 } else {
3457 // colon not found, no allocator specified, parse only list of
3458 // variables.
3459 TPA.Revert();
3460 }
3461 } else {
3462 // Parsing was unsuccessfull, revert and skip to the end of clause or
3463 // directive.
3464 TPA.Revert();
3465 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3466 StopBeforeMatch);
3467 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003468 }
3469
Alexey Bataevfa312f32017-07-21 18:48:21 +00003470 bool IsComma =
3471 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
3472 Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
3473 (Kind == OMPC_reduction && !InvalidReductionId) ||
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003474 (Kind == OMPC_map && Data.ExtraModifier != OMPC_MAP_unknown) ||
3475 (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003476 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
3477 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
3478 Tok.isNot(tok::annot_pragma_openmp_end))) {
Alexey Bataev13a15042020-04-01 15:06:38 -04003479 ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003480 ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
3481 // Parse variable
3482 ExprResult VarExpr =
3483 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
Alexey Bataev61908f652018-04-23 19:53:05 +00003484 if (VarExpr.isUsable()) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003485 Vars.push_back(VarExpr.get());
Alexey Bataev61908f652018-04-23 19:53:05 +00003486 } else {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003487 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3488 StopBeforeMatch);
3489 }
3490 // Skip ',' if any
3491 IsComma = Tok.is(tok::comma);
3492 if (IsComma)
3493 ConsumeToken();
3494 else if (Tok.isNot(tok::r_paren) &&
3495 Tok.isNot(tok::annot_pragma_openmp_end) &&
3496 (!MayHaveTail || Tok.isNot(tok::colon)))
3497 Diag(Tok, diag::err_omp_expected_punc)
3498 << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
3499 : getOpenMPClauseName(Kind))
3500 << (Kind == OMPC_flush);
3501 }
3502
3503 // Parse ')' for linear clause with modifier.
3504 if (NeedRParenForLinear)
3505 LinearT.consumeClose();
3506
3507 // Parse ':' linear-step (or ':' alignment).
3508 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
3509 if (MustHaveTail) {
3510 Data.ColonLoc = Tok.getLocation();
3511 SourceLocation ELoc = ConsumeToken();
3512 ExprResult Tail = ParseAssignmentExpression();
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00003513 Tail =
3514 Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003515 if (Tail.isUsable())
Alexey Bataev13a15042020-04-01 15:06:38 -04003516 Data.DepModOrTailExpr = Tail.get();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003517 else
3518 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3519 StopBeforeMatch);
3520 }
3521
3522 // Parse ')'.
Alexey Bataevdbc72c92018-07-06 19:35:42 +00003523 Data.RLoc = Tok.getLocation();
3524 if (!T.consumeClose())
3525 Data.RLoc = T.getCloseLocation();
Alexey Bataev13a15042020-04-01 15:06:38 -04003526 // Exit from scope when the iterator is used in depend clause.
3527 if (DependWithIterator)
3528 ExitScope();
Alexey Bataev5dadf572020-03-06 11:09:55 -05003529 return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
Alexey Bataev13a15042020-04-01 15:06:38 -04003530 (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
Michael Kruse01f670d2019-02-22 22:29:42 +00003531 IsInvalidMapperModifier;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003532}
3533
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003534/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
Alexey Bataev06dea732020-03-20 09:41:22 -04003535/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
Alexey Bataev63828a32020-03-23 10:41:08 -04003536/// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003537///
3538/// private-clause:
3539/// 'private' '(' list ')'
Alexey Bataevd5af8e42013-10-01 05:32:34 +00003540/// firstprivate-clause:
3541/// 'firstprivate' '(' list ')'
Alexander Musman1bb328c2014-06-04 13:06:39 +00003542/// lastprivate-clause:
3543/// 'lastprivate' '(' list ')'
Alexey Bataev758e55e2013-09-06 18:03:48 +00003544/// shared-clause:
3545/// 'shared' '(' list ')'
Alexander Musman8dba6642014-04-22 13:09:42 +00003546/// linear-clause:
Alexey Bataev182227b2015-08-20 10:54:39 +00003547/// 'linear' '(' linear-list [ ':' linear-step ] ')'
Alexander Musmanf0d76e72014-05-29 14:36:25 +00003548/// aligned-clause:
3549/// 'aligned' '(' list [ ':' alignment ] ')'
Alexey Bataevc5e02582014-06-16 07:08:35 +00003550/// reduction-clause:
Alexey Bataev1236eb62020-03-23 17:30:38 -04003551/// 'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
Alexey Bataev169d96a2017-07-18 20:17:46 +00003552/// task_reduction-clause:
3553/// 'task_reduction' '(' reduction-identifier ':' list ')'
Alexey Bataevfa312f32017-07-21 18:48:21 +00003554/// in_reduction-clause:
3555/// 'in_reduction' '(' reduction-identifier ':' list ')'
Alexey Bataev6125da92014-07-21 11:26:11 +00003556/// copyprivate-clause:
3557/// 'copyprivate' '(' list ')'
3558/// flush-clause:
3559/// 'flush' '(' list ')'
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00003560/// depend-clause:
Alexey Bataeveb482352015-12-18 05:05:56 +00003561/// 'depend' '(' in | out | inout : list | source ')'
Kelvin Li0bff7af2015-11-23 05:32:03 +00003562/// map-clause:
Kelvin Lief579432018-12-18 22:18:41 +00003563/// 'map' '(' [ [ always [,] ] [ close [,] ]
Michael Kruse01f670d2019-02-22 22:29:42 +00003564/// [ mapper '(' mapper-identifier ')' [,] ]
Kelvin Li0bff7af2015-11-23 05:32:03 +00003565/// to | from | tofrom | alloc | release | delete ':' ] list ')';
Samuel Antao661c0902016-05-26 17:39:58 +00003566/// to-clause:
Michael Kruse01f670d2019-02-22 22:29:42 +00003567/// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
Samuel Antaoec172c62016-05-26 17:49:04 +00003568/// from-clause:
Michael Kruse0336c752019-02-25 20:34:15 +00003569/// 'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
Carlo Bertolli2404b172016-07-13 15:37:16 +00003570/// use_device_ptr-clause:
3571/// 'use_device_ptr' '(' list ')'
Carlo Bertolli70594e92016-07-13 17:16:49 +00003572/// is_device_ptr-clause:
3573/// 'is_device_ptr' '(' list ')'
Alexey Bataeve04483e2019-03-27 14:14:31 +00003574/// allocate-clause:
3575/// 'allocate' '(' [ allocator ':' ] list ')'
Alexey Bataev06dea732020-03-20 09:41:22 -04003576/// nontemporal-clause:
3577/// 'nontemporal' '(' list ')'
3578/// inclusive-clause:
3579/// 'inclusive' '(' list ')'
Alexey Bataev63828a32020-03-23 10:41:08 -04003580/// exclusive-clause:
3581/// 'exclusive' '(' list ')'
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003582///
Alexey Bataev182227b2015-08-20 10:54:39 +00003583/// For 'linear' clause linear-list may have the following forms:
3584/// list
3585/// modifier(list)
3586/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
Alexey Bataeveb482352015-12-18 05:05:56 +00003587OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
Alexey Bataevf3c832a2018-01-09 19:21:04 +00003588 OpenMPClauseKind Kind,
3589 bool ParseOnly) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003590 SourceLocation Loc = Tok.getLocation();
3591 SourceLocation LOpen = ConsumeToken();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003592 SmallVector<Expr *, 4> Vars;
3593 OpenMPVarListDataTy Data;
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00003594
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003595 if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
Craig Topper161e4db2014-05-21 06:02:52 +00003596 return nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003597
Alexey Bataevf3c832a2018-01-09 19:21:04 +00003598 if (ParseOnly)
3599 return nullptr;
Michael Kruse4304e9d2019-02-19 16:38:20 +00003600 OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
Alexey Bataevc5e02582014-06-16 07:08:35 +00003601 return Actions.ActOnOpenMPVarListClause(
Alexey Bataev13a15042020-04-01 15:06:38 -04003602 Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc,
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003603 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
3604 Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
Alexey Bataev1236eb62020-03-23 17:30:38 -04003605 Data.IsMapTypeImplicit, Data.ExtraModifierLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003606}
3607