xref: /freebsd/contrib/llvm-project/clang/lib/Parse/ParseOpenACC.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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("auto", OpenACCClauseKind::Auto)
93       .Case("default", OpenACCClauseKind::Default)
94       .Case("finalize", OpenACCClauseKind::Finalize)
95       .Case("if", OpenACCClauseKind::If)
96       .Case("if_present", OpenACCClauseKind::IfPresent)
97       .Case("independent", OpenACCClauseKind::Independent)
98       .Case("nohost", OpenACCClauseKind::NoHost)
99       .Case("self", OpenACCClauseKind::Self)
100       .Case("seq", OpenACCClauseKind::Seq)
101       .Case("vector", OpenACCClauseKind::Vector)
102       .Case("worker", OpenACCClauseKind::Worker)
103       .Default(OpenACCClauseKind::Invalid);
104 }
105 
106 // Since 'atomic' is effectively a compound directive, this will decode the
107 // second part of the directive.
108 OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) {
109   if (!Tok.is(tok::identifier))
110     return OpenACCAtomicKind::Invalid;
111   return llvm::StringSwitch<OpenACCAtomicKind>(
112              Tok.getIdentifierInfo()->getName())
113       .Case("read", OpenACCAtomicKind::Read)
114       .Case("write", OpenACCAtomicKind::Write)
115       .Case("update", OpenACCAtomicKind::Update)
116       .Case("capture", OpenACCAtomicKind::Capture)
117       .Default(OpenACCAtomicKind::Invalid);
118 }
119 
120 OpenACCDefaultClauseKind getOpenACCDefaultClauseKind(Token Tok) {
121   if (!Tok.is(tok::identifier))
122     return OpenACCDefaultClauseKind::Invalid;
123 
124   return llvm::StringSwitch<OpenACCDefaultClauseKind>(
125              Tok.getIdentifierInfo()->getName())
126       .Case("none", OpenACCDefaultClauseKind::None)
127       .Case("present", OpenACCDefaultClauseKind::Present)
128       .Default(OpenACCDefaultClauseKind::Invalid);
129 }
130 
131 enum class OpenACCSpecialTokenKind {
132   ReadOnly,
133   DevNum,
134   Queues,
135 };
136 
137 bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) {
138   if (!Tok.is(tok::identifier))
139     return false;
140 
141   switch (Kind) {
142   case OpenACCSpecialTokenKind::ReadOnly:
143     return Tok.getIdentifierInfo()->isStr("readonly");
144   case OpenACCSpecialTokenKind::DevNum:
145     return Tok.getIdentifierInfo()->isStr("devnum");
146   case OpenACCSpecialTokenKind::Queues:
147     return Tok.getIdentifierInfo()->isStr("queues");
148   }
149   llvm_unreachable("Unknown 'Kind' Passed");
150 }
151 
152 bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) {
153   if (!Tok.is(tok::identifier))
154     return false;
155 
156   switch (Kind) {
157   case OpenACCDirectiveKind::Parallel:
158     return Tok.getIdentifierInfo()->isStr("parallel");
159   case OpenACCDirectiveKind::Serial:
160     return Tok.getIdentifierInfo()->isStr("serial");
161   case OpenACCDirectiveKind::Kernels:
162     return Tok.getIdentifierInfo()->isStr("kernels");
163   case OpenACCDirectiveKind::Data:
164     return Tok.getIdentifierInfo()->isStr("data");
165   case OpenACCDirectiveKind::HostData:
166     return Tok.getIdentifierInfo()->isStr("host_data");
167   case OpenACCDirectiveKind::Loop:
168     return Tok.getIdentifierInfo()->isStr("loop");
169   case OpenACCDirectiveKind::Cache:
170     return Tok.getIdentifierInfo()->isStr("cache");
171 
172   case OpenACCDirectiveKind::ParallelLoop:
173   case OpenACCDirectiveKind::SerialLoop:
174   case OpenACCDirectiveKind::KernelsLoop:
175   case OpenACCDirectiveKind::EnterData:
176   case OpenACCDirectiveKind::ExitData:
177     return false;
178 
179   case OpenACCDirectiveKind::Atomic:
180     return Tok.getIdentifierInfo()->isStr("atomic");
181   case OpenACCDirectiveKind::Routine:
182     return Tok.getIdentifierInfo()->isStr("routine");
183   case OpenACCDirectiveKind::Declare:
184     return Tok.getIdentifierInfo()->isStr("declare");
185   case OpenACCDirectiveKind::Init:
186     return Tok.getIdentifierInfo()->isStr("init");
187   case OpenACCDirectiveKind::Shutdown:
188     return Tok.getIdentifierInfo()->isStr("shutdown");
189   case OpenACCDirectiveKind::Set:
190     return Tok.getIdentifierInfo()->isStr("set");
191   case OpenACCDirectiveKind::Update:
192     return Tok.getIdentifierInfo()->isStr("update");
193   case OpenACCDirectiveKind::Wait:
194     return Tok.getIdentifierInfo()->isStr("wait");
195   case OpenACCDirectiveKind::Invalid:
196     return false;
197   }
198   llvm_unreachable("Unknown 'Kind' Passed");
199 }
200 
201 /// Used for cases where we expect an identifier-like token, but don't want to
202 /// give awkward error messages in cases where it is accidentially a keyword.
203 bool expectIdentifierOrKeyword(Parser &P) {
204   Token Tok = P.getCurToken();
205 
206   if (Tok.is(tok::identifier))
207     return false;
208 
209   if (!Tok.isAnnotation() && Tok.getIdentifierInfo() &&
210       Tok.getIdentifierInfo()->isKeyword(P.getLangOpts()))
211     return false;
212 
213   P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier;
214   return true;
215 }
216 
217 OpenACCDirectiveKind
218 ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok,
219                                    OpenACCDirectiveKindEx ExtDirKind) {
220   Token SecondTok = P.getCurToken();
221 
222   if (SecondTok.isAnnotation()) {
223     P.Diag(FirstTok, diag::err_acc_invalid_directive)
224         << 0 << FirstTok.getIdentifierInfo();
225     return OpenACCDirectiveKind::Invalid;
226   }
227 
228   // Consume the second name anyway, this way we can continue on without making
229   // this oddly look like a clause.
230   P.ConsumeAnyToken();
231 
232   if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) {
233     if (!SecondTok.is(tok::identifier))
234       P.Diag(SecondTok, diag::err_expected) << tok::identifier;
235     else
236       P.Diag(FirstTok, diag::err_acc_invalid_directive)
237           << 1 << FirstTok.getIdentifierInfo()->getName()
238           << SecondTok.getIdentifierInfo()->getName();
239     return OpenACCDirectiveKind::Invalid;
240   }
241 
242   return ExtDirKind == OpenACCDirectiveKindEx::Enter
243              ? OpenACCDirectiveKind::EnterData
244              : OpenACCDirectiveKind::ExitData;
245 }
246 
247 OpenACCAtomicKind ParseOpenACCAtomicKind(Parser &P) {
248   Token AtomicClauseToken = P.getCurToken();
249 
250   // #pragma acc atomic is equivilent to update:
251   if (AtomicClauseToken.isAnnotation())
252     return OpenACCAtomicKind::Update;
253 
254   OpenACCAtomicKind AtomicKind = getOpenACCAtomicKind(AtomicClauseToken);
255 
256   // If we don't know what this is, treat it as 'nothing', and treat the rest of
257   // this as a clause list, which, despite being invalid, is likely what the
258   // user was trying to do.
259   if (AtomicKind == OpenACCAtomicKind::Invalid)
260     return OpenACCAtomicKind::Update;
261 
262   P.ConsumeToken();
263   return AtomicKind;
264 }
265 
266 // Parse and consume the tokens for OpenACC Directive/Construct kinds.
267 OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
268   Token FirstTok = P.getCurToken();
269 
270   // Just #pragma acc can get us immediately to the end, make sure we don't
271   // introspect on the spelling before then.
272   if (FirstTok.isNot(tok::identifier)) {
273     P.Diag(FirstTok, diag::err_acc_missing_directive);
274 
275     if (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
276       P.ConsumeAnyToken();
277 
278     return OpenACCDirectiveKind::Invalid;
279   }
280 
281   P.ConsumeToken();
282 
283   OpenACCDirectiveKindEx ExDirKind = getOpenACCDirectiveKind(FirstTok);
284 
285   // OpenACCDirectiveKindEx is meant to be an extended list
286   // over OpenACCDirectiveKind, so any value below Invalid is one of the
287   // OpenACCDirectiveKind values.  This switch takes care of all of the extra
288   // parsing required for the Extended values.  At the end of this block,
289   // ExDirKind can be assumed to be a valid OpenACCDirectiveKind, so we can
290   // immediately cast it and use it as that.
291   if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) {
292     switch (ExDirKind) {
293     case OpenACCDirectiveKindEx::Invalid: {
294       P.Diag(FirstTok, diag::err_acc_invalid_directive)
295           << 0 << FirstTok.getIdentifierInfo();
296       return OpenACCDirectiveKind::Invalid;
297     }
298     case OpenACCDirectiveKindEx::Enter:
299     case OpenACCDirectiveKindEx::Exit:
300       return ParseOpenACCEnterExitDataDirective(P, FirstTok, ExDirKind);
301     }
302   }
303 
304   OpenACCDirectiveKind DirKind = static_cast<OpenACCDirectiveKind>(ExDirKind);
305 
306   // Combined Constructs allows parallel loop, serial loop, or kernels loop. Any
307   // other attempt at a combined construct will be diagnosed as an invalid
308   // clause.
309   Token SecondTok = P.getCurToken();
310   if (!SecondTok.isAnnotation() &&
311       isOpenACCDirectiveKind(OpenACCDirectiveKind::Loop, SecondTok)) {
312     switch (DirKind) {
313     default:
314       // Nothing to do except in the below cases, as they should be diagnosed as
315       // a clause.
316       break;
317     case OpenACCDirectiveKind::Parallel:
318       P.ConsumeToken();
319       return OpenACCDirectiveKind::ParallelLoop;
320     case OpenACCDirectiveKind::Serial:
321       P.ConsumeToken();
322       return OpenACCDirectiveKind::SerialLoop;
323     case OpenACCDirectiveKind::Kernels:
324       P.ConsumeToken();
325       return OpenACCDirectiveKind::KernelsLoop;
326     }
327   }
328 
329   return DirKind;
330 }
331 
332 bool ClauseHasOptionalParens(OpenACCClauseKind Kind) {
333   return Kind == OpenACCClauseKind::Self;
334 }
335 
336 bool ClauseHasRequiredParens(OpenACCClauseKind Kind) {
337   return Kind == OpenACCClauseKind::Default || Kind == OpenACCClauseKind::If;
338 }
339 
340 ExprResult ParseOpenACCConditionalExpr(Parser &P) {
341   // FIXME: It isn't clear if the spec saying 'condition' means the same as
342   // it does in an if/while/etc (See ParseCXXCondition), however as it was
343   // written with Fortran/C in mind, we're going to assume it just means an
344   // 'expression evaluating to boolean'.
345   return P.getActions().CorrectDelayedTyposInExpr(P.ParseExpression());
346 }
347 
348 bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
349   BalancedDelimiterTracker Parens(P, tok::l_paren,
350                                   tok::annot_pragma_openacc_end);
351 
352   if (ClauseHasRequiredParens(Kind)) {
353     if (Parens.expectAndConsume()) {
354       // We are missing a paren, so assume that the person just forgot the
355       // parameter.  Return 'false' so we try to continue on and parse the next
356       // clause.
357       P.SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end,
358                   Parser::StopBeforeMatch);
359       return false;
360     }
361 
362     switch (Kind) {
363     case OpenACCClauseKind::Default: {
364       Token DefKindTok = P.getCurToken();
365 
366       if (expectIdentifierOrKeyword(P))
367         break;
368 
369       P.ConsumeToken();
370 
371       if (getOpenACCDefaultClauseKind(DefKindTok) ==
372           OpenACCDefaultClauseKind::Invalid)
373         P.Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind);
374 
375       break;
376     }
377     case OpenACCClauseKind::If: {
378       ExprResult CondExpr = ParseOpenACCConditionalExpr(P);
379       // An invalid expression can be just about anything, so just give up on
380       // this clause list.
381       if (CondExpr.isInvalid())
382         return true;
383       break;
384     }
385     default:
386       llvm_unreachable("Not a required parens type?");
387     }
388 
389     return Parens.consumeClose();
390   } else if (ClauseHasOptionalParens(Kind)) {
391     if (!Parens.consumeOpen()) {
392       switch (Kind) {
393       case OpenACCClauseKind::Self: {
394         ExprResult CondExpr = ParseOpenACCConditionalExpr(P);
395         // An invalid expression can be just about anything, so just give up on
396         // this clause list.
397         if (CondExpr.isInvalid())
398           return true;
399         break;
400       }
401       default:
402         llvm_unreachable("Not an optional parens type?");
403       }
404       Parens.consumeClose();
405     }
406   }
407   return false;
408 }
409 
410 // The OpenACC Clause List is a comma or space-delimited list of clauses (see
411 // the comment on ParseOpenACCClauseList).  The concept of a 'clause' doesn't
412 // really have its owner grammar and each individual one has its own definition.
413 // However, they all are named with a single-identifier (or auto/default!)
414 // token, followed in some cases by either braces or parens.
415 bool ParseOpenACCClause(Parser &P) {
416   // A number of clause names are actually keywords, so accept a keyword that
417   // can be converted to a name.
418   if (expectIdentifierOrKeyword(P))
419     return true;
420 
421   OpenACCClauseKind Kind = getOpenACCClauseKind(P.getCurToken());
422 
423   if (Kind == OpenACCClauseKind::Invalid)
424     return P.Diag(P.getCurToken(), diag::err_acc_invalid_clause)
425            << P.getCurToken().getIdentifierInfo();
426 
427   // Consume the clause name.
428   P.ConsumeToken();
429 
430   return ParseOpenACCClauseParams(P, Kind);
431 }
432 
433 // Skip until we see the end of pragma token, but don't consume it. This is us
434 // just giving up on the rest of the pragma so we can continue executing. We
435 // have to do this because 'SkipUntil' considers paren balancing, which isn't
436 // what we want.
437 void SkipUntilEndOfDirective(Parser &P) {
438   while (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
439     P.ConsumeAnyToken();
440 }
441 
442 // OpenACC 3.3, section 1.7:
443 // To simplify the specification and convey appropriate constraint information,
444 // a pqr-list is a comma-separated list of pdr items. The one exception is a
445 // clause-list, which is a list of one or more clauses optionally separated by
446 // commas.
447 void ParseOpenACCClauseList(Parser &P) {
448   bool FirstClause = true;
449   while (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) {
450     // Comma is optional in a clause-list.
451     if (!FirstClause && P.getCurToken().is(tok::comma))
452       P.ConsumeToken();
453     FirstClause = false;
454 
455     // Recovering from a bad clause is really difficult, so we just give up on
456     // error.
457     if (ParseOpenACCClause(P)) {
458       SkipUntilEndOfDirective(P);
459       return;
460     }
461   }
462 }
463 
464 } // namespace
465 
466 /// OpenACC 3.3, section 2.16:
467 /// In this section and throughout the specification, the term wait-argument
468 /// means:
469 /// [ devnum : int-expr : ] [ queues : ] async-argument-list
470 bool Parser::ParseOpenACCWaitArgument() {
471   // [devnum : int-expr : ]
472   if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) &&
473       NextToken().is(tok::colon)) {
474     // Consume devnum.
475     ConsumeToken();
476     // Consume colon.
477     ConsumeToken();
478 
479     ExprResult IntExpr =
480         getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
481     if (IntExpr.isInvalid())
482       return true;
483 
484     if (ExpectAndConsume(tok::colon))
485       return true;
486   }
487 
488   // [ queues : ]
489   if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) &&
490       NextToken().is(tok::colon)) {
491     // Consume queues.
492     ConsumeToken();
493     // Consume colon.
494     ConsumeToken();
495   }
496 
497   // OpenACC 3.3, section 2.16:
498   // the term 'async-argument' means a nonnegative scalar integer expression, or
499   // one of the special values 'acc_async_noval' or 'acc_async_sync', as defined
500   // in the C header file and the Fortran opacc module.
501   //
502   // We are parsing this simply as list of assignment expressions (to avoid
503   // comma being troublesome), and will ensure it is an integral type.  The
504   // 'special' types are defined as macros, so we can't really check those
505   // (other than perhaps as values at one point?), but the standard does say it
506   // is implementation-defined to use any other negative value.
507   //
508   //
509   bool FirstArg = true;
510   while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
511     if (!FirstArg) {
512       if (ExpectAndConsume(tok::comma))
513         return true;
514     }
515     FirstArg = false;
516 
517     ExprResult CurArg =
518         getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
519 
520     if (CurArg.isInvalid())
521       return true;
522   }
523 
524   return false;
525 }
526 
527 ExprResult Parser::ParseOpenACCIDExpression() {
528   ExprResult Res;
529   if (getLangOpts().CPlusPlus) {
530     Res = ParseCXXIdExpression(/*isAddressOfOperand=*/false);
531   } else {
532     // There isn't anything quite the same as ParseCXXIdExpression for C, so we
533     // need to get the identifier, then call into Sema ourselves.
534 
535     if (Tok.isNot(tok::identifier)) {
536       Diag(Tok, diag::err_expected) << tok::identifier;
537       return ExprError();
538     }
539 
540     Token FuncName = getCurToken();
541     UnqualifiedId Name;
542     CXXScopeSpec ScopeSpec;
543     SourceLocation TemplateKWLoc;
544     Name.setIdentifier(FuncName.getIdentifierInfo(), ConsumeToken());
545 
546     // Ensure this is a valid identifier. We don't accept causing implicit
547     // function declarations per the spec, so always claim to not have trailing
548     // L Paren.
549     Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc,
550                                     Name, /*HasTrailingLParen=*/false,
551                                     /*isAddressOfOperand=*/false);
552   }
553 
554   return getActions().CorrectDelayedTyposInExpr(Res);
555 }
556 
557 /// OpenACC 3.3, section 2.10:
558 /// A 'var' in a cache directive must be a single array element or a simple
559 /// subarray.  In C and C++, a simple subarray is an array name followed by an
560 /// extended array range specification in brackets, with a start and length such
561 /// as:
562 ///
563 /// arr[lower:length]
564 ///
565 bool Parser::ParseOpenACCCacheVar() {
566   ExprResult ArrayName = ParseOpenACCIDExpression();
567   if (ArrayName.isInvalid())
568     return true;
569 
570   // If the expression is invalid, just continue parsing the brackets, there
571   // is likely other useful diagnostics we can emit inside of those.
572 
573   BalancedDelimiterTracker SquareBrackets(*this, tok::l_square,
574                                           tok::annot_pragma_openacc_end);
575 
576   // Square brackets are required, so error here, and try to recover by moving
577   // until the next comma, or the close paren/end of pragma.
578   if (SquareBrackets.expectAndConsume()) {
579     SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end,
580               Parser::StopBeforeMatch);
581     return true;
582   }
583 
584   ExprResult Lower = getActions().CorrectDelayedTyposInExpr(ParseExpression());
585   if (Lower.isInvalid())
586     return true;
587 
588   // The 'length' expression is optional, as this could be a single array
589   // element. If there is no colon, we can treat it as that.
590   if (getCurToken().is(tok::colon)) {
591     ConsumeToken();
592     ExprResult Length =
593         getActions().CorrectDelayedTyposInExpr(ParseExpression());
594     if (Length.isInvalid())
595       return true;
596   }
597 
598   // Diagnose the square bracket being in the wrong place and continue.
599   return SquareBrackets.consumeClose();
600 }
601 
602 /// OpenACC 3.3, section 2.10:
603 /// In C and C++, the syntax of the cache directive is:
604 ///
605 /// #pragma acc cache ([readonly:]var-list) new-line
606 void Parser::ParseOpenACCCacheVarList() {
607   // If this is the end of the line, just return 'false' and count on the close
608   // paren diagnostic to catch the issue.
609   if (getCurToken().isAnnotation())
610     return;
611 
612   // The VarList is an optional `readonly:` followed by a list of a variable
613   // specifications.  First, see if we have `readonly:`, else we back-out and
614   // treat it like the beginning of a reference to a potentially-existing
615   // `readonly` variable.
616   if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::ReadOnly, Tok) &&
617       NextToken().is(tok::colon)) {
618     // Consume both tokens.
619     ConsumeToken();
620     ConsumeToken();
621     // FIXME: Record that this is a 'readonly' so that we can use that during
622     // Sema/AST generation.
623   }
624 
625   bool FirstArray = true;
626   while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
627     if (!FirstArray)
628       ExpectAndConsume(tok::comma);
629     FirstArray = false;
630     if (ParseOpenACCCacheVar())
631       SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, tok::comma,
632                 StopBeforeMatch);
633   }
634 }
635 
636 void Parser::ParseOpenACCDirective() {
637   OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this);
638 
639   // Once we've parsed the construct/directive name, some have additional
640   // specifiers that need to be taken care of. Atomic has an 'atomic-clause'
641   // that needs to be parsed.
642   if (DirKind == OpenACCDirectiveKind::Atomic)
643     ParseOpenACCAtomicKind(*this);
644 
645   // We've successfully parsed the construct/directive name, however a few of
646   // the constructs have optional parens that contain further details.
647   BalancedDelimiterTracker T(*this, tok::l_paren,
648                              tok::annot_pragma_openacc_end);
649 
650   if (!T.consumeOpen()) {
651     switch (DirKind) {
652     default:
653       Diag(T.getOpenLocation(), diag::err_acc_invalid_open_paren);
654       T.skipToEnd();
655       break;
656     case OpenACCDirectiveKind::Routine: {
657       // Routine has an optional paren-wrapped name of a function in the local
658       // scope. We parse the name, emitting any diagnostics
659       ExprResult RoutineName = ParseOpenACCIDExpression();
660       // If the routine name is invalid, just skip until the closing paren to
661       // recover more gracefully.
662       if (RoutineName.isInvalid())
663         T.skipToEnd();
664       else
665         T.consumeClose();
666       break;
667     }
668     case OpenACCDirectiveKind::Cache:
669       ParseOpenACCCacheVarList();
670       // The ParseOpenACCCacheVarList function manages to recover from failures,
671       // so we can always consume the close.
672       T.consumeClose();
673       break;
674     case OpenACCDirectiveKind::Wait:
675       // OpenACC has an optional paren-wrapped 'wait-argument'.
676       if (ParseOpenACCWaitArgument())
677         T.skipToEnd();
678       else
679         T.consumeClose();
680       break;
681     }
682   } else if (DirKind == OpenACCDirectiveKind::Cache) {
683     // Cache's paren var-list is required, so error here if it isn't provided.
684     // We know that the consumeOpen above left the first non-paren here, so
685     // diagnose, then continue as if it was completely omitted.
686     Diag(Tok, diag::err_expected) << tok::l_paren;
687   }
688 
689   // Parses the list of clauses, if present.
690   ParseOpenACCClauseList(*this);
691 
692   Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
693   assert(Tok.is(tok::annot_pragma_openacc_end) &&
694          "Didn't parse all OpenACC Clauses");
695   ConsumeAnnotationToken();
696 }
697 
698 // Parse OpenACC directive on a declaration.
699 Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() {
700   assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token");
701 
702   ParsingOpenACCDirectiveRAII DirScope(*this);
703   ConsumeAnnotationToken();
704 
705   ParseOpenACCDirective();
706 
707   return nullptr;
708 }
709 
710 // Parse OpenACC Directive on a Statement.
711 StmtResult Parser::ParseOpenACCDirectiveStmt() {
712   assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token");
713 
714   ParsingOpenACCDirectiveRAII DirScope(*this);
715   ConsumeAnnotationToken();
716 
717   ParseOpenACCDirective();
718 
719   return StmtEmpty();
720 }
721