xref: /freebsd/contrib/llvm-project/clang/lib/Parse/ParseOpenACC.cpp (revision e1e636193db45630c7881246d25902e57c43d24e)
1 //===--- ParseOpenACC.cpp - OpenACC-specific parsing support --------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the parsing logic for OpenACC language features.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/Basic/OpenACCKinds.h"
14 #include "clang/Parse/ParseDiagnostic.h"
15 #include "clang/Parse/Parser.h"
16 #include "clang/Parse/RAIIObjectsForParser.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/StringSwitch.h"
19 
20 using namespace clang;
21 using namespace llvm;
22 
23 namespace {
24 // An enum that contains the extended 'partial' parsed variants. This type
25 // should never escape the initial parse functionality, but is useful for
26 // simplifying the implementation.
27 enum class OpenACCDirectiveKindEx {
28   Invalid = static_cast<int>(OpenACCDirectiveKind::Invalid),
29   // 'enter data' and 'exit data'
30   Enter,
31   Exit,
32 };
33 
34 // Translate single-token string representations to the OpenACC Directive Kind.
35 // This doesn't completely comprehend 'Compound Constructs' (as it just
36 // identifies the first token), and doesn't fully handle 'enter data', 'exit
37 // data', nor any of the 'atomic' variants, just the first token of each.  So
38 // this should only be used by `ParseOpenACCDirectiveKind`.
39 OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) {
40   if (!Tok.is(tok::identifier))
41     return OpenACCDirectiveKindEx::Invalid;
42   OpenACCDirectiveKind DirKind =
43       llvm::StringSwitch<OpenACCDirectiveKind>(
44           Tok.getIdentifierInfo()->getName())
45           .Case("parallel", OpenACCDirectiveKind::Parallel)
46           .Case("serial", OpenACCDirectiveKind::Serial)
47           .Case("kernels", OpenACCDirectiveKind::Kernels)
48           .Case("data", OpenACCDirectiveKind::Data)
49           .Case("host_data", OpenACCDirectiveKind::HostData)
50           .Case("loop", OpenACCDirectiveKind::Loop)
51           .Case("cache", OpenACCDirectiveKind::Cache)
52           .Case("atomic", OpenACCDirectiveKind::Atomic)
53           .Case("routine", OpenACCDirectiveKind::Routine)
54           .Case("declare", OpenACCDirectiveKind::Declare)
55           .Case("init", OpenACCDirectiveKind::Init)
56           .Case("shutdown", OpenACCDirectiveKind::Shutdown)
57           .Case("set", OpenACCDirectiveKind::Shutdown)
58           .Case("update", OpenACCDirectiveKind::Update)
59           .Case("wait", OpenACCDirectiveKind::Wait)
60           .Default(OpenACCDirectiveKind::Invalid);
61 
62   if (DirKind != OpenACCDirectiveKind::Invalid)
63     return static_cast<OpenACCDirectiveKindEx>(DirKind);
64 
65   return llvm::StringSwitch<OpenACCDirectiveKindEx>(
66              Tok.getIdentifierInfo()->getName())
67       .Case("enter", OpenACCDirectiveKindEx::Enter)
68       .Case("exit", OpenACCDirectiveKindEx::Exit)
69       .Default(OpenACCDirectiveKindEx::Invalid);
70 }
71 
72 // Translate single-token string representations to the OpenCC Clause Kind.
73 OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
74   // auto is a keyword in some language modes, so make sure we parse it
75   // correctly.
76   if (Tok.is(tok::kw_auto))
77     return OpenACCClauseKind::Auto;
78 
79   // default is a keyword, so make sure we parse it correctly.
80   if (Tok.is(tok::kw_default))
81     return OpenACCClauseKind::Default;
82 
83   // if is also a keyword, make sure we parse it correctly.
84   if (Tok.is(tok::kw_if))
85     return OpenACCClauseKind::If;
86 
87   if (!Tok.is(tok::identifier))
88     return OpenACCClauseKind::Invalid;
89 
90   return llvm::StringSwitch<OpenACCClauseKind>(
91              Tok.getIdentifierInfo()->getName())
92       .Case("attach", OpenACCClauseKind::Attach)
93       .Case("auto", OpenACCClauseKind::Auto)
94       .Case("bind", OpenACCClauseKind::Bind)
95       .Case("create", OpenACCClauseKind::Create)
96       .Case("collapse", OpenACCClauseKind::Collapse)
97       .Case("copy", OpenACCClauseKind::Copy)
98       .Case("copyin", OpenACCClauseKind::CopyIn)
99       .Case("copyout", OpenACCClauseKind::CopyOut)
100       .Case("default", OpenACCClauseKind::Default)
101       .Case("default_async", OpenACCClauseKind::DefaultAsync)
102       .Case("delete", OpenACCClauseKind::Delete)
103       .Case("detach", OpenACCClauseKind::Detach)
104       .Case("device", OpenACCClauseKind::Device)
105       .Case("device_num", OpenACCClauseKind::DeviceNum)
106       .Case("device_resident", OpenACCClauseKind::DeviceResident)
107       .Case("device_type", OpenACCClauseKind::DeviceType)
108       .Case("deviceptr", OpenACCClauseKind::DevicePtr)
109       .Case("dtype", OpenACCClauseKind::DType)
110       .Case("finalize", OpenACCClauseKind::Finalize)
111       .Case("firstprivate", OpenACCClauseKind::FirstPrivate)
112       .Case("host", OpenACCClauseKind::Host)
113       .Case("if", OpenACCClauseKind::If)
114       .Case("if_present", OpenACCClauseKind::IfPresent)
115       .Case("independent", OpenACCClauseKind::Independent)
116       .Case("link", OpenACCClauseKind::Link)
117       .Case("no_create", OpenACCClauseKind::NoCreate)
118       .Case("num_gangs", OpenACCClauseKind::NumGangs)
119       .Case("num_workers", OpenACCClauseKind::NumWorkers)
120       .Case("nohost", OpenACCClauseKind::NoHost)
121       .Case("present", OpenACCClauseKind::Present)
122       .Case("private", OpenACCClauseKind::Private)
123       .Case("reduction", OpenACCClauseKind::Reduction)
124       .Case("self", OpenACCClauseKind::Self)
125       .Case("seq", OpenACCClauseKind::Seq)
126       .Case("use_device", OpenACCClauseKind::UseDevice)
127       .Case("vector", OpenACCClauseKind::Vector)
128       .Case("vector_length", OpenACCClauseKind::VectorLength)
129       .Case("worker", OpenACCClauseKind::Worker)
130       .Default(OpenACCClauseKind::Invalid);
131 }
132 
133 // Since 'atomic' is effectively a compound directive, this will decode the
134 // second part of the directive.
135 OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) {
136   if (!Tok.is(tok::identifier))
137     return OpenACCAtomicKind::Invalid;
138   return llvm::StringSwitch<OpenACCAtomicKind>(
139              Tok.getIdentifierInfo()->getName())
140       .Case("read", OpenACCAtomicKind::Read)
141       .Case("write", OpenACCAtomicKind::Write)
142       .Case("update", OpenACCAtomicKind::Update)
143       .Case("capture", OpenACCAtomicKind::Capture)
144       .Default(OpenACCAtomicKind::Invalid);
145 }
146 
147 OpenACCDefaultClauseKind getOpenACCDefaultClauseKind(Token Tok) {
148   if (!Tok.is(tok::identifier))
149     return OpenACCDefaultClauseKind::Invalid;
150 
151   return llvm::StringSwitch<OpenACCDefaultClauseKind>(
152              Tok.getIdentifierInfo()->getName())
153       .Case("none", OpenACCDefaultClauseKind::None)
154       .Case("present", OpenACCDefaultClauseKind::Present)
155       .Default(OpenACCDefaultClauseKind::Invalid);
156 }
157 
158 enum class OpenACCSpecialTokenKind {
159   ReadOnly,
160   DevNum,
161   Queues,
162   Zero,
163   Force,
164   Num,
165   Length,
166 };
167 
168 bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) {
169   if (!Tok.is(tok::identifier))
170     return false;
171 
172   switch (Kind) {
173   case OpenACCSpecialTokenKind::ReadOnly:
174     return Tok.getIdentifierInfo()->isStr("readonly");
175   case OpenACCSpecialTokenKind::DevNum:
176     return Tok.getIdentifierInfo()->isStr("devnum");
177   case OpenACCSpecialTokenKind::Queues:
178     return Tok.getIdentifierInfo()->isStr("queues");
179   case OpenACCSpecialTokenKind::Zero:
180     return Tok.getIdentifierInfo()->isStr("zero");
181   case OpenACCSpecialTokenKind::Force:
182     return Tok.getIdentifierInfo()->isStr("force");
183   case OpenACCSpecialTokenKind::Num:
184     return Tok.getIdentifierInfo()->isStr("num");
185   case OpenACCSpecialTokenKind::Length:
186     return Tok.getIdentifierInfo()->isStr("length");
187   }
188   llvm_unreachable("Unknown 'Kind' Passed");
189 }
190 
191 /// Used for cases where we have a token we want to check against an
192 /// 'identifier-like' token, but don't want to give awkward error messages in
193 /// cases where it is accidentially a keyword.
194 bool isTokenIdentifierOrKeyword(Parser &P, Token Tok) {
195   if (Tok.is(tok::identifier))
196     return true;
197 
198   if (!Tok.isAnnotation() && Tok.getIdentifierInfo() &&
199       Tok.getIdentifierInfo()->isKeyword(P.getLangOpts()))
200     return true;
201 
202   return false;
203 }
204 
205 /// Parses and consumes an identifer followed immediately by a single colon, and
206 /// diagnoses if it is not the 'special token' kind that we require. Used when
207 /// the tag is the only valid value.
208 /// Return 'true' if the special token was matched, false if no special token,
209 /// or an invalid special token was found.
210 template <typename DirOrClauseTy>
211 bool tryParseAndConsumeSpecialTokenKind(Parser &P, OpenACCSpecialTokenKind Kind,
212                                         DirOrClauseTy DirOrClause) {
213   Token IdentTok = P.getCurToken();
214   // If this is an identifier-like thing followed by ':', it is one of the
215   // OpenACC 'special' name tags, so consume it.
216   if (isTokenIdentifierOrKeyword(P, IdentTok) && P.NextToken().is(tok::colon)) {
217     P.ConsumeToken();
218     P.ConsumeToken();
219 
220     if (!isOpenACCSpecialToken(Kind, IdentTok)) {
221       P.Diag(IdentTok, diag::err_acc_invalid_tag_kind)
222           << IdentTok.getIdentifierInfo() << DirOrClause
223           << std::is_same_v<DirOrClauseTy, OpenACCClauseKind>;
224       return false;
225     }
226 
227     return true;
228   }
229 
230   return false;
231 }
232 
233 bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) {
234   if (!Tok.is(tok::identifier))
235     return false;
236 
237   switch (Kind) {
238   case OpenACCDirectiveKind::Parallel:
239     return Tok.getIdentifierInfo()->isStr("parallel");
240   case OpenACCDirectiveKind::Serial:
241     return Tok.getIdentifierInfo()->isStr("serial");
242   case OpenACCDirectiveKind::Kernels:
243     return Tok.getIdentifierInfo()->isStr("kernels");
244   case OpenACCDirectiveKind::Data:
245     return Tok.getIdentifierInfo()->isStr("data");
246   case OpenACCDirectiveKind::HostData:
247     return Tok.getIdentifierInfo()->isStr("host_data");
248   case OpenACCDirectiveKind::Loop:
249     return Tok.getIdentifierInfo()->isStr("loop");
250   case OpenACCDirectiveKind::Cache:
251     return Tok.getIdentifierInfo()->isStr("cache");
252 
253   case OpenACCDirectiveKind::ParallelLoop:
254   case OpenACCDirectiveKind::SerialLoop:
255   case OpenACCDirectiveKind::KernelsLoop:
256   case OpenACCDirectiveKind::EnterData:
257   case OpenACCDirectiveKind::ExitData:
258     return false;
259 
260   case OpenACCDirectiveKind::Atomic:
261     return Tok.getIdentifierInfo()->isStr("atomic");
262   case OpenACCDirectiveKind::Routine:
263     return Tok.getIdentifierInfo()->isStr("routine");
264   case OpenACCDirectiveKind::Declare:
265     return Tok.getIdentifierInfo()->isStr("declare");
266   case OpenACCDirectiveKind::Init:
267     return Tok.getIdentifierInfo()->isStr("init");
268   case OpenACCDirectiveKind::Shutdown:
269     return Tok.getIdentifierInfo()->isStr("shutdown");
270   case OpenACCDirectiveKind::Set:
271     return Tok.getIdentifierInfo()->isStr("set");
272   case OpenACCDirectiveKind::Update:
273     return Tok.getIdentifierInfo()->isStr("update");
274   case OpenACCDirectiveKind::Wait:
275     return Tok.getIdentifierInfo()->isStr("wait");
276   case OpenACCDirectiveKind::Invalid:
277     return false;
278   }
279   llvm_unreachable("Unknown 'Kind' Passed");
280 }
281 
282 OpenACCReductionOperator ParseReductionOperator(Parser &P) {
283   // If there is no colon, treat as if the reduction operator was missing, else
284   // we probably will not recover from it in the case where an expression starts
285   // with one of the operator tokens.
286   if (P.NextToken().isNot(tok::colon)) {
287     P.Diag(P.getCurToken(), diag::err_acc_expected_reduction_operator);
288     return OpenACCReductionOperator::Invalid;
289   }
290   Token ReductionKindTok = P.getCurToken();
291   // Consume both the kind and the colon.
292   P.ConsumeToken();
293   P.ConsumeToken();
294 
295   switch (ReductionKindTok.getKind()) {
296   case tok::plus:
297     return OpenACCReductionOperator::Addition;
298   case tok::star:
299     return OpenACCReductionOperator::Multiplication;
300   case tok::amp:
301     return OpenACCReductionOperator::BitwiseAnd;
302   case tok::pipe:
303     return OpenACCReductionOperator::BitwiseOr;
304   case tok::caret:
305     return OpenACCReductionOperator::BitwiseXOr;
306   case tok::ampamp:
307     return OpenACCReductionOperator::And;
308   case tok::pipepipe:
309     return OpenACCReductionOperator::Or;
310   case tok::identifier:
311     if (ReductionKindTok.getIdentifierInfo()->isStr("max"))
312       return OpenACCReductionOperator::Max;
313     if (ReductionKindTok.getIdentifierInfo()->isStr("min"))
314       return OpenACCReductionOperator::Min;
315     LLVM_FALLTHROUGH;
316   default:
317     P.Diag(ReductionKindTok, diag::err_acc_invalid_reduction_operator);
318     return OpenACCReductionOperator::Invalid;
319   }
320   llvm_unreachable("Reduction op token kind not caught by 'default'?");
321 }
322 
323 /// Used for cases where we expect an identifier-like token, but don't want to
324 /// give awkward error messages in cases where it is accidentially a keyword.
325 bool expectIdentifierOrKeyword(Parser &P) {
326   Token Tok = P.getCurToken();
327 
328   if (isTokenIdentifierOrKeyword(P, Tok))
329     return false;
330 
331   P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier;
332   return true;
333 }
334 
335 OpenACCDirectiveKind
336 ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok,
337                                    OpenACCDirectiveKindEx ExtDirKind) {
338   Token SecondTok = P.getCurToken();
339 
340   if (SecondTok.isAnnotation()) {
341     P.Diag(FirstTok, diag::err_acc_invalid_directive)
342         << 0 << FirstTok.getIdentifierInfo();
343     return OpenACCDirectiveKind::Invalid;
344   }
345 
346   // Consume the second name anyway, this way we can continue on without making
347   // this oddly look like a clause.
348   P.ConsumeAnyToken();
349 
350   if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) {
351     if (!SecondTok.is(tok::identifier))
352       P.Diag(SecondTok, diag::err_expected) << tok::identifier;
353     else
354       P.Diag(FirstTok, diag::err_acc_invalid_directive)
355           << 1 << FirstTok.getIdentifierInfo()->getName()
356           << SecondTok.getIdentifierInfo()->getName();
357     return OpenACCDirectiveKind::Invalid;
358   }
359 
360   return ExtDirKind == OpenACCDirectiveKindEx::Enter
361              ? OpenACCDirectiveKind::EnterData
362              : OpenACCDirectiveKind::ExitData;
363 }
364 
365 OpenACCAtomicKind ParseOpenACCAtomicKind(Parser &P) {
366   Token AtomicClauseToken = P.getCurToken();
367 
368   // #pragma acc atomic is equivilent to update:
369   if (AtomicClauseToken.isAnnotation())
370     return OpenACCAtomicKind::Update;
371 
372   OpenACCAtomicKind AtomicKind = getOpenACCAtomicKind(AtomicClauseToken);
373 
374   // If we don't know what this is, treat it as 'nothing', and treat the rest of
375   // this as a clause list, which, despite being invalid, is likely what the
376   // user was trying to do.
377   if (AtomicKind == OpenACCAtomicKind::Invalid)
378     return OpenACCAtomicKind::Update;
379 
380   P.ConsumeToken();
381   return AtomicKind;
382 }
383 
384 // Parse and consume the tokens for OpenACC Directive/Construct kinds.
385 OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
386   Token FirstTok = P.getCurToken();
387 
388   // Just #pragma acc can get us immediately to the end, make sure we don't
389   // introspect on the spelling before then.
390   if (FirstTok.isNot(tok::identifier)) {
391     P.Diag(FirstTok, diag::err_acc_missing_directive);
392 
393     if (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
394       P.ConsumeAnyToken();
395 
396     return OpenACCDirectiveKind::Invalid;
397   }
398 
399   P.ConsumeToken();
400 
401   OpenACCDirectiveKindEx ExDirKind = getOpenACCDirectiveKind(FirstTok);
402 
403   // OpenACCDirectiveKindEx is meant to be an extended list
404   // over OpenACCDirectiveKind, so any value below Invalid is one of the
405   // OpenACCDirectiveKind values.  This switch takes care of all of the extra
406   // parsing required for the Extended values.  At the end of this block,
407   // ExDirKind can be assumed to be a valid OpenACCDirectiveKind, so we can
408   // immediately cast it and use it as that.
409   if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) {
410     switch (ExDirKind) {
411     case OpenACCDirectiveKindEx::Invalid: {
412       P.Diag(FirstTok, diag::err_acc_invalid_directive)
413           << 0 << FirstTok.getIdentifierInfo();
414       return OpenACCDirectiveKind::Invalid;
415     }
416     case OpenACCDirectiveKindEx::Enter:
417     case OpenACCDirectiveKindEx::Exit:
418       return ParseOpenACCEnterExitDataDirective(P, FirstTok, ExDirKind);
419     }
420   }
421 
422   OpenACCDirectiveKind DirKind = static_cast<OpenACCDirectiveKind>(ExDirKind);
423 
424   // Combined Constructs allows parallel loop, serial loop, or kernels loop. Any
425   // other attempt at a combined construct will be diagnosed as an invalid
426   // clause.
427   Token SecondTok = P.getCurToken();
428   if (!SecondTok.isAnnotation() &&
429       isOpenACCDirectiveKind(OpenACCDirectiveKind::Loop, SecondTok)) {
430     switch (DirKind) {
431     default:
432       // Nothing to do except in the below cases, as they should be diagnosed as
433       // a clause.
434       break;
435     case OpenACCDirectiveKind::Parallel:
436       P.ConsumeToken();
437       return OpenACCDirectiveKind::ParallelLoop;
438     case OpenACCDirectiveKind::Serial:
439       P.ConsumeToken();
440       return OpenACCDirectiveKind::SerialLoop;
441     case OpenACCDirectiveKind::Kernels:
442       P.ConsumeToken();
443       return OpenACCDirectiveKind::KernelsLoop;
444     }
445   }
446 
447   return DirKind;
448 }
449 
450 enum ClauseParensKind {
451   None,
452   Optional,
453   Required
454 };
455 
456 ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind,
457                                      OpenACCClauseKind Kind) {
458   switch (Kind) {
459   case OpenACCClauseKind::Self:
460     return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required
461                                                    : ClauseParensKind::Optional;
462   case OpenACCClauseKind::Worker:
463   case OpenACCClauseKind::Vector:
464     return ClauseParensKind::Optional;
465 
466   case OpenACCClauseKind::Default:
467   case OpenACCClauseKind::If:
468   case OpenACCClauseKind::Create:
469   case OpenACCClauseKind::Copy:
470   case OpenACCClauseKind::CopyIn:
471   case OpenACCClauseKind::CopyOut:
472   case OpenACCClauseKind::UseDevice:
473   case OpenACCClauseKind::NoCreate:
474   case OpenACCClauseKind::Present:
475   case OpenACCClauseKind::DevicePtr:
476   case OpenACCClauseKind::Attach:
477   case OpenACCClauseKind::Detach:
478   case OpenACCClauseKind::Private:
479   case OpenACCClauseKind::FirstPrivate:
480   case OpenACCClauseKind::Delete:
481   case OpenACCClauseKind::DeviceResident:
482   case OpenACCClauseKind::Device:
483   case OpenACCClauseKind::Link:
484   case OpenACCClauseKind::Host:
485   case OpenACCClauseKind::Reduction:
486   case OpenACCClauseKind::Collapse:
487   case OpenACCClauseKind::Bind:
488   case OpenACCClauseKind::VectorLength:
489   case OpenACCClauseKind::NumGangs:
490   case OpenACCClauseKind::NumWorkers:
491   case OpenACCClauseKind::DeviceNum:
492   case OpenACCClauseKind::DefaultAsync:
493   case OpenACCClauseKind::DeviceType:
494   case OpenACCClauseKind::DType:
495     return ClauseParensKind::Required;
496 
497   case OpenACCClauseKind::Auto:
498   case OpenACCClauseKind::Finalize:
499   case OpenACCClauseKind::IfPresent:
500   case OpenACCClauseKind::Independent:
501   case OpenACCClauseKind::Invalid:
502   case OpenACCClauseKind::NoHost:
503   case OpenACCClauseKind::Seq:
504     return ClauseParensKind::None;
505   }
506   llvm_unreachable("Unhandled clause kind");
507 }
508 
509 bool ClauseHasOptionalParens(OpenACCDirectiveKind DirKind,
510                              OpenACCClauseKind Kind) {
511   return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional;
512 }
513 
514 bool ClauseHasRequiredParens(OpenACCDirectiveKind DirKind,
515                              OpenACCClauseKind Kind) {
516   return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required;
517 }
518 
519 ExprResult ParseOpenACCConditionalExpr(Parser &P) {
520   // FIXME: It isn't clear if the spec saying 'condition' means the same as
521   // it does in an if/while/etc (See ParseCXXCondition), however as it was
522   // written with Fortran/C in mind, we're going to assume it just means an
523   // 'expression evaluating to boolean'.
524   return P.getActions().CorrectDelayedTyposInExpr(P.ParseExpression());
525 }
526 
527 // Skip until we see the end of pragma token, but don't consume it. This is us
528 // just giving up on the rest of the pragma so we can continue executing. We
529 // have to do this because 'SkipUntil' considers paren balancing, which isn't
530 // what we want.
531 void SkipUntilEndOfDirective(Parser &P) {
532   while (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
533     P.ConsumeAnyToken();
534 }
535 
536 } // namespace
537 
538 // OpenACC 3.3, section 1.7:
539 // To simplify the specification and convey appropriate constraint information,
540 // a pqr-list is a comma-separated list of pdr items. The one exception is a
541 // clause-list, which is a list of one or more clauses optionally separated by
542 // commas.
543 void Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) {
544   bool FirstClause = true;
545   while (getCurToken().isNot(tok::annot_pragma_openacc_end)) {
546     // Comma is optional in a clause-list.
547     if (!FirstClause && getCurToken().is(tok::comma))
548       ConsumeToken();
549     FirstClause = false;
550 
551     // Recovering from a bad clause is really difficult, so we just give up on
552     // error.
553     if (ParseOpenACCClause(DirKind)) {
554       SkipUntilEndOfDirective(*this);
555       return;
556     }
557   }
558 }
559 
560 ExprResult Parser::ParseOpenACCIntExpr() {
561   // FIXME: this is required to be an integer expression (or dependent), so we
562   // should ensure that is the case by passing this to SEMA here.
563   return getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
564 }
565 
566 bool Parser::ParseOpenACCClauseVarList(OpenACCClauseKind Kind) {
567   // FIXME: Future clauses will require 'special word' parsing, check for one,
568   // then parse it based on whether it is a clause that requires a 'special
569   // word'.
570   (void)Kind;
571 
572   // If the var parsing fails, skip until the end of the directive as this is
573   // an expression and gets messy if we try to continue otherwise.
574   if (ParseOpenACCVar())
575     return true;
576 
577   while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
578     ExpectAndConsume(tok::comma);
579 
580     // If the var parsing fails, skip until the end of the directive as this is
581     // an expression and gets messy if we try to continue otherwise.
582     if (ParseOpenACCVar())
583       return true;
584   }
585   return false;
586 }
587 
588 /// OpenACC 3.3 Section 2.4:
589 /// The argument to the device_type clause is a comma-separated list of one or
590 /// more device architecture name identifiers, or an asterisk.
591 ///
592 /// The syntax of the device_type clause is
593 /// device_type( * )
594 /// device_type( device-type-list )
595 ///
596 /// The device_type clause may be abbreviated to dtype.
597 bool Parser::ParseOpenACCDeviceTypeList() {
598 
599   if (expectIdentifierOrKeyword(*this)) {
600     SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
601               Parser::StopBeforeMatch);
602     return false;
603   }
604   ConsumeToken();
605 
606   while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
607     ExpectAndConsume(tok::comma);
608 
609     if (expectIdentifierOrKeyword(*this)) {
610       SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
611                 Parser::StopBeforeMatch);
612       return false;
613     }
614     ConsumeToken();
615   }
616   return false;
617 }
618 
619 // The OpenACC Clause List is a comma or space-delimited list of clauses (see
620 // the comment on ParseOpenACCClauseList).  The concept of a 'clause' doesn't
621 // really have its owner grammar and each individual one has its own definition.
622 // However, they all are named with a single-identifier (or auto/default!)
623 // token, followed in some cases by either braces or parens.
624 bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) {
625   // A number of clause names are actually keywords, so accept a keyword that
626   // can be converted to a name.
627   if (expectIdentifierOrKeyword(*this))
628     return true;
629 
630   OpenACCClauseKind Kind = getOpenACCClauseKind(getCurToken());
631 
632   if (Kind == OpenACCClauseKind::Invalid)
633     return Diag(getCurToken(), diag::err_acc_invalid_clause)
634            << getCurToken().getIdentifierInfo();
635 
636   // Consume the clause name.
637   ConsumeToken();
638 
639   return ParseOpenACCClauseParams(DirKind, Kind);
640 }
641 
642 bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
643                                       OpenACCClauseKind Kind) {
644   BalancedDelimiterTracker Parens(*this, tok::l_paren,
645                                   tok::annot_pragma_openacc_end);
646 
647   if (ClauseHasRequiredParens(DirKind, Kind)) {
648     if (Parens.expectAndConsume()) {
649       // We are missing a paren, so assume that the person just forgot the
650       // parameter.  Return 'false' so we try to continue on and parse the next
651       // clause.
652       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end,
653                 Parser::StopBeforeMatch);
654       return false;
655     }
656 
657     switch (Kind) {
658     case OpenACCClauseKind::Default: {
659       Token DefKindTok = getCurToken();
660 
661       if (expectIdentifierOrKeyword(*this))
662         break;
663 
664       ConsumeToken();
665 
666       if (getOpenACCDefaultClauseKind(DefKindTok) ==
667           OpenACCDefaultClauseKind::Invalid)
668         Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind);
669 
670       break;
671     }
672     case OpenACCClauseKind::If: {
673       ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
674       // An invalid expression can be just about anything, so just give up on
675       // this clause list.
676       if (CondExpr.isInvalid())
677         return true;
678       break;
679     }
680     case OpenACCClauseKind::CopyIn:
681       tryParseAndConsumeSpecialTokenKind(
682           *this, OpenACCSpecialTokenKind::ReadOnly, Kind);
683       if (ParseOpenACCClauseVarList(Kind))
684         return true;
685       break;
686     case OpenACCClauseKind::Create:
687     case OpenACCClauseKind::CopyOut:
688       tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Zero,
689                                          Kind);
690       if (ParseOpenACCClauseVarList(Kind))
691         return true;
692       break;
693     case OpenACCClauseKind::Reduction:
694       // If we're missing a clause-kind (or it is invalid), see if we can parse
695       // the var-list anyway.
696       ParseReductionOperator(*this);
697       if (ParseOpenACCClauseVarList(Kind))
698         return true;
699       break;
700     case OpenACCClauseKind::Self:
701       // The 'self' clause is a var-list instead of a 'condition' in the case of
702       // the 'update' clause, so we have to handle it here.  U se an assert to
703       // make sure we get the right differentiator.
704       assert(DirKind == OpenACCDirectiveKind::Update);
705       LLVM_FALLTHROUGH;
706     case OpenACCClauseKind::Attach:
707     case OpenACCClauseKind::Copy:
708     case OpenACCClauseKind::Delete:
709     case OpenACCClauseKind::Detach:
710     case OpenACCClauseKind::Device:
711     case OpenACCClauseKind::DeviceResident:
712     case OpenACCClauseKind::DevicePtr:
713     case OpenACCClauseKind::FirstPrivate:
714     case OpenACCClauseKind::Host:
715     case OpenACCClauseKind::Link:
716     case OpenACCClauseKind::NoCreate:
717     case OpenACCClauseKind::Present:
718     case OpenACCClauseKind::Private:
719     case OpenACCClauseKind::UseDevice:
720       if (ParseOpenACCClauseVarList(Kind))
721         return true;
722       break;
723     case OpenACCClauseKind::Collapse: {
724       tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Force,
725                                          Kind);
726       ExprResult NumLoops =
727           getActions().CorrectDelayedTyposInExpr(ParseConstantExpression());
728       if (NumLoops.isInvalid())
729         return true;
730       break;
731     }
732     case OpenACCClauseKind::Bind: {
733       ExprResult BindArg = ParseOpenACCBindClauseArgument();
734       if (BindArg.isInvalid())
735         return true;
736       break;
737     }
738     case OpenACCClauseKind::NumGangs:
739     case OpenACCClauseKind::NumWorkers:
740     case OpenACCClauseKind::DeviceNum:
741     case OpenACCClauseKind::DefaultAsync:
742     case OpenACCClauseKind::VectorLength: {
743       ExprResult IntExpr = ParseOpenACCIntExpr();
744       if (IntExpr.isInvalid())
745         return true;
746       break;
747     }
748     case OpenACCClauseKind::DType:
749     case OpenACCClauseKind::DeviceType:
750       if (getCurToken().is(tok::star)) {
751         // FIXME: We want to mark that this is an 'everything else' type of
752         // device_type in Sema.
753         ConsumeToken();
754       } else if (ParseOpenACCDeviceTypeList()) {
755         return true;
756       }
757       break;
758     default:
759       llvm_unreachable("Not a required parens type?");
760     }
761 
762     return Parens.consumeClose();
763   } else if (ClauseHasOptionalParens(DirKind, Kind)) {
764     if (!Parens.consumeOpen()) {
765       switch (Kind) {
766       case OpenACCClauseKind::Self: {
767         assert(DirKind != OpenACCDirectiveKind::Update);
768         ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
769         // An invalid expression can be just about anything, so just give up on
770         // this clause list.
771         if (CondExpr.isInvalid())
772           return true;
773         break;
774       }
775       case OpenACCClauseKind::Vector:
776       case OpenACCClauseKind::Worker: {
777         tryParseAndConsumeSpecialTokenKind(*this,
778                                            Kind == OpenACCClauseKind::Vector
779                                                ? OpenACCSpecialTokenKind::Length
780                                                : OpenACCSpecialTokenKind::Num,
781                                            Kind);
782         ExprResult IntExpr = ParseOpenACCIntExpr();
783         if (IntExpr.isInvalid())
784           return true;
785         break;
786       }
787       default:
788         llvm_unreachable("Not an optional parens type?");
789       }
790       Parens.consumeClose();
791     }
792   }
793   return false;
794 }
795 
796 /// OpenACC 3.3, section 2.16:
797 /// In this section and throughout the specification, the term wait-argument
798 /// means:
799 /// [ devnum : int-expr : ] [ queues : ] async-argument-list
800 bool Parser::ParseOpenACCWaitArgument() {
801   // [devnum : int-expr : ]
802   if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) &&
803       NextToken().is(tok::colon)) {
804     // Consume devnum.
805     ConsumeToken();
806     // Consume colon.
807     ConsumeToken();
808 
809     ExprResult IntExpr =
810         getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
811     if (IntExpr.isInvalid())
812       return true;
813 
814     if (ExpectAndConsume(tok::colon))
815       return true;
816   }
817 
818   // [ queues : ]
819   if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) &&
820       NextToken().is(tok::colon)) {
821     // Consume queues.
822     ConsumeToken();
823     // Consume colon.
824     ConsumeToken();
825   }
826 
827   // OpenACC 3.3, section 2.16:
828   // the term 'async-argument' means a nonnegative scalar integer expression, or
829   // one of the special values 'acc_async_noval' or 'acc_async_sync', as defined
830   // in the C header file and the Fortran opacc module.
831   //
832   // We are parsing this simply as list of assignment expressions (to avoid
833   // comma being troublesome), and will ensure it is an integral type.  The
834   // 'special' types are defined as macros, so we can't really check those
835   // (other than perhaps as values at one point?), but the standard does say it
836   // is implementation-defined to use any other negative value.
837   //
838   //
839   bool FirstArg = true;
840   while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
841     if (!FirstArg) {
842       if (ExpectAndConsume(tok::comma))
843         return true;
844     }
845     FirstArg = false;
846 
847     ExprResult CurArg =
848         getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
849 
850     if (CurArg.isInvalid())
851       return true;
852   }
853 
854   return false;
855 }
856 
857 ExprResult Parser::ParseOpenACCIDExpression() {
858   ExprResult Res;
859   if (getLangOpts().CPlusPlus) {
860     Res = ParseCXXIdExpression(/*isAddressOfOperand=*/true);
861   } else {
862     // There isn't anything quite the same as ParseCXXIdExpression for C, so we
863     // need to get the identifier, then call into Sema ourselves.
864 
865     if (Tok.isNot(tok::identifier)) {
866       Diag(Tok, diag::err_expected) << tok::identifier;
867       return ExprError();
868     }
869 
870     Token FuncName = getCurToken();
871     UnqualifiedId Name;
872     CXXScopeSpec ScopeSpec;
873     SourceLocation TemplateKWLoc;
874     Name.setIdentifier(FuncName.getIdentifierInfo(), ConsumeToken());
875 
876     // Ensure this is a valid identifier. We don't accept causing implicit
877     // function declarations per the spec, so always claim to not have trailing
878     // L Paren.
879     Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc,
880                                     Name, /*HasTrailingLParen=*/false,
881                                     /*isAddressOfOperand=*/false);
882   }
883 
884   return getActions().CorrectDelayedTyposInExpr(Res);
885 }
886 
887 ExprResult Parser::ParseOpenACCBindClauseArgument() {
888   // OpenACC 3.3 section 2.15:
889   // The bind clause specifies the name to use when calling the procedure on a
890   // device other than the host. If the name is specified as an identifier, it
891   // is called as if that name were specified in the language being compiled. If
892   // the name is specified as a string, the string is used for the procedure
893   // name unmodified.
894   if (getCurToken().is(tok::r_paren)) {
895     Diag(getCurToken(), diag::err_acc_incorrect_bind_arg);
896     return ExprError();
897   }
898 
899   if (tok::isStringLiteral(getCurToken().getKind()))
900     return getActions().CorrectDelayedTyposInExpr(ParseStringLiteralExpression(
901         /*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/true));
902 
903   return ParseOpenACCIDExpression();
904 }
905 
906 /// OpenACC 3.3, section 1.6:
907 /// In this spec, a 'var' (in italics) is one of the following:
908 /// - a variable name (a scalar, array, or compisite variable name)
909 /// - a subarray specification with subscript ranges
910 /// - an array element
911 /// - a member of a composite variable
912 /// - a common block name between slashes (fortran only)
913 bool Parser::ParseOpenACCVar() {
914   OpenACCArraySectionRAII ArraySections(*this);
915   ExprResult Res =
916       getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
917   return Res.isInvalid();
918 }
919 
920 /// OpenACC 3.3, section 2.10:
921 /// In C and C++, the syntax of the cache directive is:
922 ///
923 /// #pragma acc cache ([readonly:]var-list) new-line
924 void Parser::ParseOpenACCCacheVarList() {
925   // If this is the end of the line, just return 'false' and count on the close
926   // paren diagnostic to catch the issue.
927   if (getCurToken().isAnnotation())
928     return;
929 
930   // The VarList is an optional `readonly:` followed by a list of a variable
931   // specifications. Consume something that looks like a 'tag', and diagnose if
932   // it isn't 'readonly'.
933   if (tryParseAndConsumeSpecialTokenKind(*this,
934                                          OpenACCSpecialTokenKind::ReadOnly,
935                                          OpenACCDirectiveKind::Cache)) {
936     // FIXME: Record that this is a 'readonly' so that we can use that during
937     // Sema/AST generation.
938   }
939 
940   bool FirstArray = true;
941   while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
942     if (!FirstArray)
943       ExpectAndConsume(tok::comma);
944     FirstArray = false;
945 
946     // OpenACC 3.3, section 2.10:
947     // A 'var' in a cache directive must be a single array element or a simple
948     // subarray.  In C and C++, a simple subarray is an array name followed by
949     // an extended array range specification in brackets, with a start and
950     // length such as:
951     //
952     // arr[lower:length]
953     //
954     if (ParseOpenACCVar())
955       SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, tok::comma,
956                 StopBeforeMatch);
957   }
958 }
959 
960 void Parser::ParseOpenACCDirective() {
961   OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this);
962 
963   // Once we've parsed the construct/directive name, some have additional
964   // specifiers that need to be taken care of. Atomic has an 'atomic-clause'
965   // that needs to be parsed.
966   if (DirKind == OpenACCDirectiveKind::Atomic)
967     ParseOpenACCAtomicKind(*this);
968 
969   // We've successfully parsed the construct/directive name, however a few of
970   // the constructs have optional parens that contain further details.
971   BalancedDelimiterTracker T(*this, tok::l_paren,
972                              tok::annot_pragma_openacc_end);
973 
974   if (!T.consumeOpen()) {
975     switch (DirKind) {
976     default:
977       Diag(T.getOpenLocation(), diag::err_acc_invalid_open_paren);
978       T.skipToEnd();
979       break;
980     case OpenACCDirectiveKind::Routine: {
981       // Routine has an optional paren-wrapped name of a function in the local
982       // scope. We parse the name, emitting any diagnostics
983       ExprResult RoutineName = ParseOpenACCIDExpression();
984       // If the routine name is invalid, just skip until the closing paren to
985       // recover more gracefully.
986       if (RoutineName.isInvalid())
987         T.skipToEnd();
988       else
989         T.consumeClose();
990       break;
991     }
992     case OpenACCDirectiveKind::Cache:
993       ParseOpenACCCacheVarList();
994       // The ParseOpenACCCacheVarList function manages to recover from failures,
995       // so we can always consume the close.
996       T.consumeClose();
997       break;
998     case OpenACCDirectiveKind::Wait:
999       // OpenACC has an optional paren-wrapped 'wait-argument'.
1000       if (ParseOpenACCWaitArgument())
1001         T.skipToEnd();
1002       else
1003         T.consumeClose();
1004       break;
1005     }
1006   } else if (DirKind == OpenACCDirectiveKind::Cache) {
1007     // Cache's paren var-list is required, so error here if it isn't provided.
1008     // We know that the consumeOpen above left the first non-paren here, so
1009     // diagnose, then continue as if it was completely omitted.
1010     Diag(Tok, diag::err_expected) << tok::l_paren;
1011   }
1012 
1013   // Parses the list of clauses, if present.
1014   ParseOpenACCClauseList(DirKind);
1015 
1016   Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
1017   assert(Tok.is(tok::annot_pragma_openacc_end) &&
1018          "Didn't parse all OpenACC Clauses");
1019   ConsumeAnnotationToken();
1020 }
1021 
1022 // Parse OpenACC directive on a declaration.
1023 Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() {
1024   assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token");
1025 
1026   ParsingOpenACCDirectiveRAII DirScope(*this);
1027   ConsumeAnnotationToken();
1028 
1029   ParseOpenACCDirective();
1030 
1031   return nullptr;
1032 }
1033 
1034 // Parse OpenACC Directive on a Statement.
1035 StmtResult Parser::ParseOpenACCDirectiveStmt() {
1036   assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token");
1037 
1038   ParsingOpenACCDirectiveRAII DirScope(*this);
1039   ConsumeAnnotationToken();
1040 
1041   ParseOpenACCDirective();
1042 
1043   return StmtEmpty();
1044 }
1045