@@ -76,12 +76,17 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
76
76
if (Tok.is (tok::kw_auto))
77
77
return OpenACCClauseKind::Auto;
78
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
+
79
83
if (!Tok.is (tok::identifier))
80
84
return OpenACCClauseKind::Invalid;
81
85
82
86
return llvm::StringSwitch<OpenACCClauseKind>(
83
87
Tok.getIdentifierInfo ()->getName ())
84
88
.Case (" auto" , OpenACCClauseKind::Auto)
89
+ .Case (" default" , OpenACCClauseKind::Default)
85
90
.Case (" finalize" , OpenACCClauseKind::Finalize)
86
91
.Case (" if_present" , OpenACCClauseKind::IfPresent)
87
92
.Case (" independent" , OpenACCClauseKind::Independent)
@@ -106,6 +111,17 @@ OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) {
106
111
.Default (OpenACCAtomicKind::Invalid);
107
112
}
108
113
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
+
109
125
enum class OpenACCSpecialTokenKind {
110
126
ReadOnly,
111
127
DevNum,
@@ -176,6 +192,22 @@ bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) {
176
192
llvm_unreachable (" Unknown 'Kind' Passed" );
177
193
}
178
194
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
+
179
211
OpenACCDirectiveKind
180
212
ParseOpenACCEnterExitDataDirective (Parser &P, Token FirstTok,
181
213
OpenACCDirectiveKindEx ExtDirKind) {
@@ -291,13 +323,56 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
291
323
return DirKind;
292
324
}
293
325
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
+
294
369
// The OpenACC Clause List is a comma or space-delimited list of clauses (see
295
370
// the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't
296
371
// 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.
299
374
bool 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 ))
301
376
return P.Diag (P.getCurToken (), diag::err_expected) << tok::identifier;
302
377
303
378
OpenACCClauseKind Kind = getOpenACCClauseKind (P.getCurToken ());
@@ -309,8 +384,7 @@ bool ParseOpenACCClause(Parser &P) {
309
384
// Consume the clause name.
310
385
P.ConsumeToken ();
311
386
312
- // FIXME: For future clauses, we need to handle parens/etc below.
313
- return false ;
387
+ return ParseOpenACCClauseParams (P, Kind);
314
388
}
315
389
316
390
// Skip until we see the end of pragma token, but don't consume it. This is us
0 commit comments