@@ -76,12 +76,17 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
7676 if (Tok.is (tok::kw_auto))
7777 return OpenACCClauseKind::Auto;
7878
79+ // default is a keyword, so make sure we parse it correctly.
80+ if (Tok.is (tok::kw_default))
81+ return OpenACCClauseKind::Default;
82+
7983 if (!Tok.is (tok::identifier))
8084 return OpenACCClauseKind::Invalid;
8185
8286 return llvm::StringSwitch<OpenACCClauseKind>(
8387 Tok.getIdentifierInfo ()->getName ())
8488 .Case (" auto" , OpenACCClauseKind::Auto)
89+ .Case (" default" , OpenACCClauseKind::Default)
8590 .Case (" finalize" , OpenACCClauseKind::Finalize)
8691 .Case (" if_present" , OpenACCClauseKind::IfPresent)
8792 .Case (" independent" , OpenACCClauseKind::Independent)
@@ -106,6 +111,17 @@ OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) {
106111 .Default (OpenACCAtomicKind::Invalid);
107112}
108113
114+ OpenACCDefaultClauseKind getOpenACCDefaultClauseKind (Token Tok) {
115+ if (!Tok.is (tok::identifier))
116+ return OpenACCDefaultClauseKind::Invalid;
117+
118+ return llvm::StringSwitch<OpenACCDefaultClauseKind>(
119+ Tok.getIdentifierInfo ()->getName ())
120+ .Case (" none" , OpenACCDefaultClauseKind::None)
121+ .Case (" present" , OpenACCDefaultClauseKind::Present)
122+ .Default (OpenACCDefaultClauseKind::Invalid);
123+ }
124+
109125enum class OpenACCSpecialTokenKind {
110126 ReadOnly,
111127 DevNum,
@@ -176,6 +192,22 @@ bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) {
176192 llvm_unreachable (" Unknown 'Kind' Passed" );
177193}
178194
195+ // / Used for cases where we expect an identifier-like token, but don't want to
196+ // / give awkward error messages in cases where it is accidentially a keyword.
197+ bool expectIdentifierOrKeyword (Parser &P) {
198+ Token Tok = P.getCurToken ();
199+
200+ if (Tok.is (tok::identifier))
201+ return false ;
202+
203+ if (!Tok.isAnnotation () && Tok.getIdentifierInfo () &&
204+ Tok.getIdentifierInfo ()->isKeyword (P.getLangOpts ()))
205+ return false ;
206+
207+ P.Diag (P.getCurToken (), diag::err_expected) << tok::identifier;
208+ return true ;
209+ }
210+
179211OpenACCDirectiveKind
180212ParseOpenACCEnterExitDataDirective (Parser &P, Token FirstTok,
181213 OpenACCDirectiveKindEx ExtDirKind) {
@@ -291,13 +323,56 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
291323 return DirKind;
292324}
293325
326+ bool ClauseHasRequiredParens (OpenACCClauseKind Kind) {
327+ return Kind == OpenACCClauseKind::Default;
328+ }
329+
330+ bool ParseOpenACCClauseParams (Parser &P, OpenACCClauseKind Kind) {
331+ BalancedDelimiterTracker Parens (P, tok::l_paren,
332+ tok::annot_pragma_openacc_end);
333+
334+ if (ClauseHasRequiredParens (Kind)) {
335+ if (Parens.expectAndConsume ()) {
336+ // We are missing a paren, so assume that the person just forgot the
337+ // parameter. Return 'false' so we try to continue on and parse the next
338+ // clause.
339+ P.SkipUntil (tok::comma, tok::r_paren, tok::annot_pragma_openacc_end,
340+ Parser::StopBeforeMatch);
341+ return false ;
342+ }
343+
344+ switch (Kind) {
345+ case OpenACCClauseKind::Default: {
346+ Token DefKindTok = P.getCurToken ();
347+
348+ if (expectIdentifierOrKeyword (P))
349+ break ;
350+
351+ P.ConsumeToken ();
352+
353+ if (getOpenACCDefaultClauseKind (DefKindTok) ==
354+ OpenACCDefaultClauseKind::Invalid)
355+ P.Diag (DefKindTok, diag::err_acc_invalid_default_clause_kind);
356+
357+ break ;
358+ }
359+ default :
360+ llvm_unreachable (" Not a required parens type?" );
361+ }
362+
363+ return Parens.consumeClose ();
364+ }
365+ // FIXME: Handle optional parens
366+ return false ;
367+ }
368+
294369// The OpenACC Clause List is a comma or space-delimited list of clauses (see
295370// the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't
296371// really have its owner grammar and each individual one has its own definition.
297- // However, they all are named with a single-identifier (or auto!) token,
298- // followed in some cases by either braces or parens.
372+ // However, they all are named with a single-identifier (or auto/default!)
373+ // token, followed in some cases by either braces or parens.
299374bool ParseOpenACCClause (Parser &P) {
300- if (!P.getCurToken ().isOneOf (tok::identifier, tok::kw_auto))
375+ if (!P.getCurToken ().isOneOf (tok::identifier, tok::kw_auto, tok::kw_default ))
301376 return P.Diag (P.getCurToken (), diag::err_expected) << tok::identifier;
302377
303378 OpenACCClauseKind Kind = getOpenACCClauseKind (P.getCurToken ());
@@ -309,8 +384,7 @@ bool ParseOpenACCClause(Parser &P) {
309384 // Consume the clause name.
310385 P.ConsumeToken ();
311386
312- // FIXME: For future clauses, we need to handle parens/etc below.
313- return false ;
387+ return ParseOpenACCClauseParams (P, Kind);
314388}
315389
316390// Skip until we see the end of pragma token, but don't consume it. This is us
0 commit comments