blob: 56e88d15f8faaf42418de7aa76d031754462fb4b [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"
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000014#include "clang/AST/StmtOpenMP.h"
Alexey Bataev93dc40d2019-12-20 11:04:57 -050015#include "clang/Basic/OpenMPKinds.h"
Alexey Bataeva769e072013-03-22 06:34:35 +000016#include "clang/Parse/ParseDiagnostic.h"
Alexey Bataev6f6f3b42013-05-13 04:18:18 +000017#include "clang/Parse/Parser.h"
Vassil Vassilev11ad3392017-03-23 15:11:07 +000018#include "clang/Parse/RAIIObjectsForParser.h"
Alexey Bataev6f6f3b42013-05-13 04:18:18 +000019#include "clang/Sema/Scope.h"
20#include "llvm/ADT/PointerIntPair.h"
Alexey Bataev4513e93f2019-10-10 15:15:26 +000021#include "llvm/ADT/UniqueVector.h"
Johannes Doerfert1228d422019-12-19 20:42:12 -060022#include "llvm/Frontend/OpenMP/OMPContext.h"
Michael Wong65f367f2015-07-21 13:44:28 +000023
Alexey Bataeva769e072013-03-22 06:34:35 +000024using namespace clang;
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060025using namespace llvm::omp;
Alexey Bataeva769e072013-03-22 06:34:35 +000026
27//===----------------------------------------------------------------------===//
28// OpenMP declarative directives.
29//===----------------------------------------------------------------------===//
30
Dmitry Polukhin82478332016-02-13 06:53:38 +000031namespace {
32enum OpenMPDirectiveKindEx {
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060033 OMPD_cancellation = unsigned(OMPD_unknown) + 1,
Dmitry Polukhin82478332016-02-13 06:53:38 +000034 OMPD_data,
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000035 OMPD_declare,
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000036 OMPD_end,
37 OMPD_end_declare,
Dmitry Polukhin82478332016-02-13 06:53:38 +000038 OMPD_enter,
39 OMPD_exit,
40 OMPD_point,
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000041 OMPD_reduction,
Dmitry Polukhin82478332016-02-13 06:53:38 +000042 OMPD_target_enter,
Samuel Antao686c70c2016-05-26 17:30:50 +000043 OMPD_target_exit,
44 OMPD_update,
Kelvin Li579e41c2016-11-30 23:51:03 +000045 OMPD_distribute_parallel,
Kelvin Li80e8f562016-12-29 22:16:30 +000046 OMPD_teams_distribute_parallel,
Michael Kruse251e1482019-02-01 20:25:04 +000047 OMPD_target_teams_distribute_parallel,
48 OMPD_mapper,
Alexey Bataevd158cf62019-09-13 20:18:17 +000049 OMPD_variant,
Dmitry Polukhin82478332016-02-13 06:53:38 +000050};
Dmitry Polukhind69b5052016-05-09 14:59:13 +000051
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060052// Helper to unify the enum class OpenMPDirectiveKind with its extension
53// the OpenMPDirectiveKindEx enum which allows to use them together as if they
54// are unsigned values.
55struct OpenMPDirectiveKindExWrapper {
56 OpenMPDirectiveKindExWrapper(unsigned Value) : Value(Value) {}
57 OpenMPDirectiveKindExWrapper(OpenMPDirectiveKind DK) : Value(unsigned(DK)) {}
58 bool operator==(OpenMPDirectiveKind V) const { return Value == unsigned(V); }
59 bool operator!=(OpenMPDirectiveKind V) const { return Value != unsigned(V); }
60 bool operator<(OpenMPDirectiveKind V) const { return Value < unsigned(V); }
61 operator unsigned() const { return Value; }
62 operator OpenMPDirectiveKind() const { return OpenMPDirectiveKind(Value); }
63 unsigned Value;
64};
65
Alexey Bataev25ed0c02019-03-07 17:54:44 +000066class DeclDirectiveListParserHelper final {
Dmitry Polukhind69b5052016-05-09 14:59:13 +000067 SmallVector<Expr *, 4> Identifiers;
68 Parser *P;
Alexey Bataev25ed0c02019-03-07 17:54:44 +000069 OpenMPDirectiveKind Kind;
Dmitry Polukhind69b5052016-05-09 14:59:13 +000070
71public:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000072 DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
73 : P(P), Kind(Kind) {}
Dmitry Polukhind69b5052016-05-09 14:59:13 +000074 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
Alexey Bataev25ed0c02019-03-07 17:54:44 +000075 ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
76 P->getCurScope(), SS, NameInfo, Kind);
Dmitry Polukhind69b5052016-05-09 14:59:13 +000077 if (Res.isUsable())
78 Identifiers.push_back(Res.get());
79 }
80 llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
81};
Dmitry Polukhin82478332016-02-13 06:53:38 +000082} // namespace
83
84// Map token string to extended OMP token kind that are
85// OpenMPDirectiveKind + OpenMPDirectiveKindEx.
86static unsigned getOpenMPDirectiveKindEx(StringRef S) {
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060087 OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
Dmitry Polukhin82478332016-02-13 06:53:38 +000088 if (DKind != OMPD_unknown)
89 return DKind;
90
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060091 return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
Dmitry Polukhin82478332016-02-13 06:53:38 +000092 .Case("cancellation", OMPD_cancellation)
93 .Case("data", OMPD_data)
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000094 .Case("declare", OMPD_declare)
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000095 .Case("end", OMPD_end)
Dmitry Polukhin82478332016-02-13 06:53:38 +000096 .Case("enter", OMPD_enter)
97 .Case("exit", OMPD_exit)
98 .Case("point", OMPD_point)
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000099 .Case("reduction", OMPD_reduction)
Samuel Antao686c70c2016-05-26 17:30:50 +0000100 .Case("update", OMPD_update)
Michael Kruse251e1482019-02-01 20:25:04 +0000101 .Case("mapper", OMPD_mapper)
Alexey Bataevd158cf62019-09-13 20:18:17 +0000102 .Case("variant", OMPD_variant)
Dmitry Polukhin82478332016-02-13 06:53:38 +0000103 .Default(OMPD_unknown);
104}
105
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600106static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
Alexander Musmanf82886e2014-09-18 05:12:34 +0000107 // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
108 // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
109 // TODO: add other combined directives in topological order.
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600110 static const OpenMPDirectiveKindExWrapper F[][3] = {
Alexey Bataev61908f652018-04-23 19:53:05 +0000111 {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
112 {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
Michael Kruse251e1482019-02-01 20:25:04 +0000113 {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
Alexey Bataev61908f652018-04-23 19:53:05 +0000114 {OMPD_declare, OMPD_simd, OMPD_declare_simd},
115 {OMPD_declare, OMPD_target, OMPD_declare_target},
Alexey Bataevd158cf62019-09-13 20:18:17 +0000116 {OMPD_declare, OMPD_variant, OMPD_declare_variant},
Alexey Bataev61908f652018-04-23 19:53:05 +0000117 {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
118 {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
119 {OMPD_distribute_parallel_for, OMPD_simd,
120 OMPD_distribute_parallel_for_simd},
121 {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
122 {OMPD_end, OMPD_declare, OMPD_end_declare},
123 {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
124 {OMPD_target, OMPD_data, OMPD_target_data},
125 {OMPD_target, OMPD_enter, OMPD_target_enter},
126 {OMPD_target, OMPD_exit, OMPD_target_exit},
127 {OMPD_target, OMPD_update, OMPD_target_update},
128 {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
129 {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
130 {OMPD_for, OMPD_simd, OMPD_for_simd},
131 {OMPD_parallel, OMPD_for, OMPD_parallel_for},
132 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
133 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
134 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
135 {OMPD_target, OMPD_parallel, OMPD_target_parallel},
136 {OMPD_target, OMPD_simd, OMPD_target_simd},
137 {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
138 {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
139 {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
140 {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
141 {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
142 {OMPD_teams_distribute_parallel, OMPD_for,
143 OMPD_teams_distribute_parallel_for},
144 {OMPD_teams_distribute_parallel_for, OMPD_simd,
145 OMPD_teams_distribute_parallel_for_simd},
146 {OMPD_target, OMPD_teams, OMPD_target_teams},
147 {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
148 {OMPD_target_teams_distribute, OMPD_parallel,
149 OMPD_target_teams_distribute_parallel},
150 {OMPD_target_teams_distribute, OMPD_simd,
151 OMPD_target_teams_distribute_simd},
152 {OMPD_target_teams_distribute_parallel, OMPD_for,
153 OMPD_target_teams_distribute_parallel_for},
154 {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
Alexey Bataev60e51c42019-10-10 20:13:02 +0000155 OMPD_target_teams_distribute_parallel_for_simd},
Alexey Bataev5bbcead2019-10-14 17:17:41 +0000156 {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
Alexey Bataevb8552ab2019-10-18 16:47:35 +0000157 {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
Alexey Bataev5bbcead2019-10-14 17:17:41 +0000158 {OMPD_parallel, OMPD_master, OMPD_parallel_master},
Alexey Bataev14a388f2019-10-25 10:27:13 -0400159 {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
160 {OMPD_parallel_master_taskloop, OMPD_simd,
161 OMPD_parallel_master_taskloop_simd}};
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000162 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
Alexey Bataev61908f652018-04-23 19:53:05 +0000163 Token Tok = P.getCurToken();
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600164 OpenMPDirectiveKindExWrapper DKind =
Alexey Bataev4acb8592014-07-07 13:01:15 +0000165 Tok.isAnnotation()
Dmitry Polukhin82478332016-02-13 06:53:38 +0000166 ? static_cast<unsigned>(OMPD_unknown)
167 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
168 if (DKind == OMPD_unknown)
169 return OMPD_unknown;
Michael Wong65f367f2015-07-21 13:44:28 +0000170
Alexey Bataev61908f652018-04-23 19:53:05 +0000171 for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
172 if (DKind != F[I][0])
Dmitry Polukhin82478332016-02-13 06:53:38 +0000173 continue;
Michael Wong65f367f2015-07-21 13:44:28 +0000174
Dmitry Polukhin82478332016-02-13 06:53:38 +0000175 Tok = P.getPreprocessor().LookAhead(0);
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600176 OpenMPDirectiveKindExWrapper SDKind =
Dmitry Polukhin82478332016-02-13 06:53:38 +0000177 Tok.isAnnotation()
178 ? static_cast<unsigned>(OMPD_unknown)
179 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
180 if (SDKind == OMPD_unknown)
181 continue;
Michael Wong65f367f2015-07-21 13:44:28 +0000182
Alexey Bataev61908f652018-04-23 19:53:05 +0000183 if (SDKind == F[I][1]) {
Dmitry Polukhin82478332016-02-13 06:53:38 +0000184 P.ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +0000185 DKind = F[I][2];
Alexey Bataev4acb8592014-07-07 13:01:15 +0000186 }
187 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000188 return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
189 : OMPD_unknown;
190}
191
192static DeclarationName parseOpenMPReductionId(Parser &P) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000193 Token Tok = P.getCurToken();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000194 Sema &Actions = P.getActions();
195 OverloadedOperatorKind OOK = OO_None;
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000196 // Allow to use 'operator' keyword for C++ operators
197 bool WithOperator = false;
198 if (Tok.is(tok::kw_operator)) {
199 P.ConsumeToken();
200 Tok = P.getCurToken();
201 WithOperator = true;
202 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000203 switch (Tok.getKind()) {
204 case tok::plus: // '+'
205 OOK = OO_Plus;
206 break;
207 case tok::minus: // '-'
208 OOK = OO_Minus;
209 break;
210 case tok::star: // '*'
211 OOK = OO_Star;
212 break;
213 case tok::amp: // '&'
214 OOK = OO_Amp;
215 break;
216 case tok::pipe: // '|'
217 OOK = OO_Pipe;
218 break;
219 case tok::caret: // '^'
220 OOK = OO_Caret;
221 break;
222 case tok::ampamp: // '&&'
223 OOK = OO_AmpAmp;
224 break;
225 case tok::pipepipe: // '||'
226 OOK = OO_PipePipe;
227 break;
228 case tok::identifier: // identifier
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000229 if (!WithOperator)
230 break;
Galina Kistanova474f2ce2017-06-01 21:26:38 +0000231 LLVM_FALLTHROUGH;
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000232 default:
233 P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
234 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
235 Parser::StopBeforeMatch);
236 return DeclarationName();
237 }
238 P.ConsumeToken();
239 auto &DeclNames = Actions.getASTContext().DeclarationNames;
240 return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
241 : DeclNames.getCXXOperatorName(OOK);
242}
243
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000244/// Parse 'omp declare reduction' construct.
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000245///
246/// declare-reduction-directive:
247/// annot_pragma_openmp 'declare' 'reduction'
248/// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
249/// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
250/// annot_pragma_openmp_end
251/// <reduction_id> is either a base language identifier or one of the following
252/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
253///
254Parser::DeclGroupPtrTy
255Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
256 // Parse '('.
257 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600258 if (T.expectAndConsume(
259 diag::err_expected_lparen_after,
260 getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000261 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
262 return DeclGroupPtrTy();
263 }
264
265 DeclarationName Name = parseOpenMPReductionId(*this);
266 if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
267 return DeclGroupPtrTy();
268
269 // Consume ':'.
270 bool IsCorrect = !ExpectAndConsume(tok::colon);
271
272 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
273 return DeclGroupPtrTy();
274
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000275 IsCorrect = IsCorrect && !Name.isEmpty();
276
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000277 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
278 Diag(Tok.getLocation(), diag::err_expected_type);
279 IsCorrect = false;
280 }
281
282 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
283 return DeclGroupPtrTy();
284
285 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
286 // Parse list of types until ':' token.
287 do {
288 ColonProtectionRAIIObject ColonRAII(*this);
289 SourceRange Range;
Faisal Vali421b2d12017-12-29 05:41:00 +0000290 TypeResult TR =
291 ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000292 if (TR.isUsable()) {
Alexey Bataev61908f652018-04-23 19:53:05 +0000293 QualType ReductionType =
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000294 Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
295 if (!ReductionType.isNull()) {
296 ReductionTypes.push_back(
297 std::make_pair(ReductionType, Range.getBegin()));
298 }
299 } else {
300 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
301 StopBeforeMatch);
302 }
303
304 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
305 break;
306
307 // Consume ','.
308 if (ExpectAndConsume(tok::comma)) {
309 IsCorrect = false;
310 if (Tok.is(tok::annot_pragma_openmp_end)) {
311 Diag(Tok.getLocation(), diag::err_expected_type);
312 return DeclGroupPtrTy();
313 }
314 }
315 } while (Tok.isNot(tok::annot_pragma_openmp_end));
316
317 if (ReductionTypes.empty()) {
318 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
319 return DeclGroupPtrTy();
320 }
321
322 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
323 return DeclGroupPtrTy();
324
325 // Consume ':'.
326 if (ExpectAndConsume(tok::colon))
327 IsCorrect = false;
328
329 if (Tok.is(tok::annot_pragma_openmp_end)) {
330 Diag(Tok.getLocation(), diag::err_expected_expression);
331 return DeclGroupPtrTy();
332 }
333
334 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
335 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
336
337 // Parse <combiner> expression and then parse initializer if any for each
338 // correct type.
339 unsigned I = 0, E = ReductionTypes.size();
Alexey Bataev61908f652018-04-23 19:53:05 +0000340 for (Decl *D : DRD.get()) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000341 TentativeParsingAction TPA(*this);
342 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
Momchil Velikov57c681f2017-08-10 15:43:06 +0000343 Scope::CompoundStmtScope |
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000344 Scope::OpenMPDirectiveScope);
345 // Parse <combiner> expression.
346 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
Alexey Bataevc74a8ad2020-01-08 09:39:44 -0500347 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
348 ParseExpression().get(), D->getLocation(), /*DiscardedValue*/ false);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000349 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
350
351 if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
352 Tok.isNot(tok::annot_pragma_openmp_end)) {
353 TPA.Commit();
354 IsCorrect = false;
355 break;
356 }
357 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
358 ExprResult InitializerResult;
359 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
360 // Parse <initializer> expression.
361 if (Tok.is(tok::identifier) &&
Alexey Bataev61908f652018-04-23 19:53:05 +0000362 Tok.getIdentifierInfo()->isStr("initializer")) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000363 ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +0000364 } else {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000365 Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
366 TPA.Commit();
367 IsCorrect = false;
368 break;
369 }
370 // Parse '('.
371 BalancedDelimiterTracker T(*this, tok::l_paren,
372 tok::annot_pragma_openmp_end);
373 IsCorrect =
374 !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
375 IsCorrect;
376 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
377 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
Momchil Velikov57c681f2017-08-10 15:43:06 +0000378 Scope::CompoundStmtScope |
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000379 Scope::OpenMPDirectiveScope);
380 // Parse expression.
Alexey Bataev070f43a2017-09-06 14:49:58 +0000381 VarDecl *OmpPrivParm =
382 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
383 D);
384 // Check if initializer is omp_priv <init_expr> or something else.
385 if (Tok.is(tok::identifier) &&
386 Tok.getIdentifierInfo()->isStr("omp_priv")) {
Alexey Bataev3c676e32019-11-12 11:19:26 -0500387 ConsumeToken();
388 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
Alexey Bataev070f43a2017-09-06 14:49:58 +0000389 } else {
390 InitializerResult = Actions.ActOnFinishFullExpr(
391 ParseAssignmentExpression().get(), D->getLocation(),
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +0000392 /*DiscardedValue*/ false);
Alexey Bataev070f43a2017-09-06 14:49:58 +0000393 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000394 Actions.ActOnOpenMPDeclareReductionInitializerEnd(
Alexey Bataev070f43a2017-09-06 14:49:58 +0000395 D, InitializerResult.get(), OmpPrivParm);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +0000396 if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
397 Tok.isNot(tok::annot_pragma_openmp_end)) {
398 TPA.Commit();
399 IsCorrect = false;
400 break;
401 }
402 IsCorrect =
403 !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
404 }
405 }
406
407 ++I;
408 // Revert parsing if not the last type, otherwise accept it, we're done with
409 // parsing.
410 if (I != E)
411 TPA.Revert();
412 else
413 TPA.Commit();
414 }
415 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
416 IsCorrect);
Alexey Bataev4acb8592014-07-07 13:01:15 +0000417}
418
Alexey Bataev070f43a2017-09-06 14:49:58 +0000419void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
420 // Parse declarator '=' initializer.
421 // If a '==' or '+=' is found, suggest a fixit to '='.
422 if (isTokenEqualOrEqualTypo()) {
423 ConsumeToken();
424
425 if (Tok.is(tok::code_completion)) {
426 Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
427 Actions.FinalizeDeclaration(OmpPrivParm);
428 cutOffParsing();
429 return;
430 }
431
Alexey Bataev3c676e32019-11-12 11:19:26 -0500432 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
Alexey Bataev1fcc9b62020-01-02 15:49:08 -0500433 ExprResult Init = ParseInitializer();
Alexey Bataev070f43a2017-09-06 14:49:58 +0000434
435 if (Init.isInvalid()) {
436 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
437 Actions.ActOnInitializerError(OmpPrivParm);
438 } else {
439 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
440 /*DirectInit=*/false);
441 }
442 } else if (Tok.is(tok::l_paren)) {
443 // Parse C++ direct initializer: '(' expression-list ')'
444 BalancedDelimiterTracker T(*this, tok::l_paren);
445 T.consumeOpen();
446
447 ExprVector Exprs;
448 CommaLocsTy CommaLocs;
449
Ilya Biryukov2fab2352018-08-30 13:08:03 +0000450 SourceLocation LParLoc = T.getOpenLocation();
Ilya Biryukovff2a9972019-02-26 11:01:50 +0000451 auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
452 QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
453 getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
454 OmpPrivParm->getLocation(), Exprs, LParLoc);
455 CalledSignatureHelp = true;
456 return PreferredType;
457 };
458 if (ParseExpressionList(Exprs, CommaLocs, [&] {
459 PreferredType.enterFunctionArgument(Tok.getLocation(),
460 RunSignatureHelp);
461 })) {
462 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
463 RunSignatureHelp();
Alexey Bataev070f43a2017-09-06 14:49:58 +0000464 Actions.ActOnInitializerError(OmpPrivParm);
465 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
466 } else {
467 // Match the ')'.
Alexey Bataevdbc72c92018-07-06 19:35:42 +0000468 SourceLocation RLoc = Tok.getLocation();
469 if (!T.consumeClose())
470 RLoc = T.getCloseLocation();
Alexey Bataev070f43a2017-09-06 14:49:58 +0000471
472 assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
473 "Unexpected number of commas!");
474
Alexey Bataevdbc72c92018-07-06 19:35:42 +0000475 ExprResult Initializer =
476 Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
Alexey Bataev070f43a2017-09-06 14:49:58 +0000477 Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
478 /*DirectInit=*/true);
479 }
480 } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
481 // Parse C++0x braced-init-list.
482 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
483
484 ExprResult Init(ParseBraceInitializer());
485
486 if (Init.isInvalid()) {
487 Actions.ActOnInitializerError(OmpPrivParm);
488 } else {
489 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
490 /*DirectInit=*/true);
491 }
492 } else {
493 Actions.ActOnUninitializedDecl(OmpPrivParm);
494 }
495}
496
Michael Kruse251e1482019-02-01 20:25:04 +0000497/// Parses 'omp declare mapper' directive.
498///
499/// declare-mapper-directive:
500/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
501/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
502/// annot_pragma_openmp_end
503/// <mapper-identifier> and <var> are base language identifiers.
504///
505Parser::DeclGroupPtrTy
506Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
507 bool IsCorrect = true;
508 // Parse '('
509 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
510 if (T.expectAndConsume(diag::err_expected_lparen_after,
Johannes Doerferteb3e81f2019-11-04 22:00:49 -0600511 getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
Michael Kruse251e1482019-02-01 20:25:04 +0000512 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
513 return DeclGroupPtrTy();
514 }
515
516 // Parse <mapper-identifier>
517 auto &DeclNames = Actions.getASTContext().DeclarationNames;
518 DeclarationName MapperId;
519 if (PP.LookAhead(0).is(tok::colon)) {
520 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
521 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
522 IsCorrect = false;
523 } else {
524 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
525 }
526 ConsumeToken();
527 // Consume ':'.
528 ExpectAndConsume(tok::colon);
529 } else {
530 // If no mapper identifier is provided, its name is "default" by default
531 MapperId =
532 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
533 }
534
535 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
536 return DeclGroupPtrTy();
537
538 // Parse <type> <var>
539 DeclarationName VName;
540 QualType MapperType;
541 SourceRange Range;
542 TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
543 if (ParsedType.isUsable())
544 MapperType =
545 Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
546 if (MapperType.isNull())
547 IsCorrect = false;
548 if (!IsCorrect) {
549 SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
550 return DeclGroupPtrTy();
551 }
552
553 // Consume ')'.
554 IsCorrect &= !T.consumeClose();
555 if (!IsCorrect) {
556 SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
557 return DeclGroupPtrTy();
558 }
559
560 // Enter scope.
561 OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
562 getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
563 Range.getBegin(), VName, AS);
564 DeclarationNameInfo DirName;
565 SourceLocation Loc = Tok.getLocation();
566 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
567 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
568 ParseScope OMPDirectiveScope(this, ScopeFlags);
569 Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
570
571 // Add the mapper variable declaration.
572 Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
573 DMD, getCurScope(), MapperType, Range.getBegin(), VName);
574
575 // Parse map clauses.
576 SmallVector<OMPClause *, 6> Clauses;
577 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
578 OpenMPClauseKind CKind = Tok.isAnnotation()
579 ? OMPC_unknown
580 : getOpenMPClauseKind(PP.getSpelling(Tok));
581 Actions.StartOpenMPClause(CKind);
582 OMPClause *Clause =
583 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
584 if (Clause)
585 Clauses.push_back(Clause);
586 else
587 IsCorrect = false;
588 // Skip ',' if any.
589 if (Tok.is(tok::comma))
590 ConsumeToken();
591 Actions.EndOpenMPClause();
592 }
593 if (Clauses.empty()) {
594 Diag(Tok, diag::err_omp_expected_clause)
595 << getOpenMPDirectiveName(OMPD_declare_mapper);
596 IsCorrect = false;
597 }
598
599 // Exit scope.
600 Actions.EndOpenMPDSABlock(nullptr);
601 OMPDirectiveScope.Exit();
602
603 DeclGroupPtrTy DGP =
604 Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
605 if (!IsCorrect)
606 return DeclGroupPtrTy();
607 return DGP;
608}
609
610TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
611 DeclarationName &Name,
612 AccessSpecifier AS) {
613 // Parse the common declaration-specifiers piece.
614 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
615 DeclSpec DS(AttrFactory);
616 ParseSpecifierQualifierList(DS, AS, DSC);
617
618 // Parse the declarator.
619 DeclaratorContext Context = DeclaratorContext::PrototypeContext;
620 Declarator DeclaratorInfo(DS, Context);
621 ParseDeclarator(DeclaratorInfo);
622 Range = DeclaratorInfo.getSourceRange();
623 if (DeclaratorInfo.getIdentifier() == nullptr) {
624 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
625 return true;
626 }
627 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
628
629 return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
630}
631
Alexey Bataev2af33e32016-04-07 12:45:37 +0000632namespace {
633/// RAII that recreates function context for correct parsing of clauses of
634/// 'declare simd' construct.
635/// OpenMP, 2.8.2 declare simd Construct
636/// The expressions appearing in the clauses of this directive are evaluated in
637/// the scope of the arguments of the function declaration or definition.
638class FNContextRAII final {
639 Parser &P;
640 Sema::CXXThisScopeRAII *ThisScope;
641 Parser::ParseScope *TempScope;
642 Parser::ParseScope *FnScope;
643 bool HasTemplateScope = false;
644 bool HasFunScope = false;
645 FNContextRAII() = delete;
646 FNContextRAII(const FNContextRAII &) = delete;
647 FNContextRAII &operator=(const FNContextRAII &) = delete;
648
649public:
650 FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
651 Decl *D = *Ptr.get().begin();
652 NamedDecl *ND = dyn_cast<NamedDecl>(D);
653 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
654 Sema &Actions = P.getActions();
655
656 // Allow 'this' within late-parsed attributes.
Mikael Nilsson9d2872d2018-12-13 10:15:27 +0000657 ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
Alexey Bataev2af33e32016-04-07 12:45:37 +0000658 ND && ND->isCXXInstanceMember());
659
660 // If the Decl is templatized, add template parameters to scope.
661 HasTemplateScope = D->isTemplateDecl();
662 TempScope =
663 new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
664 if (HasTemplateScope)
665 Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
666
667 // If the Decl is on a function, add function parameters to the scope.
668 HasFunScope = D->isFunctionOrFunctionTemplate();
Momchil Velikov57c681f2017-08-10 15:43:06 +0000669 FnScope = new Parser::ParseScope(
670 &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
671 HasFunScope);
Alexey Bataev2af33e32016-04-07 12:45:37 +0000672 if (HasFunScope)
673 Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
674 }
675 ~FNContextRAII() {
676 if (HasFunScope) {
677 P.getActions().ActOnExitFunctionContext();
678 FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
679 }
680 if (HasTemplateScope)
681 TempScope->Exit();
682 delete FnScope;
683 delete TempScope;
684 delete ThisScope;
685 }
686};
687} // namespace
688
Alexey Bataevd93d3762016-04-12 09:35:56 +0000689/// Parses clauses for 'declare simd' directive.
690/// clause:
691/// 'inbranch' | 'notinbranch'
692/// 'simdlen' '(' <expr> ')'
693/// { 'uniform' '(' <argument_list> ')' }
694/// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
Alexey Bataevecba70f2016-04-12 11:02:11 +0000695/// { 'linear '(' <argument_list> [ ':' <step> ] ')' }
696static bool parseDeclareSimdClauses(
697 Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
698 SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
699 SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
700 SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
Alexey Bataevd93d3762016-04-12 09:35:56 +0000701 SourceRange BSRange;
702 const Token &Tok = P.getCurToken();
703 bool IsError = false;
704 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
705 if (Tok.isNot(tok::identifier))
706 break;
707 OMPDeclareSimdDeclAttr::BranchStateTy Out;
708 IdentifierInfo *II = Tok.getIdentifierInfo();
709 StringRef ClauseName = II->getName();
710 // Parse 'inranch|notinbranch' clauses.
711 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
712 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
713 P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
714 << ClauseName
715 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
716 IsError = true;
717 }
718 BS = Out;
719 BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
720 P.ConsumeToken();
721 } else if (ClauseName.equals("simdlen")) {
722 if (SimdLen.isUsable()) {
723 P.Diag(Tok, diag::err_omp_more_one_clause)
724 << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
725 IsError = true;
726 }
727 P.ConsumeToken();
728 SourceLocation RLoc;
729 SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
730 if (SimdLen.isInvalid())
731 IsError = true;
732 } else {
733 OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
Alexey Bataevecba70f2016-04-12 11:02:11 +0000734 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
735 CKind == OMPC_linear) {
Alexey Bataevd93d3762016-04-12 09:35:56 +0000736 Parser::OpenMPVarListDataTy Data;
Alexey Bataev61908f652018-04-23 19:53:05 +0000737 SmallVectorImpl<Expr *> *Vars = &Uniforms;
Alexey Bataev3732f4e2019-12-24 16:02:58 -0500738 if (CKind == OMPC_aligned) {
Alexey Bataevd93d3762016-04-12 09:35:56 +0000739 Vars = &Aligneds;
Alexey Bataev3732f4e2019-12-24 16:02:58 -0500740 } else if (CKind == OMPC_linear) {
741 Data.ExtraModifier = OMPC_LINEAR_val;
Alexey Bataevecba70f2016-04-12 11:02:11 +0000742 Vars = &Linears;
Alexey Bataev3732f4e2019-12-24 16:02:58 -0500743 }
Alexey Bataevd93d3762016-04-12 09:35:56 +0000744
745 P.ConsumeToken();
746 if (P.ParseOpenMPVarList(OMPD_declare_simd,
747 getOpenMPClauseKind(ClauseName), *Vars, Data))
748 IsError = true;
Alexey Bataev61908f652018-04-23 19:53:05 +0000749 if (CKind == OMPC_aligned) {
Alexey Bataevd93d3762016-04-12 09:35:56 +0000750 Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
Alexey Bataev61908f652018-04-23 19:53:05 +0000751 } else if (CKind == OMPC_linear) {
Alexey Bataev3732f4e2019-12-24 16:02:58 -0500752 assert(0 <= Data.ExtraModifier &&
753 Data.ExtraModifier <= OMPC_LINEAR_unknown &&
754 "Unexpected linear modifier.");
Alexey Bataev93dc40d2019-12-20 11:04:57 -0500755 if (P.getActions().CheckOpenMPLinearModifier(
756 static_cast<OpenMPLinearClauseKind>(Data.ExtraModifier),
757 Data.DepLinMapLastLoc))
758 Data.ExtraModifier = OMPC_LINEAR_val;
Alexey Bataevecba70f2016-04-12 11:02:11 +0000759 LinModifiers.append(Linears.size() - LinModifiers.size(),
Alexey Bataev93dc40d2019-12-20 11:04:57 -0500760 Data.ExtraModifier);
Alexey Bataevecba70f2016-04-12 11:02:11 +0000761 Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
762 }
Alexey Bataevd93d3762016-04-12 09:35:56 +0000763 } else
764 // TODO: add parsing of other clauses.
765 break;
766 }
767 // Skip ',' if any.
768 if (Tok.is(tok::comma))
769 P.ConsumeToken();
770 }
771 return IsError;
772}
773
Alexey Bataev2af33e32016-04-07 12:45:37 +0000774/// Parse clauses for '#pragma omp declare simd'.
775Parser::DeclGroupPtrTy
776Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
777 CachedTokens &Toks, SourceLocation Loc) {
Ilya Biryukov929af672019-05-17 09:32:05 +0000778 PP.EnterToken(Tok, /*IsReinject*/ true);
779 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
780 /*IsReinject*/ true);
Alexey Bataev2af33e32016-04-07 12:45:37 +0000781 // Consume the previously pushed token.
782 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
Alexey Bataevd158cf62019-09-13 20:18:17 +0000783 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
Alexey Bataev2af33e32016-04-07 12:45:37 +0000784
785 FNContextRAII FnContext(*this, Ptr);
786 OMPDeclareSimdDeclAttr::BranchStateTy BS =
787 OMPDeclareSimdDeclAttr::BS_Undefined;
788 ExprResult Simdlen;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +0000789 SmallVector<Expr *, 4> Uniforms;
Alexey Bataevd93d3762016-04-12 09:35:56 +0000790 SmallVector<Expr *, 4> Aligneds;
791 SmallVector<Expr *, 4> Alignments;
Alexey Bataevecba70f2016-04-12 11:02:11 +0000792 SmallVector<Expr *, 4> Linears;
793 SmallVector<unsigned, 4> LinModifiers;
794 SmallVector<Expr *, 4> Steps;
795 bool IsError =
796 parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
797 Alignments, Linears, LinModifiers, Steps);
Alexey Bataev2af33e32016-04-07 12:45:37 +0000798 // Need to check for extra tokens.
799 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
800 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
801 << getOpenMPDirectiveName(OMPD_declare_simd);
802 while (Tok.isNot(tok::annot_pragma_openmp_end))
803 ConsumeAnyToken();
804 }
805 // Skip the last annot_pragma_openmp_end.
Richard Smithaf3b3252017-05-18 19:21:48 +0000806 SourceLocation EndLoc = ConsumeAnnotationToken();
Alexey Bataev61908f652018-04-23 19:53:05 +0000807 if (IsError)
808 return Ptr;
809 return Actions.ActOnOpenMPDeclareSimdDirective(
810 Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
811 LinModifiers, Steps, SourceRange(Loc, EndLoc));
Alexey Bataev20dfd772016-04-04 10:12:15 +0000812}
813
Johannes Doerfert1228d422019-12-19 20:42:12 -0600814namespace {
815/// Constant used in the diagnostics to distinguish the levels in an OpenMP
816/// contexts: selector-set={selector(trait, ...), ...}, ....
817enum OMPContextLvl {
818 CONTEXT_SELECTOR_SET_LVL = 0,
819 CONTEXT_SELECTOR_LVL = 1,
820 CONTEXT_TRAIT_LVL = 2,
821};
822
823static StringRef stringLiteralParser(Parser &P) {
824 ExprResult Res = P.ParseStringLiteralExpression(true);
825 return Res.isUsable() ? Res.getAs<StringLiteral>()->getString() : "";
826}
827
828static StringRef getNameFromIdOrString(Parser &P, Token &Tok,
829 OMPContextLvl Lvl) {
830 if (Tok.is(tok::identifier)) {
831 llvm::SmallString<16> Buffer;
832 StringRef Name = P.getPreprocessor().getSpelling(Tok, Buffer);
833 (void)P.ConsumeToken();
834 return Name;
835 }
836
837 if (tok::isStringLiteral(Tok.getKind()))
838 return stringLiteralParser(P);
839
840 P.Diag(Tok.getLocation(),
841 diag::warn_omp_declare_variant_string_literal_or_identifier)
842 << Lvl;
843 return "";
844}
845
846static bool checkForDuplicates(Parser &P, StringRef Name,
847 SourceLocation NameLoc,
848 llvm::StringMap<SourceLocation> &Seen,
849 OMPContextLvl Lvl) {
850 auto Res = Seen.try_emplace(Name, NameLoc);
851 if (Res.second)
852 return false;
853
854 // Each trait-set-selector-name, trait-selector-name and trait-name can
855 // only be specified once.
856 P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
857 << Lvl << Name;
858 P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
859 << Lvl << Name;
860 return true;
861}
862} // namespace
863
864void Parser::parseOMPTraitPropertyKind(
865 OMPTraitInfo::OMPTraitProperty &TIProperty, llvm::omp::TraitSet Set,
866 llvm::omp::TraitSelector Selector, llvm::StringMap<SourceLocation> &Seen) {
867 TIProperty.Kind = TraitProperty::invalid;
868
869 SourceLocation NameLoc = Tok.getLocation();
870 StringRef Name =
871 getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
872 if (Name.empty()) {
873 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
874 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
875 return;
876 }
877
878 TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Name);
879 if (TIProperty.Kind != TraitProperty::invalid) {
880 if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
881 TIProperty.Kind = TraitProperty::invalid;
882 return;
883 }
884
885 // It follows diagnosis and helping notes.
886 // FIXME: We should move the diagnosis string generation into libFrontend.
887 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
888 << Name << getOpenMPContextTraitSelectorName(Selector)
889 << getOpenMPContextTraitSetName(Set);
890
891 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
892 if (SetForName != TraitSet::invalid) {
893 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
894 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
895 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
896 << Name << "<selector-name>"
897 << "(<property-name>)";
898 return;
899 }
900 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
901 if (SelectorForName != TraitSelector::invalid) {
902 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
903 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
904 bool AllowsTraitScore = false;
905 bool RequiresProperty = false;
906 isValidTraitSelectorForTraitSet(
907 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
908 AllowsTraitScore, RequiresProperty);
909 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
910 << getOpenMPContextTraitSetName(
911 getOpenMPContextTraitSetForSelector(SelectorForName))
912 << Name << (RequiresProperty ? "(<property-name>)" : "");
913 return;
914 }
915 for (const auto &PotentialSet :
916 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
917 TraitSet::device}) {
918 TraitProperty PropertyForName =
919 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
920 if (PropertyForName == TraitProperty::invalid)
921 continue;
922 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
923 << getOpenMPContextTraitSetName(
924 getOpenMPContextTraitSetForProperty(PropertyForName))
925 << getOpenMPContextTraitSelectorName(
926 getOpenMPContextTraitSelectorForProperty(PropertyForName))
927 << ("(" + Name + ")").str();
928 return;
929 }
930 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
931 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
932}
933
934void Parser::parseOMPContextProperty(OMPTraitInfo::OMPTraitSelector &TISelector,
935 llvm::omp::TraitSet Set,
936 llvm::StringMap<SourceLocation> &Seen) {
937 assert(TISelector.Kind != TraitSelector::user_condition &&
938 "User conditions are special properties not handled here!");
939
940 SourceLocation PropertyLoc = Tok.getLocation();
941 OMPTraitInfo::OMPTraitProperty TIProperty;
942 parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen);
943
944 // If we have an invalid property here we already issued a warning.
945 if (TIProperty.Kind == TraitProperty::invalid) {
946 if (PropertyLoc != Tok.getLocation())
947 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
948 << CONTEXT_TRAIT_LVL;
949 return;
950 }
951
952 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind,
953 TISelector.Kind, Set)) {
954 // If we make it here the property, selector, set, score, condition, ... are
955 // all valid (or have been corrected). Thus we can record the property.
956 TISelector.Properties.push_back(TIProperty);
957 return;
958 }
959
960 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
961 << getOpenMPContextTraitPropertyName(TIProperty.Kind)
962 << getOpenMPContextTraitSelectorName(TISelector.Kind)
963 << getOpenMPContextTraitSetName(Set);
964 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
965 << getOpenMPContextTraitPropertyName(TIProperty.Kind)
966 << getOpenMPContextTraitSelectorName(
967 getOpenMPContextTraitSelectorForProperty(TIProperty.Kind))
968 << getOpenMPContextTraitSetName(
969 getOpenMPContextTraitSetForProperty(TIProperty.Kind));
970 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
971 << CONTEXT_TRAIT_LVL;
972}
973
974void Parser::parseOMPTraitSelectorKind(
975 OMPTraitInfo::OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
976 llvm::StringMap<SourceLocation> &Seen) {
977 TISelector.Kind = TraitSelector::invalid;
978
979 SourceLocation NameLoc = Tok.getLocation();
980 StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_LVL
981 );
982 if (Name.empty()) {
983 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
984 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
985 return;
986 }
987
988 TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
989 if (TISelector.Kind != TraitSelector::invalid) {
990 if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
991 TISelector.Kind = TraitSelector::invalid;
992 return;
993 }
994
995 // It follows diagnosis and helping notes.
996 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
997 << Name << getOpenMPContextTraitSetName(Set);
998
999 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1000 if (SetForName != TraitSet::invalid) {
1001 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1002 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1003 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1004 << Name << "<selector-name>"
1005 << "<property-name>";
1006 return;
1007 }
1008 for (const auto &PotentialSet :
1009 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1010 TraitSet::device}) {
1011 TraitProperty PropertyForName =
1012 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
1013 if (PropertyForName == TraitProperty::invalid)
1014 continue;
1015 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1016 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1017 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1018 << getOpenMPContextTraitSetName(
1019 getOpenMPContextTraitSetForProperty(PropertyForName))
1020 << getOpenMPContextTraitSelectorName(
1021 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1022 << ("(" + Name + ")").str();
1023 return;
1024 }
1025 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1026 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1027}
1028
Alexey Bataeva15a1412019-10-02 18:19:02 +00001029/// Parse optional 'score' '(' <expr> ')' ':'.
1030static ExprResult parseContextScore(Parser &P) {
1031 ExprResult ScoreExpr;
Johannes Doerfert1228d422019-12-19 20:42:12 -06001032 llvm::SmallString<16> Buffer;
Alexey Bataeva15a1412019-10-02 18:19:02 +00001033 StringRef SelectorName =
1034 P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
Alexey Bataevdcec2ac2019-11-05 15:33:18 -05001035 if (!SelectorName.equals("score"))
Alexey Bataeva15a1412019-10-02 18:19:02 +00001036 return ScoreExpr;
Alexey Bataeva15a1412019-10-02 18:19:02 +00001037 (void)P.ConsumeToken();
1038 SourceLocation RLoc;
1039 ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
1040 // Parse ':'
1041 if (P.getCurToken().is(tok::colon))
1042 (void)P.ConsumeAnyToken();
1043 else
Johannes Doerfert1228d422019-12-19 20:42:12 -06001044 P.Diag(P.getCurToken(), diag::warn_omp_declare_variant_expected)
1045 << "':'"
1046 << "score expression";
Alexey Bataeva15a1412019-10-02 18:19:02 +00001047 return ScoreExpr;
1048}
1049
Johannes Doerfert1228d422019-12-19 20:42:12 -06001050/// Parses an OpenMP context selector.
1051///
1052/// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
1053void Parser::parseOMPContextSelector(
1054 OMPTraitInfo::OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1055 llvm::StringMap<SourceLocation> &SeenSelectors) {
1056 unsigned short OuterPC = ParenCount;
Alexey Bataev9ff34742019-09-25 19:43:37 +00001057
Johannes Doerfert1228d422019-12-19 20:42:12 -06001058 // If anything went wrong we issue an error or warning and then skip the rest
1059 // of the selector. However, commas are ambiguous so we look for the nesting
1060 // of parentheses here as well.
1061 auto FinishSelector = [OuterPC, this]() -> void {
1062 bool Done = false;
1063 while (!Done) {
1064 while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1065 tok::annot_pragma_openmp_end},
1066 StopBeforeMatch))
1067 ;
1068 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1069 (void)ConsumeParen();
1070 if (OuterPC <= ParenCount) {
1071 Done = true;
1072 break;
Alexey Bataev4e8231b2019-11-05 15:13:30 -05001073 }
Johannes Doerfert1228d422019-12-19 20:42:12 -06001074 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1075 Done = true;
1076 break;
Alexey Bataev4e8231b2019-11-05 15:13:30 -05001077 }
Johannes Doerfert1228d422019-12-19 20:42:12 -06001078 (void)ConsumeAnyToken();
1079 }
1080 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1081 << CONTEXT_SELECTOR_LVL;
1082 };
Alexey Bataev4e8231b2019-11-05 15:13:30 -05001083
Johannes Doerfert1228d422019-12-19 20:42:12 -06001084 SourceLocation SelectorLoc = Tok.getLocation();
1085 parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1086 if (TISelector.Kind == TraitSelector::invalid)
1087 return FinishSelector();
1088
1089 bool AllowsTraitScore = false;
1090 bool RequiresProperty = false;
1091 if (!isValidTraitSelectorForTraitSet(TISelector.Kind, Set, AllowsTraitScore,
1092 RequiresProperty)) {
1093 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1094 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1095 << getOpenMPContextTraitSetName(Set);
1096 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1097 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1098 << getOpenMPContextTraitSetName(
1099 getOpenMPContextTraitSetForSelector(TISelector.Kind))
1100 << RequiresProperty;
1101 return FinishSelector();
1102 }
1103
1104 if (!RequiresProperty) {
1105 TISelector.Properties.push_back(
1106 {getOpenMPContextTraitPropertyForSelector(TISelector.Kind)});
1107 return;
1108 }
1109
1110 if (!Tok.is(tok::l_paren)) {
1111 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1112 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1113 << getOpenMPContextTraitSetName(Set);
1114 return FinishSelector();
1115 }
1116
1117 if (TISelector.Kind == TraitSelector::user_condition) {
1118 SourceLocation RLoc;
1119 ExprResult Condition = ParseOpenMPParensExpr("user condition", RLoc);
1120 if (!Condition.isUsable())
1121 return FinishSelector();
1122 TISelector.ScoreOrCondition = Condition.get();
1123 TISelector.Properties.push_back({TraitProperty::user_condition_unknown});
1124 return;
1125 }
1126
1127 BalancedDelimiterTracker BDT(*this, tok::l_paren,
1128 tok::annot_pragma_openmp_end);
1129 // Parse '('.
1130 (void)BDT.consumeOpen();
1131
1132 ExprResult Score = parseContextScore(*this);
1133
1134 if (!AllowsTraitScore && Score.isUsable()) {
1135 Diag(Score.get()->getBeginLoc(),
1136 diag::warn_omp_ctx_incompatible_score_for_property)
1137 << getOpenMPContextTraitSelectorName(TISelector.Kind)
1138 << getOpenMPContextTraitSetName(Set) << Score.get();
1139 Score = ExprResult();
1140 }
1141
1142 if (Score.isUsable())
1143 TISelector.ScoreOrCondition = Score.get();
1144
1145 llvm::StringMap<SourceLocation> SeenProperties;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001146 do {
Johannes Doerfert1228d422019-12-19 20:42:12 -06001147 parseOMPContextProperty(TISelector, Set, SeenProperties);
1148 } while (TryConsumeToken(tok::comma));
1149
1150 // Parse ')'.
1151 BDT.consumeClose();
1152}
1153
1154void Parser::parseOMPTraitSetKind(OMPTraitInfo::OMPTraitSet &TISet,
1155 llvm::StringMap<SourceLocation> &Seen) {
1156 TISet.Kind = TraitSet::invalid;
1157
1158 SourceLocation NameLoc = Tok.getLocation();
1159 StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_SET_LVL
1160 );
1161 if (Name.empty()) {
1162 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1163 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1164 return;
1165 }
1166
1167 TISet.Kind = getOpenMPContextTraitSetKind(Name);
1168 if (TISet.Kind != TraitSet::invalid) {
1169 if (checkForDuplicates(*this, Name, NameLoc, Seen,
1170 CONTEXT_SELECTOR_SET_LVL))
1171 TISet.Kind = TraitSet::invalid;
1172 return;
1173 }
1174
1175 // It follows diagnosis and helping notes.
1176 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1177
1178 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1179 if (SelectorForName != TraitSelector::invalid) {
1180 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1181 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1182 bool AllowsTraitScore = false;
1183 bool RequiresProperty = false;
1184 isValidTraitSelectorForTraitSet(
1185 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1186 AllowsTraitScore, RequiresProperty);
1187 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1188 << getOpenMPContextTraitSetName(
1189 getOpenMPContextTraitSetForSelector(SelectorForName))
1190 << Name << (RequiresProperty ? "(<property-name>)" : "");
1191 return;
1192 }
1193 for (const auto &PotentialSet :
1194 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1195 TraitSet::device}) {
1196 TraitProperty PropertyForName =
1197 getOpenMPContextTraitPropertyKind(PotentialSet, Name);
1198 if (PropertyForName == TraitProperty::invalid)
1199 continue;
1200 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1201 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1202 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1203 << getOpenMPContextTraitSetName(
1204 getOpenMPContextTraitSetForProperty(PropertyForName))
1205 << getOpenMPContextTraitSelectorName(
1206 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1207 << ("(" + Name + ")").str();
1208 return;
1209 }
1210 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1211 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1212}
1213
1214/// Parses an OpenMP context selector set.
1215///
1216/// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
1217void Parser::parseOMPContextSelectorSet(
1218 OMPTraitInfo::OMPTraitSet &TISet,
1219 llvm::StringMap<SourceLocation> &SeenSets) {
1220 auto OuterBC = BraceCount;
1221
1222 // If anything went wrong we issue an error or warning and then skip the rest
1223 // of the set. However, commas are ambiguous so we look for the nesting
1224 // of braces here as well.
1225 auto FinishSelectorSet = [this, OuterBC]() -> void {
1226 bool Done = false;
1227 while (!Done) {
1228 while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1229 tok::annot_pragma_openmp_end},
1230 StopBeforeMatch))
1231 ;
1232 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1233 (void)ConsumeBrace();
1234 if (OuterBC <= BraceCount) {
1235 Done = true;
1236 break;
1237 }
1238 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1239 Done = true;
1240 break;
1241 }
1242 (void)ConsumeAnyToken();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001243 }
Johannes Doerfert1228d422019-12-19 20:42:12 -06001244 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1245 << CONTEXT_SELECTOR_SET_LVL;
1246 };
1247
1248 parseOMPTraitSetKind(TISet, SeenSets);
1249 if (TISet.Kind == TraitSet::invalid)
1250 return FinishSelectorSet();
1251
1252 // Parse '='.
1253 if (!TryConsumeToken(tok::equal))
1254 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1255 << "="
1256 << ("context set name \"" + getOpenMPContextTraitSetName(TISet.Kind) +
1257 "\"")
1258 .str();
1259
1260 // Parse '{'.
1261 if (Tok.is(tok::l_brace)) {
1262 (void)ConsumeBrace();
1263 } else {
1264 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1265 << "{"
1266 << ("'=' that follows the context set name \"" +
1267 getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1268 .str();
1269 }
1270
1271 llvm::StringMap<SourceLocation> SeenSelectors;
1272 do {
1273 OMPTraitInfo::OMPTraitSelector TISelector;
1274 parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors);
1275 if (TISelector.Kind != TraitSelector::invalid &&
1276 !TISelector.Properties.empty())
1277 TISet.Selectors.push_back(TISelector);
1278 } while (TryConsumeToken(tok::comma));
1279
1280 // Parse '}'.
1281 if (Tok.is(tok::r_brace)) {
1282 (void)ConsumeBrace();
1283 } else {
1284 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1285 << "}"
1286 << ("context selectors for the context set \"" +
1287 getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1288 .str();
1289 }
1290}
1291
1292/// Parse OpenMP context selectors:
1293///
1294/// <trait-set-selector> [, <trait-set-selector>]*
1295bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) {
1296 llvm::StringMap<SourceLocation> SeenSets;
1297 do {
1298 OMPTraitInfo::OMPTraitSet TISet;
1299 parseOMPContextSelectorSet(TISet, SeenSets);
1300 if (TISet.Kind != TraitSet::invalid && !TISet.Selectors.empty())
1301 TI.Sets.push_back(TISet);
1302 } while (TryConsumeToken(tok::comma));
1303
Alexey Bataevd158cf62019-09-13 20:18:17 +00001304 return false;
1305}
1306
1307/// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001308void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
1309 CachedTokens &Toks,
1310 SourceLocation Loc) {
Alexey Bataevd158cf62019-09-13 20:18:17 +00001311 PP.EnterToken(Tok, /*IsReinject*/ true);
1312 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1313 /*IsReinject*/ true);
1314 // Consume the previously pushed token.
1315 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1316 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1317
1318 FNContextRAII FnContext(*this, Ptr);
1319 // Parse function declaration id.
1320 SourceLocation RLoc;
1321 // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs
1322 // instead of MemberExprs.
Alexey Bataev02d04d52019-12-10 16:12:53 -05001323 ExprResult AssociatedFunction;
1324 {
1325 // Do not mark function as is used to prevent its emission if this is the
1326 // only place where it is used.
1327 EnterExpressionEvaluationContext Unevaluated(
1328 Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1329 AssociatedFunction = ParseOpenMPParensExpr(
1330 getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1331 /*IsAddressOfOperand=*/true);
1332 }
Alexey Bataevd158cf62019-09-13 20:18:17 +00001333 if (!AssociatedFunction.isUsable()) {
1334 if (!Tok.is(tok::annot_pragma_openmp_end))
1335 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1336 ;
1337 // Skip the last annot_pragma_openmp_end.
1338 (void)ConsumeAnnotationToken();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001339 return;
1340 }
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001341
1342 // Parse 'match'.
Alexey Bataevdba792c2019-09-23 18:13:31 +00001343 OpenMPClauseKind CKind = Tok.isAnnotation()
1344 ? OMPC_unknown
1345 : getOpenMPClauseKind(PP.getSpelling(Tok));
1346 if (CKind != OMPC_match) {
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001347 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
Alexey Bataevdba792c2019-09-23 18:13:31 +00001348 << getOpenMPClauseName(OMPC_match);
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001349 while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
1350 ;
1351 // Skip the last annot_pragma_openmp_end.
1352 (void)ConsumeAnnotationToken();
1353 return;
1354 }
1355 (void)ConsumeToken();
1356 // Parse '('.
1357 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Alexey Bataevdba792c2019-09-23 18:13:31 +00001358 if (T.expectAndConsume(diag::err_expected_lparen_after,
1359 getOpenMPClauseName(OMPC_match))) {
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001360 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1361 ;
1362 // Skip the last annot_pragma_openmp_end.
1363 (void)ConsumeAnnotationToken();
1364 return;
Alexey Bataevd158cf62019-09-13 20:18:17 +00001365 }
1366
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001367 // Parse inner context selectors.
Johannes Doerfertb86bf832020-02-15 18:07:42 -06001368 OMPTraitInfo TI;
1369 parseOMPContextSelectors(Loc, TI);
Johannes Doerfert1228d422019-12-19 20:42:12 -06001370
1371 // Parse ')'
1372 (void)T.consumeClose();
1373
1374 Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1375 Actions.checkOpenMPDeclareVariantFunction(
Johannes Doerfertb86bf832020-02-15 18:07:42 -06001376 Ptr, AssociatedFunction.get(), TI,
Johannes Doerfert1228d422019-12-19 20:42:12 -06001377 SourceRange(Loc, Tok.getLocation()));
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001378
1379 // Skip last tokens.
1380 while (Tok.isNot(tok::annot_pragma_openmp_end))
1381 ConsumeAnyToken();
Johannes Doerfertb86bf832020-02-15 18:07:42 -06001382 if (DeclVarData.hasValue() && !TI.Sets.empty())
Alexey Bataevfde11e92019-11-07 11:03:10 -05001383 Actions.ActOnOpenMPDeclareVariantDirective(
Johannes Doerfert1228d422019-12-19 20:42:12 -06001384 DeclVarData.getValue().first, DeclVarData.getValue().second, TI,
1385 SourceRange(Loc, Tok.getLocation()));
Johannes Doerfert1228d422019-12-19 20:42:12 -06001386
Alexey Bataevd158cf62019-09-13 20:18:17 +00001387 // Skip the last annot_pragma_openmp_end.
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001388 (void)ConsumeAnnotationToken();
Alexey Bataevd158cf62019-09-13 20:18:17 +00001389}
1390
Alexey Bataev729e2422019-08-23 16:11:14 +00001391/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1392///
1393/// default-clause:
1394/// 'default' '(' 'none' | 'shared' ')
1395///
1396/// proc_bind-clause:
1397/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
1398///
1399/// device_type-clause:
1400/// 'device_type' '(' 'host' | 'nohost' | 'any' )'
1401namespace {
1402 struct SimpleClauseData {
1403 unsigned Type;
1404 SourceLocation Loc;
1405 SourceLocation LOpen;
1406 SourceLocation TypeLoc;
1407 SourceLocation RLoc;
1408 SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1409 SourceLocation TypeLoc, SourceLocation RLoc)
1410 : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1411 };
1412} // anonymous namespace
1413
1414static Optional<SimpleClauseData>
1415parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) {
1416 const Token &Tok = P.getCurToken();
1417 SourceLocation Loc = Tok.getLocation();
1418 SourceLocation LOpen = P.ConsumeToken();
1419 // Parse '('.
1420 BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
1421 if (T.expectAndConsume(diag::err_expected_lparen_after,
1422 getOpenMPClauseName(Kind)))
1423 return llvm::None;
1424
1425 unsigned Type = getOpenMPSimpleClauseType(
1426 Kind, Tok.isAnnotation() ? "" : P.getPreprocessor().getSpelling(Tok));
1427 SourceLocation TypeLoc = Tok.getLocation();
1428 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1429 Tok.isNot(tok::annot_pragma_openmp_end))
1430 P.ConsumeAnyToken();
1431
1432 // Parse ')'.
1433 SourceLocation RLoc = Tok.getLocation();
1434 if (!T.consumeClose())
1435 RLoc = T.getCloseLocation();
1436
1437 return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc);
1438}
1439
Kelvin Lie0502752018-11-21 20:15:57 +00001440Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
1441 // OpenMP 4.5 syntax with list of entities.
1442 Sema::NamedDeclSetType SameDirectiveDecls;
Alexey Bataev729e2422019-08-23 16:11:14 +00001443 SmallVector<std::tuple<OMPDeclareTargetDeclAttr::MapTypeTy, SourceLocation,
1444 NamedDecl *>,
1445 4>
1446 DeclareTargetDecls;
1447 OMPDeclareTargetDeclAttr::DevTypeTy DT = OMPDeclareTargetDeclAttr::DT_Any;
1448 SourceLocation DeviceTypeLoc;
Kelvin Lie0502752018-11-21 20:15:57 +00001449 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1450 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1451 if (Tok.is(tok::identifier)) {
1452 IdentifierInfo *II = Tok.getIdentifierInfo();
1453 StringRef ClauseName = II->getName();
Alexey Bataev729e2422019-08-23 16:11:14 +00001454 bool IsDeviceTypeClause =
1455 getLangOpts().OpenMP >= 50 &&
1456 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1457 // Parse 'to|link|device_type' clauses.
1458 if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT) &&
1459 !IsDeviceTypeClause) {
1460 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1461 << ClauseName << (getLangOpts().OpenMP >= 50 ? 1 : 0);
Kelvin Lie0502752018-11-21 20:15:57 +00001462 break;
1463 }
Alexey Bataev729e2422019-08-23 16:11:14 +00001464 // Parse 'device_type' clause and go to next clause if any.
1465 if (IsDeviceTypeClause) {
1466 Optional<SimpleClauseData> DevTypeData =
1467 parseOpenMPSimpleClause(*this, OMPC_device_type);
1468 if (DevTypeData.hasValue()) {
1469 if (DeviceTypeLoc.isValid()) {
1470 // We already saw another device_type clause, diagnose it.
1471 Diag(DevTypeData.getValue().Loc,
1472 diag::warn_omp_more_one_device_type_clause);
1473 }
1474 switch(static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) {
1475 case OMPC_DEVICE_TYPE_any:
1476 DT = OMPDeclareTargetDeclAttr::DT_Any;
1477 break;
1478 case OMPC_DEVICE_TYPE_host:
1479 DT = OMPDeclareTargetDeclAttr::DT_Host;
1480 break;
1481 case OMPC_DEVICE_TYPE_nohost:
1482 DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1483 break;
1484 case OMPC_DEVICE_TYPE_unknown:
1485 llvm_unreachable("Unexpected device_type");
1486 }
1487 DeviceTypeLoc = DevTypeData.getValue().Loc;
1488 }
1489 continue;
1490 }
Kelvin Lie0502752018-11-21 20:15:57 +00001491 ConsumeToken();
1492 }
Alexey Bataev729e2422019-08-23 16:11:14 +00001493 auto &&Callback = [this, MT, &DeclareTargetDecls, &SameDirectiveDecls](
1494 CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
1495 NamedDecl *ND = Actions.lookupOpenMPDeclareTargetName(
1496 getCurScope(), SS, NameInfo, SameDirectiveDecls);
1497 if (ND)
1498 DeclareTargetDecls.emplace_back(MT, NameInfo.getLoc(), ND);
Kelvin Lie0502752018-11-21 20:15:57 +00001499 };
1500 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1501 /*AllowScopeSpecifier=*/true))
1502 break;
1503
1504 // Consume optional ','.
1505 if (Tok.is(tok::comma))
1506 ConsumeToken();
1507 }
1508 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1509 ConsumeAnyToken();
Alexey Bataev729e2422019-08-23 16:11:14 +00001510 for (auto &MTLocDecl : DeclareTargetDecls) {
1511 OMPDeclareTargetDeclAttr::MapTypeTy MT;
1512 SourceLocation Loc;
1513 NamedDecl *ND;
1514 std::tie(MT, Loc, ND) = MTLocDecl;
1515 // device_type clause is applied only to functions.
1516 Actions.ActOnOpenMPDeclareTargetName(
1517 ND, Loc, MT, isa<VarDecl>(ND) ? OMPDeclareTargetDeclAttr::DT_Any : DT);
1518 }
Kelvin Lie0502752018-11-21 20:15:57 +00001519 SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
1520 SameDirectiveDecls.end());
1521 if (Decls.empty())
1522 return DeclGroupPtrTy();
1523 return Actions.BuildDeclaratorGroup(Decls);
1524}
1525
1526void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
1527 SourceLocation DTLoc) {
1528 if (DKind != OMPD_end_declare_target) {
1529 Diag(Tok, diag::err_expected_end_declare_target);
1530 Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
1531 return;
1532 }
1533 ConsumeAnyToken();
1534 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1535 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1536 << getOpenMPDirectiveName(OMPD_end_declare_target);
1537 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1538 }
1539 // Skip the last annot_pragma_openmp_end.
1540 ConsumeAnyToken();
1541}
1542
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001543/// Parsing of declarative OpenMP directives.
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001544///
1545/// threadprivate-directive:
1546/// annot_pragma_openmp 'threadprivate' simple-variable-list
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001547/// annot_pragma_openmp_end
Alexey Bataeva769e072013-03-22 06:34:35 +00001548///
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001549/// allocate-directive:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001550/// annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001551/// annot_pragma_openmp_end
1552///
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001553/// declare-reduction-directive:
1554/// annot_pragma_openmp 'declare' 'reduction' [...]
1555/// annot_pragma_openmp_end
1556///
Michael Kruse251e1482019-02-01 20:25:04 +00001557/// declare-mapper-directive:
1558/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1559/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
1560/// annot_pragma_openmp_end
1561///
Alexey Bataev587e1de2016-03-30 10:43:55 +00001562/// declare-simd-directive:
1563/// annot_pragma_openmp 'declare simd' {<clause> [,]}
1564/// annot_pragma_openmp_end
1565/// <function declaration/definition>
1566///
Kelvin Li1408f912018-09-26 04:28:39 +00001567/// requires directive:
1568/// annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
1569/// annot_pragma_openmp_end
1570///
Alexey Bataev587e1de2016-03-30 10:43:55 +00001571Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
Alexey Bataevc972f6f2020-01-07 13:39:18 -05001572 AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
Alexey Bataev587e1de2016-03-30 10:43:55 +00001573 DeclSpec::TST TagType, Decl *Tag) {
Alexey Bataeva769e072013-03-22 06:34:35 +00001574 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
Alexey Bataev8035bb42019-12-13 16:05:30 -05001575 ParsingOpenMPDirectiveRAII DirScope(*this);
Alexey Bataevee6507d2013-11-18 08:17:37 +00001576 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Alexey Bataeva769e072013-03-22 06:34:35 +00001577
Alexey Bataevc972f6f2020-01-07 13:39:18 -05001578 SourceLocation Loc;
1579 OpenMPDirectiveKind DKind;
1580 if (Delayed) {
1581 TentativeParsingAction TPA(*this);
1582 Loc = ConsumeAnnotationToken();
1583 DKind = parseOpenMPDirectiveKind(*this);
1584 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1585 // Need to delay parsing until completion of the parent class.
1586 TPA.Revert();
1587 CachedTokens Toks;
1588 unsigned Cnt = 1;
1589 Toks.push_back(Tok);
1590 while (Cnt && Tok.isNot(tok::eof)) {
1591 (void)ConsumeAnyToken();
1592 if (Tok.is(tok::annot_pragma_openmp))
1593 ++Cnt;
1594 else if (Tok.is(tok::annot_pragma_openmp_end))
1595 --Cnt;
1596 Toks.push_back(Tok);
1597 }
1598 // Skip last annot_pragma_openmp_end.
1599 if (Cnt == 0)
1600 (void)ConsumeAnyToken();
1601 auto *LP = new LateParsedPragma(this, AS);
1602 LP->takeToks(Toks);
1603 getCurrentClass().LateParsedDeclarations.push_back(LP);
1604 return nullptr;
1605 }
1606 TPA.Commit();
1607 } else {
1608 Loc = ConsumeAnnotationToken();
1609 DKind = parseOpenMPDirectiveKind(*this);
1610 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001611
1612 switch (DKind) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001613 case OMPD_threadprivate: {
Alexey Bataeva769e072013-03-22 06:34:35 +00001614 ConsumeToken();
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001615 DeclDirectiveListParserHelper Helper(this, DKind);
1616 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1617 /*AllowScopeSpecifier=*/true)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00001618 // The last seen token is annot_pragma_openmp_end - need to check for
1619 // extra tokens.
1620 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1621 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001622 << getOpenMPDirectiveName(DKind);
Alp Tokerd751fa72013-12-18 19:10:49 +00001623 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataeva769e072013-03-22 06:34:35 +00001624 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001625 // Skip the last annot_pragma_openmp_end.
Richard Smithaf3b3252017-05-18 19:21:48 +00001626 ConsumeAnnotationToken();
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001627 return Actions.ActOnOpenMPThreadprivateDirective(Loc,
1628 Helper.getIdentifiers());
Alexey Bataeva769e072013-03-22 06:34:35 +00001629 }
1630 break;
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001631 }
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001632 case OMPD_allocate: {
1633 ConsumeToken();
1634 DeclDirectiveListParserHelper Helper(this, DKind);
1635 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1636 /*AllowScopeSpecifier=*/true)) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001637 SmallVector<OMPClause *, 1> Clauses;
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001638 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001639 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1640 OMPC_unknown + 1>
1641 FirstClauses(OMPC_unknown + 1);
1642 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1643 OpenMPClauseKind CKind =
1644 Tok.isAnnotation() ? OMPC_unknown
1645 : getOpenMPClauseKind(PP.getSpelling(Tok));
1646 Actions.StartOpenMPClause(CKind);
1647 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
1648 !FirstClauses[CKind].getInt());
1649 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1650 StopBeforeMatch);
1651 FirstClauses[CKind].setInt(true);
1652 if (Clause != nullptr)
1653 Clauses.push_back(Clause);
1654 if (Tok.is(tok::annot_pragma_openmp_end)) {
1655 Actions.EndOpenMPClause();
1656 break;
1657 }
1658 // Skip ',' if any.
1659 if (Tok.is(tok::comma))
1660 ConsumeToken();
1661 Actions.EndOpenMPClause();
1662 }
1663 // The last seen token is annot_pragma_openmp_end - need to check for
1664 // extra tokens.
1665 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1666 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1667 << getOpenMPDirectiveName(DKind);
1668 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1669 }
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001670 }
1671 // Skip the last annot_pragma_openmp_end.
1672 ConsumeAnnotationToken();
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001673 return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
1674 Clauses);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001675 }
1676 break;
1677 }
Kelvin Li1408f912018-09-26 04:28:39 +00001678 case OMPD_requires: {
1679 SourceLocation StartLoc = ConsumeToken();
1680 SmallVector<OMPClause *, 5> Clauses;
1681 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
1682 FirstClauses(OMPC_unknown + 1);
1683 if (Tok.is(tok::annot_pragma_openmp_end)) {
Ilya Biryukovff2a9972019-02-26 11:01:50 +00001684 Diag(Tok, diag::err_omp_expected_clause)
Kelvin Li1408f912018-09-26 04:28:39 +00001685 << getOpenMPDirectiveName(OMPD_requires);
1686 break;
1687 }
1688 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1689 OpenMPClauseKind CKind = Tok.isAnnotation()
1690 ? OMPC_unknown
1691 : getOpenMPClauseKind(PP.getSpelling(Tok));
1692 Actions.StartOpenMPClause(CKind);
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001693 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
1694 !FirstClauses[CKind].getInt());
1695 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1696 StopBeforeMatch);
Kelvin Li1408f912018-09-26 04:28:39 +00001697 FirstClauses[CKind].setInt(true);
1698 if (Clause != nullptr)
1699 Clauses.push_back(Clause);
1700 if (Tok.is(tok::annot_pragma_openmp_end)) {
1701 Actions.EndOpenMPClause();
1702 break;
1703 }
1704 // Skip ',' if any.
1705 if (Tok.is(tok::comma))
1706 ConsumeToken();
1707 Actions.EndOpenMPClause();
1708 }
1709 // Consume final annot_pragma_openmp_end
Alexey Bataev2d4f80f2020-02-11 15:15:21 -05001710 if (Clauses.empty()) {
Kelvin Li1408f912018-09-26 04:28:39 +00001711 Diag(Tok, diag::err_omp_expected_clause)
1712 << getOpenMPDirectiveName(OMPD_requires);
1713 ConsumeAnnotationToken();
1714 return nullptr;
1715 }
1716 ConsumeAnnotationToken();
1717 return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
1718 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001719 case OMPD_declare_reduction:
1720 ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +00001721 if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001722 // The last seen token is annot_pragma_openmp_end - need to check for
1723 // extra tokens.
1724 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1725 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1726 << getOpenMPDirectiveName(OMPD_declare_reduction);
1727 while (Tok.isNot(tok::annot_pragma_openmp_end))
1728 ConsumeAnyToken();
1729 }
1730 // Skip the last annot_pragma_openmp_end.
Richard Smithaf3b3252017-05-18 19:21:48 +00001731 ConsumeAnnotationToken();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001732 return Res;
1733 }
1734 break;
Michael Kruse251e1482019-02-01 20:25:04 +00001735 case OMPD_declare_mapper: {
1736 ConsumeToken();
1737 if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1738 // Skip the last annot_pragma_openmp_end.
1739 ConsumeAnnotationToken();
1740 return Res;
1741 }
1742 break;
1743 }
Alexey Bataevd158cf62019-09-13 20:18:17 +00001744 case OMPD_declare_variant:
Alexey Bataev587e1de2016-03-30 10:43:55 +00001745 case OMPD_declare_simd: {
1746 // The syntax is:
Alexey Bataevd158cf62019-09-13 20:18:17 +00001747 // { #pragma omp declare {simd|variant} }
Alexey Bataev587e1de2016-03-30 10:43:55 +00001748 // <function-declaration-or-definition>
1749 //
Alexey Bataev2af33e32016-04-07 12:45:37 +00001750 CachedTokens Toks;
Alexey Bataevd158cf62019-09-13 20:18:17 +00001751 Toks.push_back(Tok);
1752 ConsumeToken();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00001753 while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1754 Toks.push_back(Tok);
1755 ConsumeAnyToken();
1756 }
1757 Toks.push_back(Tok);
1758 ConsumeAnyToken();
Alexey Bataev587e1de2016-03-30 10:43:55 +00001759
1760 DeclGroupPtrTy Ptr;
Alexey Bataev61908f652018-04-23 19:53:05 +00001761 if (Tok.is(tok::annot_pragma_openmp)) {
Alexey Bataevc972f6f2020-01-07 13:39:18 -05001762 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
1763 TagType, Tag);
Alexey Bataev61908f652018-04-23 19:53:05 +00001764 } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
Alexey Bataev587e1de2016-03-30 10:43:55 +00001765 // Here we expect to see some function declaration.
1766 if (AS == AS_none) {
1767 assert(TagType == DeclSpec::TST_unspecified);
1768 MaybeParseCXX11Attributes(Attrs);
Alexey Bataev587e1de2016-03-30 10:43:55 +00001769 ParsingDeclSpec PDS(*this);
1770 Ptr = ParseExternalDeclaration(Attrs, &PDS);
1771 } else {
1772 Ptr =
1773 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1774 }
1775 }
1776 if (!Ptr) {
Alexey Bataevd158cf62019-09-13 20:18:17 +00001777 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
1778 << (DKind == OMPD_declare_simd ? 0 : 1);
Alexey Bataev587e1de2016-03-30 10:43:55 +00001779 return DeclGroupPtrTy();
1780 }
Alexey Bataevd158cf62019-09-13 20:18:17 +00001781 if (DKind == OMPD_declare_simd)
1782 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1783 assert(DKind == OMPD_declare_variant &&
1784 "Expected declare variant directive only");
Alexey Bataev0736f7f2019-09-18 16:24:31 +00001785 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
1786 return Ptr;
Alexey Bataev587e1de2016-03-30 10:43:55 +00001787 }
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001788 case OMPD_declare_target: {
1789 SourceLocation DTLoc = ConsumeAnyToken();
1790 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Kelvin Lie0502752018-11-21 20:15:57 +00001791 return ParseOMPDeclareTargetClauses();
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001792 }
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001793
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001794 // Skip the last annot_pragma_openmp_end.
1795 ConsumeAnyToken();
1796
1797 if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1798 return DeclGroupPtrTy();
1799
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001800 llvm::SmallVector<Decl *, 4> Decls;
Alexey Bataev61908f652018-04-23 19:53:05 +00001801 DKind = parseOpenMPDirectiveKind(*this);
Kelvin Libc38e632018-09-10 02:07:09 +00001802 while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
1803 Tok.isNot(tok::r_brace)) {
Alexey Bataev502ec492017-10-03 20:00:00 +00001804 DeclGroupPtrTy Ptr;
1805 // Here we expect to see some function declaration.
1806 if (AS == AS_none) {
1807 assert(TagType == DeclSpec::TST_unspecified);
1808 MaybeParseCXX11Attributes(Attrs);
1809 ParsingDeclSpec PDS(*this);
1810 Ptr = ParseExternalDeclaration(Attrs, &PDS);
1811 } else {
1812 Ptr =
1813 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1814 }
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001815 if (Ptr) {
1816 DeclGroupRef Ref = Ptr.get();
1817 Decls.append(Ref.begin(), Ref.end());
1818 }
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001819 if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
1820 TentativeParsingAction TPA(*this);
Richard Smithaf3b3252017-05-18 19:21:48 +00001821 ConsumeAnnotationToken();
Alexey Bataev61908f652018-04-23 19:53:05 +00001822 DKind = parseOpenMPDirectiveKind(*this);
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001823 if (DKind != OMPD_end_declare_target)
1824 TPA.Revert();
1825 else
1826 TPA.Commit();
1827 }
1828 }
1829
Kelvin Lie0502752018-11-21 20:15:57 +00001830 ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001831 Actions.ActOnFinishOpenMPDeclareTargetDirective();
Alexey Bataev34f8a702018-03-28 14:28:54 +00001832 return Actions.BuildDeclaratorGroup(Decls);
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001833 }
Alexey Bataeva769e072013-03-22 06:34:35 +00001834 case OMPD_unknown:
1835 Diag(Tok, diag::err_omp_unknown_directive);
1836 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001837 case OMPD_parallel:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001838 case OMPD_simd:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001839 case OMPD_task:
Alexey Bataev68446b72014-07-18 07:47:19 +00001840 case OMPD_taskyield:
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001841 case OMPD_barrier:
Alexey Bataev2df347a2014-07-18 10:17:07 +00001842 case OMPD_taskwait:
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001843 case OMPD_taskgroup:
Alexey Bataev6125da92014-07-21 11:26:11 +00001844 case OMPD_flush:
Alexey Bataevc112e942020-02-28 09:52:15 -05001845 case OMPD_depobj:
Alexey Bataevf29276e2014-06-18 04:14:57 +00001846 case OMPD_for:
Alexander Musmanf82886e2014-09-18 05:12:34 +00001847 case OMPD_for_simd:
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001848 case OMPD_sections:
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001849 case OMPD_section:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001850 case OMPD_single:
Alexander Musman80c22892014-07-17 08:54:58 +00001851 case OMPD_master:
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001852 case OMPD_ordered:
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001853 case OMPD_critical:
Alexey Bataev4acb8592014-07-07 13:01:15 +00001854 case OMPD_parallel_for:
Alexander Musmane4e893b2014-09-23 09:33:00 +00001855 case OMPD_parallel_for_simd:
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001856 case OMPD_parallel_sections:
cchen47d60942019-12-05 13:43:48 -05001857 case OMPD_parallel_master:
Alexey Bataev0162e452014-07-22 10:10:35 +00001858 case OMPD_atomic:
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001859 case OMPD_target:
Alexey Bataev13314bf2014-10-09 04:18:56 +00001860 case OMPD_teams:
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001861 case OMPD_cancellation_point:
Alexey Bataev80909872015-07-02 11:25:17 +00001862 case OMPD_cancel:
Samuel Antao5b0688e2015-07-22 16:02:46 +00001863 case OMPD_target_data:
Samuel Antaodf67fc42016-01-19 19:15:56 +00001864 case OMPD_target_enter_data:
Samuel Antao72590762016-01-19 20:04:50 +00001865 case OMPD_target_exit_data:
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001866 case OMPD_target_parallel:
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00001867 case OMPD_target_parallel_for:
Alexey Bataev49f6e782015-12-01 04:18:41 +00001868 case OMPD_taskloop:
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001869 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +00001870 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00001871 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +00001872 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -04001873 case OMPD_parallel_master_taskloop_simd:
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001874 case OMPD_distribute:
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001875 case OMPD_end_declare_target:
Samuel Antao686c70c2016-05-26 17:30:50 +00001876 case OMPD_target_update:
Carlo Bertolli9925f152016-06-27 14:55:37 +00001877 case OMPD_distribute_parallel_for:
Kelvin Li4a39add2016-07-05 05:00:15 +00001878 case OMPD_distribute_parallel_for_simd:
Kelvin Li787f3fc2016-07-06 04:45:38 +00001879 case OMPD_distribute_simd:
Kelvin Lia579b912016-07-14 02:54:56 +00001880 case OMPD_target_parallel_for_simd:
Kelvin Li986330c2016-07-20 22:57:10 +00001881 case OMPD_target_simd:
Kelvin Li02532872016-08-05 14:37:37 +00001882 case OMPD_teams_distribute:
Kelvin Li4e325f72016-10-25 12:50:55 +00001883 case OMPD_teams_distribute_simd:
Kelvin Li579e41c2016-11-30 23:51:03 +00001884 case OMPD_teams_distribute_parallel_for_simd:
Kelvin Li7ade93f2016-12-09 03:24:30 +00001885 case OMPD_teams_distribute_parallel_for:
Kelvin Libf594a52016-12-17 05:48:59 +00001886 case OMPD_target_teams:
Kelvin Li83c451e2016-12-25 04:52:54 +00001887 case OMPD_target_teams_distribute:
Kelvin Li80e8f562016-12-29 22:16:30 +00001888 case OMPD_target_teams_distribute_parallel_for:
Kelvin Li1851df52017-01-03 05:23:48 +00001889 case OMPD_target_teams_distribute_parallel_for_simd:
Kelvin Lida681182017-01-10 18:08:18 +00001890 case OMPD_target_teams_distribute_simd:
Alexey Bataeva769e072013-03-22 06:34:35 +00001891 Diag(Tok, diag::err_omp_unexpected_directive)
Alexey Bataev96dae812018-02-16 18:36:44 +00001892 << 1 << getOpenMPDirectiveName(DKind);
Alexey Bataeva769e072013-03-22 06:34:35 +00001893 break;
1894 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001895 while (Tok.isNot(tok::annot_pragma_openmp_end))
1896 ConsumeAnyToken();
1897 ConsumeAnyToken();
David Blaikie0403cb12016-01-15 23:43:25 +00001898 return nullptr;
Alexey Bataeva769e072013-03-22 06:34:35 +00001899}
1900
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001901/// Parsing of declarative or executable OpenMP directives.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001902///
1903/// threadprivate-directive:
1904/// annot_pragma_openmp 'threadprivate' simple-variable-list
1905/// annot_pragma_openmp_end
1906///
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001907/// allocate-directive:
1908/// annot_pragma_openmp 'allocate' simple-variable-list
1909/// annot_pragma_openmp_end
1910///
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00001911/// declare-reduction-directive:
1912/// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
1913/// <type> {',' <type>} ':' <expression> ')' ['initializer' '('
1914/// ('omp_priv' '=' <expression>|<function_call>) ')']
1915/// annot_pragma_openmp_end
1916///
Michael Kruse251e1482019-02-01 20:25:04 +00001917/// declare-mapper-directive:
1918/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1919/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
1920/// annot_pragma_openmp_end
1921///
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001922/// executable-directive:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001923/// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001924/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
cchen47d60942019-12-05 13:43:48 -05001925/// 'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
1926/// 'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
1927/// 'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
1928/// data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
1929/// 'master taskloop' | 'master taskloop simd' | 'parallel master
1930/// taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
1931/// enter data' | 'target exit data' | 'target parallel' | 'target
1932/// parallel for' | 'target update' | 'distribute parallel for' |
1933/// 'distribute paralle for simd' | 'distribute simd' | 'target parallel
1934/// for simd' | 'target simd' | 'teams distribute' | 'teams distribute
1935/// simd' | 'teams distribute parallel for simd' | 'teams distribute
1936/// parallel for' | 'target teams' | 'target teams distribute' | 'target
1937/// teams distribute parallel for' | 'target teams distribute parallel
1938/// for simd' | 'target teams distribute simd' {clause}
Alexey Bataev14a388f2019-10-25 10:27:13 -04001939/// annot_pragma_openmp_end
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001940///
Richard Smitha6e8d5e2019-02-15 00:27:53 +00001941StmtResult
1942Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001943 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
Alexey Bataev8035bb42019-12-13 16:05:30 -05001944 ParsingOpenMPDirectiveRAII DirScope(*this);
Alexey Bataevee6507d2013-11-18 08:17:37 +00001945 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946 SmallVector<OMPClause *, 5> Clauses;
Alexey Bataev4ca40ed2014-05-12 04:23:46 +00001947 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
Alexey Bataeva55ed262014-05-28 06:15:33 +00001948 FirstClauses(OMPC_unknown + 1);
Momchil Velikov57c681f2017-08-10 15:43:06 +00001949 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
1950 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
Richard Smithaf3b3252017-05-18 19:21:48 +00001951 SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
Alexey Bataev61908f652018-04-23 19:53:05 +00001952 OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001953 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001954 // Name of critical directive.
1955 DeclarationNameInfo DirName;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001956 StmtResult Directive = StmtError();
Alexey Bataev68446b72014-07-18 07:47:19 +00001957 bool HasAssociatedStatement = true;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001958
1959 switch (DKind) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001960 case OMPD_threadprivate: {
Richard Smitha6e8d5e2019-02-15 00:27:53 +00001961 // FIXME: Should this be permitted in C++?
1962 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1963 ParsedStmtContext()) {
Alexey Bataevc4fad652016-01-13 11:18:54 +00001964 Diag(Tok, diag::err_omp_immediate_directive)
1965 << getOpenMPDirectiveName(DKind) << 0;
1966 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001967 ConsumeToken();
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001968 DeclDirectiveListParserHelper Helper(this, DKind);
1969 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1970 /*AllowScopeSpecifier=*/false)) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001971 // The last seen token is annot_pragma_openmp_end - need to check for
1972 // extra tokens.
1973 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1974 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001975 << getOpenMPDirectiveName(DKind);
Alp Tokerd751fa72013-12-18 19:10:49 +00001976 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001977 }
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001978 DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1979 Loc, Helper.getIdentifiers());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001980 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1981 }
Alp Tokerd751fa72013-12-18 19:10:49 +00001982 SkipUntil(tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001983 break;
Dmitry Polukhind69b5052016-05-09 14:59:13 +00001984 }
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001985 case OMPD_allocate: {
1986 // FIXME: Should this be permitted in C++?
1987 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1988 ParsedStmtContext()) {
1989 Diag(Tok, diag::err_omp_immediate_directive)
1990 << getOpenMPDirectiveName(DKind) << 0;
1991 }
1992 ConsumeToken();
1993 DeclDirectiveListParserHelper Helper(this, DKind);
1994 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1995 /*AllowScopeSpecifier=*/false)) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001996 SmallVector<OMPClause *, 1> Clauses;
Alexey Bataev25ed0c02019-03-07 17:54:44 +00001997 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00001998 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1999 OMPC_unknown + 1>
2000 FirstClauses(OMPC_unknown + 1);
2001 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2002 OpenMPClauseKind CKind =
2003 Tok.isAnnotation() ? OMPC_unknown
2004 : getOpenMPClauseKind(PP.getSpelling(Tok));
2005 Actions.StartOpenMPClause(CKind);
2006 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2007 !FirstClauses[CKind].getInt());
2008 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2009 StopBeforeMatch);
2010 FirstClauses[CKind].setInt(true);
2011 if (Clause != nullptr)
2012 Clauses.push_back(Clause);
2013 if (Tok.is(tok::annot_pragma_openmp_end)) {
2014 Actions.EndOpenMPClause();
2015 break;
2016 }
2017 // Skip ',' if any.
2018 if (Tok.is(tok::comma))
2019 ConsumeToken();
2020 Actions.EndOpenMPClause();
2021 }
2022 // The last seen token is annot_pragma_openmp_end - need to check for
2023 // extra tokens.
2024 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2025 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
2026 << getOpenMPDirectiveName(DKind);
2027 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
2028 }
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002029 }
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002030 DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2031 Loc, Helper.getIdentifiers(), Clauses);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002032 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2033 }
2034 SkipUntil(tok::annot_pragma_openmp_end);
2035 break;
2036 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002037 case OMPD_declare_reduction:
2038 ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +00002039 if (DeclGroupPtrTy Res =
2040 ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002041 // The last seen token is annot_pragma_openmp_end - need to check for
2042 // extra tokens.
2043 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2044 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
2045 << getOpenMPDirectiveName(OMPD_declare_reduction);
2046 while (Tok.isNot(tok::annot_pragma_openmp_end))
2047 ConsumeAnyToken();
2048 }
2049 ConsumeAnyToken();
2050 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
Alexey Bataev61908f652018-04-23 19:53:05 +00002051 } else {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002052 SkipUntil(tok::annot_pragma_openmp_end);
Alexey Bataev61908f652018-04-23 19:53:05 +00002053 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00002054 break;
Michael Kruse251e1482019-02-01 20:25:04 +00002055 case OMPD_declare_mapper: {
2056 ConsumeToken();
2057 if (DeclGroupPtrTy Res =
2058 ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2059 // Skip the last annot_pragma_openmp_end.
2060 ConsumeAnnotationToken();
2061 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2062 } else {
2063 SkipUntil(tok::annot_pragma_openmp_end);
2064 }
2065 break;
2066 }
Alexey Bataev6125da92014-07-21 11:26:11 +00002067 case OMPD_flush:
Alexey Bataevc112e942020-02-28 09:52:15 -05002068 case OMPD_depobj:
Alexey Bataev68446b72014-07-18 07:47:19 +00002069 case OMPD_taskyield:
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002070 case OMPD_barrier:
Alexey Bataev2df347a2014-07-18 10:17:07 +00002071 case OMPD_taskwait:
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002072 case OMPD_cancellation_point:
Alexey Bataev80909872015-07-02 11:25:17 +00002073 case OMPD_cancel:
Samuel Antaodf67fc42016-01-19 19:15:56 +00002074 case OMPD_target_enter_data:
Samuel Antao72590762016-01-19 20:04:50 +00002075 case OMPD_target_exit_data:
Samuel Antao686c70c2016-05-26 17:30:50 +00002076 case OMPD_target_update:
Richard Smitha6e8d5e2019-02-15 00:27:53 +00002077 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2078 ParsedStmtContext()) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002079 Diag(Tok, diag::err_omp_immediate_directive)
Alexey Bataeveb482352015-12-18 05:05:56 +00002080 << getOpenMPDirectiveName(DKind) << 0;
Alexey Bataev68446b72014-07-18 07:47:19 +00002081 }
2082 HasAssociatedStatement = false;
Alexey Bataev6125da92014-07-21 11:26:11 +00002083 // Fall through for further analysis.
Galina Kistanova474f2ce2017-06-01 21:26:38 +00002084 LLVM_FALLTHROUGH;
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002085 case OMPD_parallel:
Alexey Bataevf29276e2014-06-18 04:14:57 +00002086 case OMPD_simd:
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002087 case OMPD_for:
Alexander Musmanf82886e2014-09-18 05:12:34 +00002088 case OMPD_for_simd:
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002089 case OMPD_sections:
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002090 case OMPD_single:
Alexey Bataev4acb8592014-07-07 13:01:15 +00002091 case OMPD_section:
Alexander Musman80c22892014-07-17 08:54:58 +00002092 case OMPD_master:
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002093 case OMPD_critical:
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002094 case OMPD_parallel_for:
Alexander Musmane4e893b2014-09-23 09:33:00 +00002095 case OMPD_parallel_for_simd:
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002096 case OMPD_parallel_sections:
cchen47d60942019-12-05 13:43:48 -05002097 case OMPD_parallel_master:
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002098 case OMPD_task:
Alexey Bataev0162e452014-07-22 10:10:35 +00002099 case OMPD_ordered:
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002100 case OMPD_atomic:
Alexey Bataev13314bf2014-10-09 04:18:56 +00002101 case OMPD_target:
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002102 case OMPD_teams:
Michael Wong65f367f2015-07-21 13:44:28 +00002103 case OMPD_taskgroup:
Alexey Bataev49f6e782015-12-01 04:18:41 +00002104 case OMPD_target_data:
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002105 case OMPD_target_parallel:
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002106 case OMPD_target_parallel_for:
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002107 case OMPD_taskloop:
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002108 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +00002109 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002110 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002111 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -04002112 case OMPD_parallel_master_taskloop_simd:
Carlo Bertolli9925f152016-06-27 14:55:37 +00002113 case OMPD_distribute:
Kelvin Li4a39add2016-07-05 05:00:15 +00002114 case OMPD_distribute_parallel_for:
Kelvin Li787f3fc2016-07-06 04:45:38 +00002115 case OMPD_distribute_parallel_for_simd:
Kelvin Lia579b912016-07-14 02:54:56 +00002116 case OMPD_distribute_simd:
Kelvin Li986330c2016-07-20 22:57:10 +00002117 case OMPD_target_parallel_for_simd:
Kelvin Li02532872016-08-05 14:37:37 +00002118 case OMPD_target_simd:
Kelvin Li4e325f72016-10-25 12:50:55 +00002119 case OMPD_teams_distribute:
Kelvin Li579e41c2016-11-30 23:51:03 +00002120 case OMPD_teams_distribute_simd:
Kelvin Li7ade93f2016-12-09 03:24:30 +00002121 case OMPD_teams_distribute_parallel_for_simd:
Kelvin Libf594a52016-12-17 05:48:59 +00002122 case OMPD_teams_distribute_parallel_for:
Kelvin Li83c451e2016-12-25 04:52:54 +00002123 case OMPD_target_teams:
Kelvin Li80e8f562016-12-29 22:16:30 +00002124 case OMPD_target_teams_distribute:
Kelvin Li1851df52017-01-03 05:23:48 +00002125 case OMPD_target_teams_distribute_parallel_for:
Kelvin Lida681182017-01-10 18:08:18 +00002126 case OMPD_target_teams_distribute_parallel_for_simd:
2127 case OMPD_target_teams_distribute_simd: {
Alexey Bataevc112e942020-02-28 09:52:15 -05002128 // Special processing for flush and depobj clauses.
2129 Token ImplicitTok;
2130 bool ImplicitClauseAllowed = false;
2131 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2132 ImplicitTok = Tok;
2133 ImplicitClauseAllowed = true;
2134 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002135 ConsumeToken();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002136 // Parse directive name of the 'critical' directive if any.
2137 if (DKind == OMPD_critical) {
2138 BalancedDelimiterTracker T(*this, tok::l_paren,
2139 tok::annot_pragma_openmp_end);
2140 if (!T.consumeOpen()) {
2141 if (Tok.isAnyIdentifier()) {
2142 DirName =
2143 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2144 ConsumeAnyToken();
2145 } else {
2146 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2147 }
2148 T.consumeClose();
2149 }
Alexey Bataev80909872015-07-02 11:25:17 +00002150 } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
Alexey Bataev61908f652018-04-23 19:53:05 +00002151 CancelRegion = parseOpenMPDirectiveKind(*this);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002152 if (Tok.isNot(tok::annot_pragma_openmp_end))
2153 ConsumeToken();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002154 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002155
Alexey Bataevf29276e2014-06-18 04:14:57 +00002156 if (isOpenMPLoopDirective(DKind))
2157 ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2158 if (isOpenMPSimdDirective(DKind))
2159 ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2160 ParseScope OMPDirectiveScope(this, ScopeFlags);
Alexey Bataevbae9a792014-06-27 10:37:06 +00002161 Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002162
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002163 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataevc112e942020-02-28 09:52:15 -05002164 bool HasImplicitClause = false;
2165 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2166 HasImplicitClause = true;
Alexey Bataevea9166b2020-02-06 16:30:23 -05002167 // Push copy of the current token back to stream to properly parse
Alexey Bataevc112e942020-02-28 09:52:15 -05002168 // pseudo-clause OMPFlushClause or OMPDepobjClause.
Alexey Bataevea9166b2020-02-06 16:30:23 -05002169 PP.EnterToken(Tok, /*IsReinject*/ true);
Alexey Bataevc112e942020-02-28 09:52:15 -05002170 PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
Alexey Bataevea9166b2020-02-06 16:30:23 -05002171 ConsumeAnyToken();
2172 }
Alexey Bataevc112e942020-02-28 09:52:15 -05002173 OpenMPClauseKind CKind = Tok.isAnnotation()
2174 ? OMPC_unknown
2175 : getOpenMPClauseKind(PP.getSpelling(Tok));
2176 if (HasImplicitClause) {
2177 assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2178 if (DKind == OMPD_flush) {
2179 CKind = OMPC_flush;
2180 } else {
2181 assert(DKind == OMPD_depobj &&
2182 "Expected flush or depobj directives.");
2183 CKind = OMPC_depobj;
2184 }
2185 }
2186 // No more implicit clauses allowed.
2187 ImplicitClauseAllowed = false;
Alexey Bataevaac108a2015-06-23 04:51:00 +00002188 Actions.StartOpenMPClause(CKind);
Alexey Bataevc112e942020-02-28 09:52:15 -05002189 HasImplicitClause = false;
Alexey Bataeva55ed262014-05-28 06:15:33 +00002190 OMPClause *Clause =
2191 ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002192 FirstClauses[CKind].setInt(true);
2193 if (Clause) {
2194 FirstClauses[CKind].setPointer(Clause);
2195 Clauses.push_back(Clause);
2196 }
2197
2198 // Skip ',' if any.
2199 if (Tok.is(tok::comma))
2200 ConsumeToken();
Alexey Bataevaac108a2015-06-23 04:51:00 +00002201 Actions.EndOpenMPClause();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002202 }
2203 // End location of the directive.
2204 EndLoc = Tok.getLocation();
2205 // Consume final annot_pragma_openmp_end.
Richard Smithaf3b3252017-05-18 19:21:48 +00002206 ConsumeAnnotationToken();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002207
Alexey Bataeveb482352015-12-18 05:05:56 +00002208 // OpenMP [2.13.8, ordered Construct, Syntax]
2209 // If the depend clause is specified, the ordered construct is a stand-alone
2210 // directive.
2211 if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
Richard Smitha6e8d5e2019-02-15 00:27:53 +00002212 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2213 ParsedStmtContext()) {
Alexey Bataeveb482352015-12-18 05:05:56 +00002214 Diag(Loc, diag::err_omp_immediate_directive)
2215 << getOpenMPDirectiveName(DKind) << 1
2216 << getOpenMPClauseName(OMPC_depend);
2217 }
2218 HasAssociatedStatement = false;
2219 }
2220
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002221 StmtResult AssociatedStmt;
Alexey Bataev68446b72014-07-18 07:47:19 +00002222 if (HasAssociatedStatement) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002223 // The body is a block scope like in Lambdas and Blocks.
Alexey Bataevbae9a792014-06-27 10:37:06 +00002224 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
Richard Smith6eb9b9e2018-02-03 00:44:57 +00002225 // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2226 // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2227 // should have at least one compound statement scope within it.
2228 AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00002229 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
Alexey Bataev7828b252017-11-21 17:08:48 +00002230 } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2231 DKind == OMPD_target_exit_data) {
Alexey Bataev7828b252017-11-21 17:08:48 +00002232 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
Richard Smith6eb9b9e2018-02-03 00:44:57 +00002233 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2234 Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2235 /*isStmtExpr=*/false));
Alexey Bataev7828b252017-11-21 17:08:48 +00002236 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002237 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002238 Directive = Actions.ActOnOpenMPExecutableDirective(
2239 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2240 EndLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002241
2242 // Exit scope.
Alexey Bataev758e55e2013-09-06 18:03:48 +00002243 Actions.EndOpenMPDSABlock(Directive.get());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002244 OMPDirectiveScope.Exit();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002245 break;
Alexey Bataeva55ed262014-05-28 06:15:33 +00002246 }
Alexey Bataev587e1de2016-03-30 10:43:55 +00002247 case OMPD_declare_simd:
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00002248 case OMPD_declare_target:
2249 case OMPD_end_declare_target:
Kelvin Li1408f912018-09-26 04:28:39 +00002250 case OMPD_requires:
Alexey Bataevd158cf62019-09-13 20:18:17 +00002251 case OMPD_declare_variant:
Alexey Bataev587e1de2016-03-30 10:43:55 +00002252 Diag(Tok, diag::err_omp_unexpected_directive)
Alexey Bataev96dae812018-02-16 18:36:44 +00002253 << 1 << getOpenMPDirectiveName(DKind);
Alexey Bataev587e1de2016-03-30 10:43:55 +00002254 SkipUntil(tok::annot_pragma_openmp_end);
2255 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002256 case OMPD_unknown:
2257 Diag(Tok, diag::err_omp_unknown_directive);
Alp Tokerd751fa72013-12-18 19:10:49 +00002258 SkipUntil(tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002259 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002260 }
2261 return Directive;
2262}
2263
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002264// Parses simple list:
2265// simple-variable-list:
2266// '(' id-expression {, id-expression} ')'
2267//
2268bool Parser::ParseOpenMPSimpleVarList(
2269 OpenMPDirectiveKind Kind,
2270 const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
2271 Callback,
2272 bool AllowScopeSpecifier) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002273 // Parse '('.
Alp Tokerd751fa72013-12-18 19:10:49 +00002274 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002275 if (T.expectAndConsume(diag::err_expected_lparen_after,
Johannes Doerferteb3e81f2019-11-04 22:00:49 -06002276 getOpenMPDirectiveName(Kind).data()))
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002277 return true;
2278 bool IsCorrect = true;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002279 bool NoIdentIsFound = true;
Alexey Bataeva769e072013-03-22 06:34:35 +00002280
2281 // Read tokens while ')' or annot_pragma_openmp_end is not found.
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002282 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002283 CXXScopeSpec SS;
Alexey Bataeva769e072013-03-22 06:34:35 +00002284 UnqualifiedId Name;
2285 // Read var name.
2286 Token PrevTok = Tok;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002287 NoIdentIsFound = false;
Alexey Bataeva769e072013-03-22 06:34:35 +00002288
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002289 if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
David Blaikieefdccaa2016-01-15 23:43:34 +00002290 ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002291 IsCorrect = false;
2292 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +00002293 StopBeforeMatch);
Richard Smith35845152017-02-07 01:37:30 +00002294 } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
Richard Smithc08b6932018-04-27 02:00:13 +00002295 nullptr, Name)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002296 IsCorrect = false;
2297 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +00002298 StopBeforeMatch);
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002299 } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2300 Tok.isNot(tok::annot_pragma_openmp_end)) {
2301 IsCorrect = false;
2302 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
Alp Tokerd751fa72013-12-18 19:10:49 +00002303 StopBeforeMatch);
Alp Tokerec543272013-12-24 09:48:30 +00002304 Diag(PrevTok.getLocation(), diag::err_expected)
2305 << tok::identifier
2306 << SourceRange(PrevTok.getLocation(), PrevTokLocation);
Alexey Bataeva769e072013-03-22 06:34:35 +00002307 } else {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002308 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
Alexey Bataeva769e072013-03-22 06:34:35 +00002309 }
2310 // Consume ','.
2311 if (Tok.is(tok::comma)) {
2312 ConsumeToken();
2313 }
Alexey Bataeva769e072013-03-22 06:34:35 +00002314 }
2315
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002316 if (NoIdentIsFound) {
Alp Tokerec543272013-12-24 09:48:30 +00002317 Diag(Tok, diag::err_expected) << tok::identifier;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002318 IsCorrect = false;
2319 }
2320
2321 // Parse ')'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002322 IsCorrect = !T.consumeClose() && IsCorrect;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002323
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002324 return !IsCorrect;
Alexey Bataeva769e072013-03-22 06:34:35 +00002325}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002326
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002327/// Parsing of OpenMP clauses.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002328///
2329/// clause:
Alexey Bataev3778b602014-07-17 07:32:53 +00002330/// if-clause | final-clause | num_threads-clause | safelen-clause |
2331/// default-clause | private-clause | firstprivate-clause | shared-clause
2332/// | linear-clause | aligned-clause | collapse-clause |
2333/// lastprivate-clause | reduction-clause | proc_bind-clause |
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002334/// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
Alexey Bataev67a4f222014-07-23 10:25:33 +00002335/// mergeable-clause | flush-clause | read-clause | write-clause |
Alexey Bataev66b15b52015-08-21 11:14:16 +00002336/// update-clause | capture-clause | seq_cst-clause | device-clause |
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002337/// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002338/// thread_limit-clause | priority-clause | grainsize-clause |
Samuel Antaoec172c62016-05-26 17:49:04 +00002339/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
Alexey Bataevfa312f32017-07-21 18:48:21 +00002340/// from-clause | is_device_ptr-clause | task_reduction-clause |
Alexey Bataevea9166b2020-02-06 16:30:23 -05002341/// in_reduction-clause | allocator-clause | allocate-clause |
Alexey Bataevc112e942020-02-28 09:52:15 -05002342/// acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
Alexey Bataev375437a2020-03-02 14:21:20 -05002343/// depobj-clause | destroy-clause
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002344///
2345OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
2346 OpenMPClauseKind CKind, bool FirstClause) {
Craig Topper161e4db2014-05-21 06:02:52 +00002347 OMPClause *Clause = nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002348 bool ErrorFound = false;
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002349 bool WrongDirective = false;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002350 // Check if clause is allowed for the given directive.
Alexey Bataevd08c0562019-11-19 12:07:54 -05002351 if (CKind != OMPC_unknown &&
2352 !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
Alexey Bataeva55ed262014-05-28 06:15:33 +00002353 Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
2354 << getOpenMPDirectiveName(DKind);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002355 ErrorFound = true;
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002356 WrongDirective = true;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002357 }
2358
2359 switch (CKind) {
Alexey Bataev3778b602014-07-17 07:32:53 +00002360 case OMPC_final:
Alexey Bataev568a8332014-03-06 06:15:19 +00002361 case OMPC_num_threads:
Alexey Bataev62c87d22014-03-21 04:51:18 +00002362 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +00002363 case OMPC_simdlen:
Alexander Musman8bd31e62014-05-27 15:12:19 +00002364 case OMPC_collapse:
Alexey Bataev10e775f2015-07-30 11:36:16 +00002365 case OMPC_ordered:
Michael Wonge710d542015-08-07 16:16:36 +00002366 case OMPC_device:
Kelvin Li099bb8c2015-11-24 20:50:12 +00002367 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002368 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +00002369 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002370 case OMPC_grainsize:
Alexey Bataev382967a2015-12-08 12:06:20 +00002371 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +00002372 case OMPC_hint:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002373 case OMPC_allocator:
Alexey Bataevc112e942020-02-28 09:52:15 -05002374 case OMPC_depobj:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002375 // OpenMP [2.5, Restrictions]
Alexey Bataev568a8332014-03-06 06:15:19 +00002376 // At most one num_threads clause can appear on the directive.
Alexey Bataev62c87d22014-03-21 04:51:18 +00002377 // OpenMP [2.8.1, simd construct, Restrictions]
Alexander Musman8bd31e62014-05-27 15:12:19 +00002378 // Only one safelen clause can appear on a simd directive.
Alexey Bataev66b15b52015-08-21 11:14:16 +00002379 // Only one simdlen clause can appear on a simd directive.
Alexander Musman8bd31e62014-05-27 15:12:19 +00002380 // Only one collapse clause can appear on a simd directive.
Michael Wonge710d542015-08-07 16:16:36 +00002381 // OpenMP [2.9.1, target data construct, Restrictions]
2382 // At most one device clause can appear on the directive.
Alexey Bataev3778b602014-07-17 07:32:53 +00002383 // OpenMP [2.11.1, task Construct, Restrictions]
2384 // At most one if clause can appear on the directive.
2385 // At most one final clause can appear on the directive.
Kelvin Li099bb8c2015-11-24 20:50:12 +00002386 // OpenMP [teams Construct, Restrictions]
2387 // At most one num_teams clause can appear on the directive.
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002388 // At most one thread_limit clause can appear on the directive.
Alexey Bataeva0569352015-12-01 10:17:31 +00002389 // OpenMP [2.9.1, task Construct, Restrictions]
2390 // At most one priority clause can appear on the directive.
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002391 // OpenMP [2.9.2, taskloop Construct, Restrictions]
2392 // At most one grainsize clause can appear on the directive.
Alexey Bataev382967a2015-12-08 12:06:20 +00002393 // OpenMP [2.9.2, taskloop Construct, Restrictions]
2394 // At most one num_tasks clause can appear on the directive.
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002395 // OpenMP [2.11.3, allocate Directive, Restrictions]
2396 // At most one allocator clause can appear on the directive.
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002397 if (!FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002398 Diag(Tok, diag::err_omp_more_one_clause)
2399 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +00002400 ErrorFound = true;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002401 }
2402
Alexey Bataev10e775f2015-07-30 11:36:16 +00002403 if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002404 Clause = ParseOpenMPClause(CKind, WrongDirective);
Alexey Bataev10e775f2015-07-30 11:36:16 +00002405 else
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002406 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002407 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002408 case OMPC_default:
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002409 case OMPC_proc_bind:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002410 case OMPC_atomic_default_mem_order:
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002411 case OMPC_order:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002412 // OpenMP [2.14.3.1, Restrictions]
2413 // Only a single default clause may be specified on a parallel, task or
2414 // teams directive.
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002415 // OpenMP [2.5, parallel Construct, Restrictions]
2416 // At most one proc_bind clause can appear on the directive.
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002417 // OpenMP [5.0, Requires directive, Restrictions]
2418 // At most one atomic_default_mem_order clause can appear
2419 // on the directive
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002420 if (!FirstClause && CKind != OMPC_order) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002421 Diag(Tok, diag::err_omp_more_one_clause)
2422 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +00002423 ErrorFound = true;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002424 }
2425
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002426 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002427 break;
Alexey Bataev56dafe82014-06-20 07:16:17 +00002428 case OMPC_schedule:
Carlo Bertollib4adf552016-01-15 18:50:31 +00002429 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002430 case OMPC_defaultmap:
Alexey Bataev56dafe82014-06-20 07:16:17 +00002431 // OpenMP [2.7.1, Restrictions, p. 3]
2432 // Only one schedule clause can appear on a loop directive.
cchene06f3e02019-11-15 13:02:06 -05002433 // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002434 // At most one defaultmap clause can appear on the directive.
cchene06f3e02019-11-15 13:02:06 -05002435 if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
2436 !FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002437 Diag(Tok, diag::err_omp_more_one_clause)
2438 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +00002439 ErrorFound = true;
Alexey Bataev56dafe82014-06-20 07:16:17 +00002440 }
Galina Kistanova474f2ce2017-06-01 21:26:38 +00002441 LLVM_FALLTHROUGH;
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002442 case OMPC_if:
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002443 Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002444 break;
Alexey Bataev236070f2014-06-20 11:19:47 +00002445 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002446 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002447 case OMPC_mergeable:
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002448 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +00002449 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +00002450 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +00002451 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002452 case OMPC_seq_cst:
Alexey Bataevea9166b2020-02-06 16:30:23 -05002453 case OMPC_acq_rel:
Alexey Bataev04a830f2020-02-10 14:30:39 -05002454 case OMPC_acquire:
Alexey Bataev95598342020-02-10 15:49:05 -05002455 case OMPC_release:
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002456 case OMPC_relaxed:
Alexey Bataev346265e2015-09-25 10:37:12 +00002457 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002458 case OMPC_simd:
Alexey Bataevb825de12015-12-07 10:51:44 +00002459 case OMPC_nogroup:
Kelvin Li1408f912018-09-26 04:28:39 +00002460 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +00002461 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002462 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002463 case OMPC_dynamic_allocators:
Alexey Bataev375437a2020-03-02 14:21:20 -05002464 case OMPC_destroy:
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002465 // OpenMP [2.7.1, Restrictions, p. 9]
2466 // Only one ordered clause can appear on a loop directive.
Alexey Bataev236070f2014-06-20 11:19:47 +00002467 // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
2468 // Only one nowait clause can appear on a for directive.
Kelvin Li1408f912018-09-26 04:28:39 +00002469 // OpenMP [5.0, Requires directive, Restrictions]
2470 // Each of the requires clauses can appear at most once on the directive.
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002471 if (!FirstClause) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002472 Diag(Tok, diag::err_omp_more_one_clause)
2473 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Alexey Bataevdea47612014-07-23 07:46:59 +00002474 ErrorFound = true;
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002475 }
2476
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002477 Clause = ParseOpenMPClause(CKind, WrongDirective);
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002478 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002479 case OMPC_private:
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002480 case OMPC_firstprivate:
Alexander Musman1bb328c2014-06-04 13:06:39 +00002481 case OMPC_lastprivate:
Alexey Bataev758e55e2013-09-06 18:03:48 +00002482 case OMPC_shared:
Alexey Bataevc5e02582014-06-16 07:08:35 +00002483 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +00002484 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +00002485 case OMPC_in_reduction:
Alexander Musman8dba6642014-04-22 13:09:42 +00002486 case OMPC_linear:
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002487 case OMPC_aligned:
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002488 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +00002489 case OMPC_copyprivate:
Alexey Bataev6125da92014-07-21 11:26:11 +00002490 case OMPC_flush:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002491 case OMPC_depend:
Kelvin Li0bff7af2015-11-23 05:32:03 +00002492 case OMPC_map:
Samuel Antao661c0902016-05-26 17:39:58 +00002493 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +00002494 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +00002495 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +00002496 case OMPC_is_device_ptr:
Alexey Bataeve04483e2019-03-27 14:14:31 +00002497 case OMPC_allocate:
Alexey Bataevb6e70842019-12-16 15:54:17 -05002498 case OMPC_nontemporal:
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002499 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002500 break;
Alexey Bataev729e2422019-08-23 16:11:14 +00002501 case OMPC_device_type:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002502 case OMPC_unknown:
2503 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
Alexey Bataeva55ed262014-05-28 06:15:33 +00002504 << getOpenMPDirectiveName(DKind);
Alp Tokerd751fa72013-12-18 19:10:49 +00002505 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002506 break;
2507 case OMPC_threadprivate:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002508 case OMPC_uniform:
Alexey Bataevdba792c2019-09-23 18:13:31 +00002509 case OMPC_match:
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002510 if (!WrongDirective)
2511 Diag(Tok, diag::err_omp_unexpected_clause)
2512 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
Alp Tokerd751fa72013-12-18 19:10:49 +00002513 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002514 break;
2515 }
Craig Topper161e4db2014-05-21 06:02:52 +00002516 return ErrorFound ? nullptr : Clause;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002517}
2518
Alexey Bataev2af33e32016-04-07 12:45:37 +00002519/// Parses simple expression in parens for single-expression clauses of OpenMP
2520/// constructs.
2521/// \param RLoc Returned location of right paren.
2522ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
Alexey Bataevd158cf62019-09-13 20:18:17 +00002523 SourceLocation &RLoc,
2524 bool IsAddressOfOperand) {
Alexey Bataev2af33e32016-04-07 12:45:37 +00002525 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2526 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
2527 return ExprError();
2528
2529 SourceLocation ELoc = Tok.getLocation();
Saar Razb65b1f32020-01-09 15:07:51 +02002530 ExprResult LHS(ParseCastExpression(AnyCastExpr, IsAddressOfOperand,
2531 NotTypeCast));
Alexey Bataev2af33e32016-04-07 12:45:37 +00002532 ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00002533 Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataev2af33e32016-04-07 12:45:37 +00002534
2535 // Parse ')'.
Alexey Bataevdbc72c92018-07-06 19:35:42 +00002536 RLoc = Tok.getLocation();
2537 if (!T.consumeClose())
2538 RLoc = T.getCloseLocation();
Alexey Bataev2af33e32016-04-07 12:45:37 +00002539
Alexey Bataev2af33e32016-04-07 12:45:37 +00002540 return Val;
2541}
2542
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002543/// Parsing of OpenMP clauses with single expressions like 'final',
Alexey Bataeva0569352015-12-01 10:17:31 +00002544/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
Alexey Bataev28c75412015-12-15 08:19:24 +00002545/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002546///
Alexey Bataev3778b602014-07-17 07:32:53 +00002547/// final-clause:
2548/// 'final' '(' expression ')'
2549///
Alexey Bataev62c87d22014-03-21 04:51:18 +00002550/// num_threads-clause:
2551/// 'num_threads' '(' expression ')'
2552///
2553/// safelen-clause:
2554/// 'safelen' '(' expression ')'
2555///
Alexey Bataev66b15b52015-08-21 11:14:16 +00002556/// simdlen-clause:
2557/// 'simdlen' '(' expression ')'
2558///
Alexander Musman8bd31e62014-05-27 15:12:19 +00002559/// collapse-clause:
2560/// 'collapse' '(' expression ')'
2561///
Alexey Bataeva0569352015-12-01 10:17:31 +00002562/// priority-clause:
2563/// 'priority' '(' expression ')'
2564///
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002565/// grainsize-clause:
2566/// 'grainsize' '(' expression ')'
2567///
Alexey Bataev382967a2015-12-08 12:06:20 +00002568/// num_tasks-clause:
2569/// 'num_tasks' '(' expression ')'
2570///
Alexey Bataev28c75412015-12-15 08:19:24 +00002571/// hint-clause:
2572/// 'hint' '(' expression ')'
2573///
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002574/// allocator-clause:
2575/// 'allocator' '(' expression ')'
2576///
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002577OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
2578 bool ParseOnly) {
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002579 SourceLocation Loc = ConsumeToken();
Alexey Bataev2af33e32016-04-07 12:45:37 +00002580 SourceLocation LLoc = Tok.getLocation();
2581 SourceLocation RLoc;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002582
Alexey Bataev2af33e32016-04-07 12:45:37 +00002583 ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002584
2585 if (Val.isInvalid())
Craig Topper161e4db2014-05-21 06:02:52 +00002586 return nullptr;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002587
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002588 if (ParseOnly)
2589 return nullptr;
Alexey Bataev2af33e32016-04-07 12:45:37 +00002590 return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002591}
2592
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002593/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002594///
2595/// default-clause:
2596/// 'default' '(' 'none' | 'shared' ')
2597///
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002598/// proc_bind-clause:
2599/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
2600///
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002601OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
2602 bool ParseOnly) {
Alexey Bataev729e2422019-08-23 16:11:14 +00002603 llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
2604 if (!Val || ParseOnly)
Craig Topper161e4db2014-05-21 06:02:52 +00002605 return nullptr;
Alexey Bataev729e2422019-08-23 16:11:14 +00002606 return Actions.ActOnOpenMPSimpleClause(
2607 Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
2608 Val.getValue().Loc, Val.getValue().RLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002609}
2610
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002611/// Parsing of OpenMP clauses like 'ordered'.
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002612///
2613/// ordered-clause:
2614/// 'ordered'
2615///
Alexey Bataev236070f2014-06-20 11:19:47 +00002616/// nowait-clause:
2617/// 'nowait'
2618///
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002619/// untied-clause:
2620/// 'untied'
2621///
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002622/// mergeable-clause:
2623/// 'mergeable'
2624///
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002625/// read-clause:
2626/// 'read'
2627///
Alexey Bataev346265e2015-09-25 10:37:12 +00002628/// threads-clause:
2629/// 'threads'
2630///
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002631/// simd-clause:
2632/// 'simd'
2633///
Alexey Bataevb825de12015-12-07 10:51:44 +00002634/// nogroup-clause:
2635/// 'nogroup'
2636///
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002637OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002638 SourceLocation Loc = Tok.getLocation();
2639 ConsumeAnyToken();
2640
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002641 if (ParseOnly)
2642 return nullptr;
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002643 return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
2644}
2645
2646
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002647/// Parsing of OpenMP clauses with single expressions and some additional
Alexey Bataev56dafe82014-06-20 07:16:17 +00002648/// argument like 'schedule' or 'dist_schedule'.
2649///
2650/// schedule-clause:
Alexey Bataev6402bca2015-12-28 07:25:51 +00002651/// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
2652/// ')'
Alexey Bataev56dafe82014-06-20 07:16:17 +00002653///
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002654/// if-clause:
2655/// 'if' '(' [ directive-name-modifier ':' ] expression ')'
2656///
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002657/// defaultmap:
2658/// 'defaultmap' '(' modifier ':' kind ')'
2659///
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002660OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
2661 bool ParseOnly) {
Alexey Bataev56dafe82014-06-20 07:16:17 +00002662 SourceLocation Loc = ConsumeToken();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002663 SourceLocation DelimLoc;
Alexey Bataev56dafe82014-06-20 07:16:17 +00002664 // Parse '('.
2665 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2666 if (T.expectAndConsume(diag::err_expected_lparen_after,
2667 getOpenMPClauseName(Kind)))
2668 return nullptr;
2669
2670 ExprResult Val;
Alexey Bataev6402bca2015-12-28 07:25:51 +00002671 SmallVector<unsigned, 4> Arg;
2672 SmallVector<SourceLocation, 4> KLoc;
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002673 if (Kind == OMPC_schedule) {
Alexey Bataev6402bca2015-12-28 07:25:51 +00002674 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
2675 Arg.resize(NumberOfElements);
2676 KLoc.resize(NumberOfElements);
2677 Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
2678 Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
2679 Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
Alexey Bataev61908f652018-04-23 19:53:05 +00002680 unsigned KindModifier = getOpenMPSimpleClauseType(
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002681 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
Alexey Bataev6402bca2015-12-28 07:25:51 +00002682 if (KindModifier > OMPC_SCHEDULE_unknown) {
2683 // Parse 'modifier'
2684 Arg[Modifier1] = KindModifier;
2685 KLoc[Modifier1] = Tok.getLocation();
2686 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2687 Tok.isNot(tok::annot_pragma_openmp_end))
2688 ConsumeAnyToken();
2689 if (Tok.is(tok::comma)) {
2690 // Parse ',' 'modifier'
2691 ConsumeAnyToken();
2692 KindModifier = getOpenMPSimpleClauseType(
2693 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2694 Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
2695 ? KindModifier
Aaron Ballmanad8a1042015-12-28 15:52:46 +00002696 : (unsigned)OMPC_SCHEDULE_unknown;
Alexey Bataev6402bca2015-12-28 07:25:51 +00002697 KLoc[Modifier2] = Tok.getLocation();
2698 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2699 Tok.isNot(tok::annot_pragma_openmp_end))
2700 ConsumeAnyToken();
2701 }
2702 // Parse ':'
2703 if (Tok.is(tok::colon))
2704 ConsumeAnyToken();
2705 else
2706 Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
2707 KindModifier = getOpenMPSimpleClauseType(
2708 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2709 }
2710 Arg[ScheduleKind] = KindModifier;
2711 KLoc[ScheduleKind] = Tok.getLocation();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002712 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2713 Tok.isNot(tok::annot_pragma_openmp_end))
2714 ConsumeAnyToken();
Alexey Bataev6402bca2015-12-28 07:25:51 +00002715 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
2716 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
2717 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002718 Tok.is(tok::comma))
2719 DelimLoc = ConsumeAnyToken();
Carlo Bertollib4adf552016-01-15 18:50:31 +00002720 } else if (Kind == OMPC_dist_schedule) {
2721 Arg.push_back(getOpenMPSimpleClauseType(
2722 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
2723 KLoc.push_back(Tok.getLocation());
2724 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2725 Tok.isNot(tok::annot_pragma_openmp_end))
2726 ConsumeAnyToken();
2727 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
2728 DelimLoc = ConsumeAnyToken();
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002729 } else if (Kind == OMPC_defaultmap) {
2730 // Get a defaultmap modifier
cchene06f3e02019-11-15 13:02:06 -05002731 unsigned Modifier = getOpenMPSimpleClauseType(
2732 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
2733 // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
2734 // pointer
2735 if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
2736 Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
2737 Arg.push_back(Modifier);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002738 KLoc.push_back(Tok.getLocation());
2739 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2740 Tok.isNot(tok::annot_pragma_openmp_end))
2741 ConsumeAnyToken();
2742 // Parse ':'
2743 if (Tok.is(tok::colon))
2744 ConsumeAnyToken();
2745 else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
2746 Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
2747 // Get a defaultmap kind
2748 Arg.push_back(getOpenMPSimpleClauseType(
2749 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
2750 KLoc.push_back(Tok.getLocation());
2751 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2752 Tok.isNot(tok::annot_pragma_openmp_end))
2753 ConsumeAnyToken();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002754 } else {
2755 assert(Kind == OMPC_if);
Alexey Bataev6402bca2015-12-28 07:25:51 +00002756 KLoc.push_back(Tok.getLocation());
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002757 TentativeParsingAction TPA(*this);
Johannes Doerferteb3e81f2019-11-04 22:00:49 -06002758 auto DK = parseOpenMPDirectiveKind(*this);
2759 Arg.push_back(DK);
2760 if (DK != OMPD_unknown) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002761 ConsumeToken();
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002762 if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
2763 TPA.Commit();
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002764 DelimLoc = ConsumeToken();
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002765 } else {
2766 TPA.Revert();
Johannes Doerferteb3e81f2019-11-04 22:00:49 -06002767 Arg.back() = unsigned(OMPD_unknown);
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002768 }
Alexey Bataev61908f652018-04-23 19:53:05 +00002769 } else {
Alexey Bataev2a6de8c2016-12-20 12:10:05 +00002770 TPA.Revert();
Alexey Bataev61908f652018-04-23 19:53:05 +00002771 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002772 }
Alexey Bataev56dafe82014-06-20 07:16:17 +00002773
Carlo Bertollib4adf552016-01-15 18:50:31 +00002774 bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
2775 (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
2776 Kind == OMPC_if;
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002777 if (NeedAnExpression) {
2778 SourceLocation ELoc = Tok.getLocation();
Saar Razb65b1f32020-01-09 15:07:51 +02002779 ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
Alexey Bataev56dafe82014-06-20 07:16:17 +00002780 Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00002781 Val =
2782 Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002783 }
2784
2785 // Parse ')'.
Alexey Bataevdbc72c92018-07-06 19:35:42 +00002786 SourceLocation RLoc = Tok.getLocation();
2787 if (!T.consumeClose())
2788 RLoc = T.getCloseLocation();
Alexey Bataev56dafe82014-06-20 07:16:17 +00002789
Alexey Bataev6b8046a2015-09-03 07:23:48 +00002790 if (NeedAnExpression && Val.isInvalid())
2791 return nullptr;
2792
Alexey Bataevf3c832a2018-01-09 19:21:04 +00002793 if (ParseOnly)
2794 return nullptr;
Alexey Bataev56dafe82014-06-20 07:16:17 +00002795 return Actions.ActOnOpenMPSingleExprWithArgClause(
Alexey Bataevdbc72c92018-07-06 19:35:42 +00002796 Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002797}
2798
Alexey Bataevc5e02582014-06-16 07:08:35 +00002799static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
2800 UnqualifiedId &ReductionId) {
Alexey Bataevc5e02582014-06-16 07:08:35 +00002801 if (ReductionIdScopeSpec.isEmpty()) {
2802 auto OOK = OO_None;
2803 switch (P.getCurToken().getKind()) {
2804 case tok::plus:
2805 OOK = OO_Plus;
2806 break;
2807 case tok::minus:
2808 OOK = OO_Minus;
2809 break;
2810 case tok::star:
2811 OOK = OO_Star;
2812 break;
2813 case tok::amp:
2814 OOK = OO_Amp;
2815 break;
2816 case tok::pipe:
2817 OOK = OO_Pipe;
2818 break;
2819 case tok::caret:
2820 OOK = OO_Caret;
2821 break;
2822 case tok::ampamp:
2823 OOK = OO_AmpAmp;
2824 break;
2825 case tok::pipepipe:
2826 OOK = OO_PipePipe;
2827 break;
2828 default:
2829 break;
2830 }
2831 if (OOK != OO_None) {
2832 SourceLocation OpLoc = P.ConsumeToken();
Alexey Bataev23b69422014-06-18 07:08:49 +00002833 SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
Alexey Bataevc5e02582014-06-16 07:08:35 +00002834 ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
2835 return false;
2836 }
2837 }
2838 return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
2839 /*AllowDestructorName*/ false,
Richard Smith35845152017-02-07 01:37:30 +00002840 /*AllowConstructorName*/ false,
2841 /*AllowDeductionGuide*/ false,
Richard Smithc08b6932018-04-27 02:00:13 +00002842 nullptr, nullptr, ReductionId);
Alexey Bataevc5e02582014-06-16 07:08:35 +00002843}
2844
Kelvin Lief579432018-12-18 22:18:41 +00002845/// Checks if the token is a valid map-type-modifier.
2846static OpenMPMapModifierKind isMapModifier(Parser &P) {
2847 Token Tok = P.getCurToken();
2848 if (!Tok.is(tok::identifier))
2849 return OMPC_MAP_MODIFIER_unknown;
2850
2851 Preprocessor &PP = P.getPreprocessor();
2852 OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
2853 getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2854 return TypeModifier;
2855}
2856
Michael Kruse01f670d2019-02-22 22:29:42 +00002857/// Parse the mapper modifier in map, to, and from clauses.
2858bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
2859 // Parse '('.
2860 BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
2861 if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
2862 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2863 StopBeforeMatch);
2864 return true;
2865 }
2866 // Parse mapper-identifier
2867 if (getLangOpts().CPlusPlus)
2868 ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2869 /*ObjectType=*/nullptr,
2870 /*EnteringContext=*/false);
2871 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
2872 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2873 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2874 StopBeforeMatch);
2875 return true;
2876 }
2877 auto &DeclNames = Actions.getASTContext().DeclarationNames;
2878 Data.ReductionOrMapperId = DeclarationNameInfo(
2879 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
2880 ConsumeToken();
2881 // Parse ')'.
2882 return T.consumeClose();
2883}
2884
Kelvin Lief579432018-12-18 22:18:41 +00002885/// Parse map-type-modifiers in map clause.
2886/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
Michael Kruse4304e9d2019-02-19 16:38:20 +00002887/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
2888bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
2889 while (getCurToken().isNot(tok::colon)) {
2890 OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
Kelvin Lief579432018-12-18 22:18:41 +00002891 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2892 TypeModifier == OMPC_MAP_MODIFIER_close) {
2893 Data.MapTypeModifiers.push_back(TypeModifier);
2894 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
Michael Kruse4304e9d2019-02-19 16:38:20 +00002895 ConsumeToken();
2896 } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2897 Data.MapTypeModifiers.push_back(TypeModifier);
2898 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2899 ConsumeToken();
Michael Kruse01f670d2019-02-22 22:29:42 +00002900 if (parseMapperModifier(Data))
Michael Kruse4304e9d2019-02-19 16:38:20 +00002901 return true;
Kelvin Lief579432018-12-18 22:18:41 +00002902 } else {
2903 // For the case of unknown map-type-modifier or a map-type.
2904 // Map-type is followed by a colon; the function returns when it
2905 // encounters a token followed by a colon.
2906 if (Tok.is(tok::comma)) {
Michael Kruse4304e9d2019-02-19 16:38:20 +00002907 Diag(Tok, diag::err_omp_map_type_modifier_missing);
2908 ConsumeToken();
Kelvin Lief579432018-12-18 22:18:41 +00002909 continue;
2910 }
2911 // Potential map-type token as it is followed by a colon.
2912 if (PP.LookAhead(0).is(tok::colon))
Michael Kruse4304e9d2019-02-19 16:38:20 +00002913 return false;
2914 Diag(Tok, diag::err_omp_unknown_map_type_modifier);
2915 ConsumeToken();
Kelvin Lief579432018-12-18 22:18:41 +00002916 }
Michael Kruse4304e9d2019-02-19 16:38:20 +00002917 if (getCurToken().is(tok::comma))
2918 ConsumeToken();
Kelvin Lief579432018-12-18 22:18:41 +00002919 }
Michael Kruse4304e9d2019-02-19 16:38:20 +00002920 return false;
Kelvin Lief579432018-12-18 22:18:41 +00002921}
2922
2923/// Checks if the token is a valid map-type.
2924static OpenMPMapClauseKind isMapType(Parser &P) {
2925 Token Tok = P.getCurToken();
2926 // The map-type token can be either an identifier or the C++ delete keyword.
2927 if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
2928 return OMPC_MAP_unknown;
2929 Preprocessor &PP = P.getPreprocessor();
2930 OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
2931 getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2932 return MapType;
2933}
2934
2935/// Parse map-type in map clause.
2936/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
Ilya Biryukovff2a9972019-02-26 11:01:50 +00002937/// where, map-type ::= to | from | tofrom | alloc | release | delete
Kelvin Lief579432018-12-18 22:18:41 +00002938static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
2939 Token Tok = P.getCurToken();
2940 if (Tok.is(tok::colon)) {
2941 P.Diag(Tok, diag::err_omp_map_type_missing);
2942 return;
2943 }
Alexey Bataev93dc40d2019-12-20 11:04:57 -05002944 Data.ExtraModifier = isMapType(P);
2945 if (Data.ExtraModifier == OMPC_MAP_unknown)
Kelvin Lief579432018-12-18 22:18:41 +00002946 P.Diag(Tok, diag::err_omp_unknown_map_type);
2947 P.ConsumeToken();
2948}
2949
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002950/// Parses clauses with list.
2951bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
2952 OpenMPClauseKind Kind,
2953 SmallVectorImpl<Expr *> &Vars,
2954 OpenMPVarListDataTy &Data) {
2955 UnqualifiedId UnqualifiedReductionId;
2956 bool InvalidReductionId = false;
Michael Kruse01f670d2019-02-22 22:29:42 +00002957 bool IsInvalidMapperModifier = false;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002958
2959 // Parse '('.
2960 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2961 if (T.expectAndConsume(diag::err_expected_lparen_after,
2962 getOpenMPClauseName(Kind)))
2963 return true;
2964
2965 bool NeedRParenForLinear = false;
2966 BalancedDelimiterTracker LinearT(*this, tok::l_paren,
2967 tok::annot_pragma_openmp_end);
2968 // Handle reduction-identifier for reduction clause.
Alexey Bataevfa312f32017-07-21 18:48:21 +00002969 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
2970 Kind == OMPC_in_reduction) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002971 ColonProtectionRAIIObject ColonRAII(*this);
2972 if (getLangOpts().CPlusPlus)
Michael Kruse4304e9d2019-02-19 16:38:20 +00002973 ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002974 /*ObjectType=*/nullptr,
2975 /*EnteringContext=*/false);
Michael Kruse4304e9d2019-02-19 16:38:20 +00002976 InvalidReductionId = ParseReductionId(
2977 *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002978 if (InvalidReductionId) {
2979 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2980 StopBeforeMatch);
2981 }
2982 if (Tok.is(tok::colon))
2983 Data.ColonLoc = ConsumeToken();
2984 else
2985 Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
2986 if (!InvalidReductionId)
Michael Kruse4304e9d2019-02-19 16:38:20 +00002987 Data.ReductionOrMapperId =
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002988 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
2989 } else if (Kind == OMPC_depend) {
Alexey Bataev93dc40d2019-12-20 11:04:57 -05002990 // Handle dependency type for depend clause.
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002991 ColonProtectionRAIIObject ColonRAII(*this);
Alexey Bataev93dc40d2019-12-20 11:04:57 -05002992 Data.ExtraModifier = getOpenMPSimpleClauseType(
2993 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "");
2994 Data.DepLinMapLastLoc = Tok.getLocation();
2995 if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00002996 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2997 StopBeforeMatch);
2998 } else {
2999 ConsumeToken();
3000 // Special processing for depend(source) clause.
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003001 if (DKind == OMPD_ordered && Data.ExtraModifier == OMPC_DEPEND_source) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003002 // Parse ')'.
3003 T.consumeClose();
3004 return false;
3005 }
3006 }
Alexey Bataev61908f652018-04-23 19:53:05 +00003007 if (Tok.is(tok::colon)) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003008 Data.ColonLoc = ConsumeToken();
Alexey Bataev61908f652018-04-23 19:53:05 +00003009 } else {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003010 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
3011 : diag::warn_pragma_expected_colon)
3012 << "dependency type";
3013 }
3014 } else if (Kind == OMPC_linear) {
3015 // Try to parse modifier if any.
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003016 Data.ExtraModifier = OMPC_LINEAR_val;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003017 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003018 Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
3019 Data.DepLinMapLastLoc = ConsumeToken();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003020 LinearT.consumeOpen();
3021 NeedRParenForLinear = true;
3022 }
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003023 } else if (Kind == OMPC_lastprivate) {
3024 // Try to parse modifier if any.
3025 Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
3026 // Conditional modifier allowed only in OpenMP 5.0 and not supported in
3027 // distribute and taskloop based directives.
3028 if ((getLangOpts().OpenMP >= 50 && !isOpenMPDistributeDirective(DKind) &&
3029 !isOpenMPTaskLoopDirective(DKind)) &&
3030 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
3031 Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
3032 Data.DepLinMapLastLoc = Tok.getLocation();
3033 if (Data.ExtraModifier == OMPC_LASTPRIVATE_unknown) {
3034 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3035 StopBeforeMatch);
3036 } else {
3037 ConsumeToken();
3038 }
3039 assert(Tok.is(tok::colon) && "Expected colon.");
3040 Data.ColonLoc = ConsumeToken();
3041 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003042 } else if (Kind == OMPC_map) {
3043 // Handle map type for map clause.
3044 ColonProtectionRAIIObject ColonRAII(*this);
3045
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003046 // The first identifier may be a list item, a map-type or a
Kelvin Lief579432018-12-18 22:18:41 +00003047 // map-type-modifier. The map-type can also be delete which has the same
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003048 // spelling of the C++ delete keyword.
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003049 Data.ExtraModifier = OMPC_MAP_unknown;
3050 Data.DepLinMapLastLoc = Tok.getLocation();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003051
Kelvin Lief579432018-12-18 22:18:41 +00003052 // Check for presence of a colon in the map clause.
3053 TentativeParsingAction TPA(*this);
3054 bool ColonPresent = false;
3055 if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3056 StopBeforeMatch)) {
3057 if (Tok.is(tok::colon))
3058 ColonPresent = true;
3059 }
3060 TPA.Revert();
3061 // Only parse map-type-modifier[s] and map-type if a colon is present in
3062 // the map clause.
3063 if (ColonPresent) {
Michael Kruse01f670d2019-02-22 22:29:42 +00003064 IsInvalidMapperModifier = parseMapTypeModifiers(Data);
3065 if (!IsInvalidMapperModifier)
Michael Kruse4304e9d2019-02-19 16:38:20 +00003066 parseMapType(*this, Data);
Michael Kruse01f670d2019-02-22 22:29:42 +00003067 else
3068 SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
Kelvin Lief579432018-12-18 22:18:41 +00003069 }
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003070 if (Data.ExtraModifier == OMPC_MAP_unknown) {
3071 Data.ExtraModifier = OMPC_MAP_tofrom;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003072 Data.IsMapTypeImplicit = true;
3073 }
3074
3075 if (Tok.is(tok::colon))
3076 Data.ColonLoc = ConsumeToken();
Michael Kruse0336c752019-02-25 20:34:15 +00003077 } else if (Kind == OMPC_to || Kind == OMPC_from) {
Michael Kruse01f670d2019-02-22 22:29:42 +00003078 if (Tok.is(tok::identifier)) {
3079 bool IsMapperModifier = false;
Michael Kruse0336c752019-02-25 20:34:15 +00003080 if (Kind == OMPC_to) {
3081 auto Modifier = static_cast<OpenMPToModifierKind>(
3082 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
3083 if (Modifier == OMPC_TO_MODIFIER_mapper)
3084 IsMapperModifier = true;
3085 } else {
3086 auto Modifier = static_cast<OpenMPFromModifierKind>(
3087 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
3088 if (Modifier == OMPC_FROM_MODIFIER_mapper)
3089 IsMapperModifier = true;
3090 }
Michael Kruse01f670d2019-02-22 22:29:42 +00003091 if (IsMapperModifier) {
3092 // Parse the mapper modifier.
3093 ConsumeToken();
3094 IsInvalidMapperModifier = parseMapperModifier(Data);
3095 if (Tok.isNot(tok::colon)) {
3096 if (!IsInvalidMapperModifier)
3097 Diag(Tok, diag::warn_pragma_expected_colon) << ")";
3098 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3099 StopBeforeMatch);
3100 }
3101 // Consume ':'.
3102 if (Tok.is(tok::colon))
3103 ConsumeToken();
3104 }
3105 }
Alexey Bataeve04483e2019-03-27 14:14:31 +00003106 } else if (Kind == OMPC_allocate) {
3107 // Handle optional allocator expression followed by colon delimiter.
3108 ColonProtectionRAIIObject ColonRAII(*this);
3109 TentativeParsingAction TPA(*this);
3110 ExprResult Tail =
3111 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3112 Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
3113 /*DiscardedValue=*/false);
3114 if (Tail.isUsable()) {
3115 if (Tok.is(tok::colon)) {
3116 Data.TailExpr = Tail.get();
3117 Data.ColonLoc = ConsumeToken();
3118 TPA.Commit();
3119 } else {
3120 // colon not found, no allocator specified, parse only list of
3121 // variables.
3122 TPA.Revert();
3123 }
3124 } else {
3125 // Parsing was unsuccessfull, revert and skip to the end of clause or
3126 // directive.
3127 TPA.Revert();
3128 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3129 StopBeforeMatch);
3130 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003131 }
3132
Alexey Bataevfa312f32017-07-21 18:48:21 +00003133 bool IsComma =
3134 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
3135 Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
3136 (Kind == OMPC_reduction && !InvalidReductionId) ||
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003137 (Kind == OMPC_map && Data.ExtraModifier != OMPC_MAP_unknown) ||
3138 (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003139 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
3140 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
3141 Tok.isNot(tok::annot_pragma_openmp_end))) {
3142 ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
3143 // Parse variable
3144 ExprResult VarExpr =
3145 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
Alexey Bataev61908f652018-04-23 19:53:05 +00003146 if (VarExpr.isUsable()) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003147 Vars.push_back(VarExpr.get());
Alexey Bataev61908f652018-04-23 19:53:05 +00003148 } else {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003149 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3150 StopBeforeMatch);
3151 }
3152 // Skip ',' if any
3153 IsComma = Tok.is(tok::comma);
3154 if (IsComma)
3155 ConsumeToken();
3156 else if (Tok.isNot(tok::r_paren) &&
3157 Tok.isNot(tok::annot_pragma_openmp_end) &&
3158 (!MayHaveTail || Tok.isNot(tok::colon)))
3159 Diag(Tok, diag::err_omp_expected_punc)
3160 << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
3161 : getOpenMPClauseName(Kind))
3162 << (Kind == OMPC_flush);
3163 }
3164
3165 // Parse ')' for linear clause with modifier.
3166 if (NeedRParenForLinear)
3167 LinearT.consumeClose();
3168
3169 // Parse ':' linear-step (or ':' alignment).
3170 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
3171 if (MustHaveTail) {
3172 Data.ColonLoc = Tok.getLocation();
3173 SourceLocation ELoc = ConsumeToken();
3174 ExprResult Tail = ParseAssignmentExpression();
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00003175 Tail =
3176 Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003177 if (Tail.isUsable())
3178 Data.TailExpr = Tail.get();
3179 else
3180 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3181 StopBeforeMatch);
3182 }
3183
3184 // Parse ')'.
Alexey Bataevdbc72c92018-07-06 19:35:42 +00003185 Data.RLoc = Tok.getLocation();
3186 if (!T.consumeClose())
3187 Data.RLoc = T.getCloseLocation();
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003188 return (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown &&
Alexey Bataev61908f652018-04-23 19:53:05 +00003189 Vars.empty()) ||
3190 (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
Michael Kruse4304e9d2019-02-19 16:38:20 +00003191 (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
Michael Kruse01f670d2019-02-22 22:29:42 +00003192 IsInvalidMapperModifier;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003193}
3194
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003195/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
Alexey Bataevfa312f32017-07-21 18:48:21 +00003196/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
3197/// 'in_reduction'.
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003198///
3199/// private-clause:
3200/// 'private' '(' list ')'
Alexey Bataevd5af8e42013-10-01 05:32:34 +00003201/// firstprivate-clause:
3202/// 'firstprivate' '(' list ')'
Alexander Musman1bb328c2014-06-04 13:06:39 +00003203/// lastprivate-clause:
3204/// 'lastprivate' '(' list ')'
Alexey Bataev758e55e2013-09-06 18:03:48 +00003205/// shared-clause:
3206/// 'shared' '(' list ')'
Alexander Musman8dba6642014-04-22 13:09:42 +00003207/// linear-clause:
Alexey Bataev182227b2015-08-20 10:54:39 +00003208/// 'linear' '(' linear-list [ ':' linear-step ] ')'
Alexander Musmanf0d76e72014-05-29 14:36:25 +00003209/// aligned-clause:
3210/// 'aligned' '(' list [ ':' alignment ] ')'
Alexey Bataevc5e02582014-06-16 07:08:35 +00003211/// reduction-clause:
3212/// 'reduction' '(' reduction-identifier ':' list ')'
Alexey Bataev169d96a2017-07-18 20:17:46 +00003213/// task_reduction-clause:
3214/// 'task_reduction' '(' reduction-identifier ':' list ')'
Alexey Bataevfa312f32017-07-21 18:48:21 +00003215/// in_reduction-clause:
3216/// 'in_reduction' '(' reduction-identifier ':' list ')'
Alexey Bataev6125da92014-07-21 11:26:11 +00003217/// copyprivate-clause:
3218/// 'copyprivate' '(' list ')'
3219/// flush-clause:
3220/// 'flush' '(' list ')'
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00003221/// depend-clause:
Alexey Bataeveb482352015-12-18 05:05:56 +00003222/// 'depend' '(' in | out | inout : list | source ')'
Kelvin Li0bff7af2015-11-23 05:32:03 +00003223/// map-clause:
Kelvin Lief579432018-12-18 22:18:41 +00003224/// 'map' '(' [ [ always [,] ] [ close [,] ]
Michael Kruse01f670d2019-02-22 22:29:42 +00003225/// [ mapper '(' mapper-identifier ')' [,] ]
Kelvin Li0bff7af2015-11-23 05:32:03 +00003226/// to | from | tofrom | alloc | release | delete ':' ] list ')';
Samuel Antao661c0902016-05-26 17:39:58 +00003227/// to-clause:
Michael Kruse01f670d2019-02-22 22:29:42 +00003228/// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
Samuel Antaoec172c62016-05-26 17:49:04 +00003229/// from-clause:
Michael Kruse0336c752019-02-25 20:34:15 +00003230/// 'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
Carlo Bertolli2404b172016-07-13 15:37:16 +00003231/// use_device_ptr-clause:
3232/// 'use_device_ptr' '(' list ')'
Carlo Bertolli70594e92016-07-13 17:16:49 +00003233/// is_device_ptr-clause:
3234/// 'is_device_ptr' '(' list ')'
Alexey Bataeve04483e2019-03-27 14:14:31 +00003235/// allocate-clause:
3236/// 'allocate' '(' [ allocator ':' ] list ')'
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003237///
Alexey Bataev182227b2015-08-20 10:54:39 +00003238/// For 'linear' clause linear-list may have the following forms:
3239/// list
3240/// modifier(list)
3241/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
Alexey Bataeveb482352015-12-18 05:05:56 +00003242OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
Alexey Bataevf3c832a2018-01-09 19:21:04 +00003243 OpenMPClauseKind Kind,
3244 bool ParseOnly) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003245 SourceLocation Loc = Tok.getLocation();
3246 SourceLocation LOpen = ConsumeToken();
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003247 SmallVector<Expr *, 4> Vars;
3248 OpenMPVarListDataTy Data;
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00003249
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003250 if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
Craig Topper161e4db2014-05-21 06:02:52 +00003251 return nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003252
Alexey Bataevf3c832a2018-01-09 19:21:04 +00003253 if (ParseOnly)
3254 return nullptr;
Michael Kruse4304e9d2019-02-19 16:38:20 +00003255 OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
Alexey Bataevc5e02582014-06-16 07:08:35 +00003256 return Actions.ActOnOpenMPVarListClause(
Michael Kruse4304e9d2019-02-19 16:38:20 +00003257 Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
Alexey Bataev93dc40d2019-12-20 11:04:57 -05003258 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
3259 Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
3260 Data.IsMapTypeImplicit, Data.DepLinMapLastLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003261}
3262