@@ -132,7 +132,7 @@ void AccStructureChecker::Leave(const parser::OpenACCBlockConstruct &x) {
132
132
default :
133
133
break ;
134
134
}
135
- accContext_ .pop_back ();
135
+ dirContext_ .pop_back ();
136
136
}
137
137
138
138
void AccStructureChecker::CheckNoBranching (const parser::Block &block,
@@ -152,7 +152,7 @@ void AccStructureChecker::Leave(
152
152
const parser::OpenACCStandaloneDeclarativeConstruct &) {
153
153
// Restriction - 2075
154
154
CheckAtLeastOneClause ();
155
- accContext_ .pop_back ();
155
+ dirContext_ .pop_back ();
156
156
}
157
157
158
158
void AccStructureChecker::Enter (const parser::OpenACCCombinedConstruct &x) {
@@ -185,12 +185,7 @@ void AccStructureChecker::Leave(const parser::OpenACCCombinedConstruct &x) {
185
185
default :
186
186
break ;
187
187
}
188
- accContext_.pop_back ();
189
- }
190
-
191
- std::string AccStructureChecker::ContextDirectiveAsFortran () {
192
- return parser::ToUpperCaseLetters (
193
- llvm::acc::getOpenACCDirectiveName (GetContext ().directive ).str ());
188
+ dirContext_.pop_back ();
194
189
}
195
190
196
191
void AccStructureChecker::Enter (const parser::OpenACCLoopConstruct &x) {
@@ -211,7 +206,7 @@ void AccStructureChecker::Leave(const parser::OpenACCLoopConstruct &x) {
211
206
{llvm::acc::Clause::ACCC_gang, llvm::acc::Clause::ACCC_vector,
212
207
llvm::acc::Clause::ACCC_worker});
213
208
}
214
- accContext_ .pop_back ();
209
+ dirContext_ .pop_back ();
215
210
}
216
211
217
212
void AccStructureChecker::Enter (const parser::OpenACCStandaloneConstruct &x) {
@@ -238,7 +233,7 @@ void AccStructureChecker::Leave(const parser::OpenACCStandaloneConstruct &x) {
238
233
default :
239
234
break ;
240
235
}
241
- accContext_ .pop_back ();
236
+ dirContext_ .pop_back ();
242
237
}
243
238
244
239
void AccStructureChecker::Enter (const parser::OpenACCRoutineConstruct &x) {
@@ -250,7 +245,7 @@ void AccStructureChecker::Leave(const parser::OpenACCRoutineConstruct &) {
250
245
// Restriction - 2407-2408
251
246
CheckOnlyAllowedAfter (llvm::acc::Clause::ACCC_device_type,
252
247
routineOnlyAllowedAfterDeviceTypeClauses);
253
- accContext_ .pop_back ();
248
+ dirContext_ .pop_back ();
254
249
}
255
250
256
251
// Clause checkers
@@ -348,154 +343,13 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyout &c) {
348
343
}
349
344
}
350
345
351
- void AccStructureChecker::CheckAllowed (llvm::acc::Clause clause) {
352
- if (!GetContext ().allowedClauses .test (clause) &&
353
- !GetContext ().allowedOnceClauses .test (clause) &&
354
- !GetContext ().allowedExclusiveClauses .test (clause) &&
355
- !GetContext ().requiredClauses .test (clause)) {
356
- context_.Say (GetContext ().clauseSource ,
357
- " %s clause is not allowed on the %s directive" _err_en_US,
358
- parser::ToUpperCaseLetters (
359
- llvm::acc::getOpenACCClauseName (clause).str ()),
360
- parser::ToUpperCaseLetters (GetContext ().directiveSource .ToString ()));
361
- return ;
362
- }
363
- if ((GetContext ().allowedOnceClauses .test (clause) ||
364
- GetContext ().allowedExclusiveClauses .test (clause)) &&
365
- FindClause (clause)) {
366
- context_.Say (GetContext ().clauseSource ,
367
- " At most one %s clause can appear on the %s directive" _err_en_US,
368
- parser::ToUpperCaseLetters (
369
- llvm::acc::getOpenACCClauseName (clause).str ()),
370
- parser::ToUpperCaseLetters (GetContext ().directiveSource .ToString ()));
371
- return ;
372
- }
373
- if (GetContext ().allowedExclusiveClauses .test (clause)) {
374
- std::vector<llvm::acc::Clause> others;
375
- GetContext ().allowedExclusiveClauses .IterateOverMembers (
376
- [&](llvm::acc::Clause o) {
377
- if (FindClause (o)) {
378
- others.emplace_back (o);
379
- }
380
- });
381
- for (const auto &e : others) {
382
- context_.Say (GetContext ().clauseSource ,
383
- " %s and %s clauses are mutually exclusive and may not appear on the "
384
- " same %s directive" _err_en_US,
385
- parser::ToUpperCaseLetters (
386
- llvm::acc::getOpenACCClauseName (clause).str ()),
387
- parser::ToUpperCaseLetters (llvm::acc::getOpenACCClauseName (e).str ()),
388
- parser::ToUpperCaseLetters (GetContext ().directiveSource .ToString ()));
389
- }
390
- if (!others.empty ()) {
391
- return ;
392
- }
393
- }
394
- SetContextClauseInfo (clause);
395
- AddClauseToCrtContext (clause);
396
- }
397
-
398
- void AccStructureChecker::CheckOnlyAllowedAfter (
399
- llvm::acc::Clause clause, AccClauseSet set) {
400
- bool enforceCheck = false ;
401
- for (auto cl : GetContext ().actualClauses ) {
402
- if (cl == clause) {
403
- enforceCheck = true ;
404
- continue ;
405
- } else if (enforceCheck && !set.test (cl)) {
406
- auto parserClause = GetContext ().clauseInfo .find (cl);
407
- context_.Say (parserClause->second ->source ,
408
- " Clause %s is not allowed after clause %s on the %s "
409
- " directive" _err_en_US,
410
- parser::ToUpperCaseLetters (llvm::acc::getOpenACCClauseName (cl).str ()),
411
- parser::ToUpperCaseLetters (
412
- llvm::acc::getOpenACCClauseName (clause).str ()),
413
- ContextDirectiveAsFortran ());
414
- }
415
- }
416
- }
417
-
418
- void AccStructureChecker::CheckRequireAtLeastOneOf () {
419
- for (auto cl : GetContext ().actualClauses ) {
420
- if (GetContext ().requiredClauses .test (cl))
421
- return ;
422
- }
423
- // No clause matched in the actual clauses list
424
- context_.Say (GetContext ().directiveSource ,
425
- " At least one of %s clause must appear on the %s directive" _err_en_US,
426
- ClauseSetToString (GetContext ().requiredClauses ),
427
- ContextDirectiveAsFortran ());
428
- }
429
-
430
- void AccStructureChecker::CheckAtLeastOneClause () {
431
- if (GetContext ().actualClauses .empty ()) {
432
- context_.Say (GetContext ().directiveSource ,
433
- " At least one clause is required on the %s directive" _err_en_US,
434
- ContextDirectiveAsFortran ());
435
- }
436
- }
437
-
438
- // Enforce restriction where clauses in the given set are not allowed if the
439
- // given clause appears.
440
- void AccStructureChecker::CheckNotAllowedIfClause (
441
- llvm::acc::Clause clause, AccClauseSet set) {
442
- if (std::find (GetContext ().actualClauses .begin (),
443
- GetContext ().actualClauses .end (),
444
- clause) == GetContext ().actualClauses .end ()) {
445
- return ; // Clause is not present
446
- }
447
-
448
- for (auto cl : GetContext ().actualClauses ) {
449
- if (set.test (cl)) {
450
- context_.Say (GetContext ().directiveSource ,
451
- " Clause %s is not allowed if clause %s appears on the %s directive" _err_en_US,
452
- parser::ToUpperCaseLetters (llvm::acc::getOpenACCClauseName (cl).str ()),
453
- parser::ToUpperCaseLetters (
454
- llvm::acc::getOpenACCClauseName (clause).str ()),
455
- ContextDirectiveAsFortran ());
456
- }
457
- }
458
- }
459
-
460
- void AccStructureChecker::RequiresConstantPositiveParameter (
461
- const llvm::acc::Clause &clause, const parser::ScalarIntConstantExpr &i) {
462
- if (const auto v{GetIntValue (i)}) {
463
- if (*v <= 0 ) {
464
- context_.Say (GetContext ().clauseSource ,
465
- " The parameter of the %s clause on the %s directive must be "
466
- " a constant positive integer expression" _err_en_US,
467
- parser::ToUpperCaseLetters (
468
- llvm::acc::getOpenACCClauseName (clause).str ()),
469
- ContextDirectiveAsFortran ());
470
- }
471
- }
472
- }
473
-
474
- void AccStructureChecker::OptionalConstantPositiveParameter (
475
- const llvm::acc::Clause &clause,
476
- const std::optional<parser::ScalarIntConstantExpr> &o) {
477
- if (o != std::nullopt) {
478
- RequiresConstantPositiveParameter (clause, o.value ());
479
- }
480
- }
481
-
482
- std::string AccStructureChecker::ClauseSetToString (const AccClauseSet set) {
483
- std::string list;
484
- set.IterateOverMembers ([&](llvm::acc::Clause o) {
485
- if (!list.empty ())
486
- list.append (" , " );
487
- list.append (
488
- parser::ToUpperCaseLetters (llvm::acc::getOpenACCClauseName (o).str ()));
489
- });
490
- return list;
346
+ llvm::StringRef AccStructureChecker::getClauseName (llvm::acc::Clause clause) {
347
+ return llvm::acc::getOpenACCClauseName (clause);
491
348
}
492
349
493
- void AccStructureChecker::SayNotMatching (
494
- const parser::CharBlock &beginSource, const parser::CharBlock &endSource) {
495
- context_
496
- .Say (endSource, " Unmatched %s directive" _err_en_US,
497
- parser::ToUpperCaseLetters (endSource.ToString ()))
498
- .Attach (beginSource, " Does not match directive" _en_US);
350
+ llvm::StringRef AccStructureChecker::getDirectiveName (
351
+ llvm::acc::Directive directive) {
352
+ return llvm::acc::getOpenACCDirectiveName (directive);
499
353
}
500
354
501
355
} // namespace Fortran::semantics
0 commit comments