@@ -14313,7 +14313,7 @@ bool SemaOpenMP::checkTransformableLoopNest(
14313
14313
/// }
14314
14314
/// }
14315
14315
/// }
14316
- /// Result: Loop 'i' contains 2 loops, Loop 'r' also contains 2 loops
14316
+ /// Result: Loop 'i' contains 2 loops, Loop 'r' also contains 2 loops.
14317
14317
class NestedLoopCounterVisitor final : public DynamicRecursiveASTVisitor {
14318
14318
private:
14319
14319
unsigned NestedLoopCount = 0;
@@ -14341,24 +14341,24 @@ class NestedLoopCounterVisitor final : public DynamicRecursiveASTVisitor {
14341
14341
// LambdaExpr, StmtExpr, BlockExpr, and RequiresExpr. These expressions
14342
14342
// may contain inner statements (and even loops), but they are not part
14343
14343
// of the syntactic body of the surrounding loop structure.
14344
- // Therefore must not be counted
14344
+ // Therefore must not be counted.
14345
14345
if (isa<Expr>(S))
14346
14346
return true;
14347
14347
14348
- // Only recurse into CompoundStmt (block {}) and loop bodies
14348
+ // Only recurse into CompoundStmt (block {}) and loop bodies.
14349
14349
if (isa<CompoundStmt, ForStmt, CXXForRangeStmt>(S)) {
14350
14350
return DynamicRecursiveASTVisitor::TraverseStmt(S);
14351
14351
}
14352
14352
14353
14353
// Stop traversal of the rest of statements, that break perfect
14354
- // loop nesting, such as control flow (IfStmt, SwitchStmt...)
14354
+ // loop nesting, such as control flow (IfStmt, SwitchStmt...).
14355
14355
return true;
14356
14356
}
14357
14357
14358
14358
bool TraverseDecl(Decl *D) override {
14359
14359
// Stop in the case of finding a declaration, it is not important
14360
14360
// in order to find nested loops (Possible CXXRecordDecl, RecordDecl,
14361
- // FunctionDecl...)
14361
+ // FunctionDecl...).
14362
14362
return true;
14363
14363
}
14364
14364
};
@@ -14370,7 +14370,7 @@ bool SemaOpenMP::analyzeLoopSequence(Stmt *LoopSeqStmt,
14370
14370
14371
14371
VarsWithInheritedDSAType TmpDSA;
14372
14372
/// Helper Lambda to handle storing initialization and body statements for
14373
- /// both ForStmt and CXXForRangeStmt
14373
+ /// both ForStmt and CXXForRangeStmt.
14374
14374
auto StoreLoopStatements = [](LoopAnalysis &Analysis, Stmt *LoopStmt) {
14375
14375
if (auto *For = dyn_cast<ForStmt>(LoopStmt)) {
14376
14376
Analysis.OriginalInits.push_back(For->getInit());
@@ -14384,7 +14384,7 @@ bool SemaOpenMP::analyzeLoopSequence(Stmt *LoopSeqStmt,
14384
14384
14385
14385
/// Helper lambda functions to encapsulate the processing of different
14386
14386
/// derivations of the canonical loop sequence grammar
14387
- /// Modularized code for handling loop generation and transformations
14387
+ /// Modularized code for handling loop generation and transformations.
14388
14388
auto AnalyzeLoopGeneration = [&](Stmt *Child) {
14389
14389
auto *LoopTransform = dyn_cast<OMPLoopTransformationDirective>(Child);
14390
14390
Stmt *TransformedStmt = LoopTransform->getTransformedStmt();
@@ -14442,7 +14442,7 @@ bool SemaOpenMP::analyzeLoopSequence(Stmt *LoopSeqStmt,
14442
14442
return true;
14443
14443
};
14444
14444
14445
- /// Modularized code for handling regular canonical loops
14445
+ /// Modularized code for handling regular canonical loops.
14446
14446
auto AnalyzeRegularLoop = [&](Stmt *Child) {
14447
14447
LoopAnalysis &NewRegularLoop =
14448
14448
SeqAnalysis.Loops.emplace_back(OMPLoopCategory::RegularLoop);
@@ -14463,55 +14463,47 @@ bool SemaOpenMP::analyzeLoopSequence(Stmt *LoopSeqStmt,
14463
14463
return true;
14464
14464
};
14465
14465
14466
- /// Helper functions to validate loop sequence grammar derivations
14466
+ /// Helper functions to validate loop sequence grammar derivations.
14467
14467
auto IsLoopSequenceDerivation = [](auto *Child) {
14468
14468
return isa<ForStmt, CXXForRangeStmt, OMPLoopTransformationDirective>(Child);
14469
14469
};
14470
- /// Helper functions to validate loop generating grammar derivations
14470
+ /// Helper functions to validate loop generating grammar derivations.
14471
14471
auto IsLoopGeneratingStmt = [](auto *Child) {
14472
14472
return isa<OMPLoopTransformationDirective>(Child);
14473
14473
};
14474
14474
14475
- // High level grammar validation
14475
+ // High level grammar validation.
14476
14476
for (auto *Child : LoopSeqStmt->children()) {
14477
-
14478
14477
if (!Child)
14479
14478
continue;
14480
-
14481
- // Skip over non-loop-sequence statements
14479
+ // Skip over non-loop-sequence statements.
14482
14480
if (!IsLoopSequenceDerivation(Child)) {
14483
14481
Child = Child->IgnoreContainers();
14484
-
14485
- // Ignore empty compound statement
14482
+ // Ignore empty compound statement.
14486
14483
if (!Child)
14487
14484
continue;
14488
-
14489
14485
// In the case of a nested loop sequence ignoring containers would not
14490
- // be enough, a recurisve transversal of the loop sequence is required
14486
+ // be enough, a recurisve transversal of the loop sequence is required.
14491
14487
if (isa<CompoundStmt>(Child)) {
14492
14488
if (!analyzeLoopSequence(Child, SeqAnalysis, Context, Kind))
14493
14489
return false;
14494
14490
// Already been treated, skip this children
14495
14491
continue;
14496
14492
}
14497
14493
}
14498
- // Regular loop sequence handling
14494
+ // Regular loop sequence handling.
14499
14495
if (IsLoopSequenceDerivation(Child)) {
14500
14496
if (IsLoopGeneratingStmt(Child)) {
14501
14497
if (!AnalyzeLoopGeneration(Child))
14502
14498
return false;
14503
-
14504
- // AnalyzeLoopGeneration updates Loop Sequence size accordingly
14505
-
14499
+ // AnalyzeLoopGeneration updates SeqAnalysis.LoopSeqSize accordingly.
14506
14500
} else {
14507
14501
if (!AnalyzeRegularLoop(Child))
14508
14502
return false;
14509
-
14510
- // Update the Loop Sequence size by one
14511
14503
SeqAnalysis.LoopSeqSize++;
14512
14504
}
14513
14505
} else {
14514
- // Report error for invalid statement inside canonical loop sequence
14506
+ // Report error for invalid statement inside canonical loop sequence.
14515
14507
Diag(Child->getBeginLoc(), diag::err_omp_not_for)
14516
14508
<< 0 << getOpenMPDirectiveName(Kind);
14517
14509
return false;
@@ -14523,14 +14515,6 @@ bool SemaOpenMP::analyzeLoopSequence(Stmt *LoopSeqStmt,
14523
14515
bool SemaOpenMP::checkTransformableLoopSequence(
14524
14516
OpenMPDirectiveKind Kind, Stmt *AStmt, LoopSequenceAnalysis &SeqAnalysis,
14525
14517
ASTContext &Context) {
14526
-
14527
- // Checks whether the given statement is a compound statement
14528
- if (!isa<CompoundStmt>(AStmt)) {
14529
- Diag(AStmt->getBeginLoc(), diag::err_omp_not_a_loop_sequence)
14530
- << getOpenMPDirectiveName(Kind);
14531
- return false;
14532
- }
14533
-
14534
14518
// Following OpenMP 6.0 API Specification, a Canonical Loop Sequence follows
14535
14519
// the grammar:
14536
14520
//
@@ -14543,17 +14527,25 @@ bool SemaOpenMP::checkTransformableLoopSequence(
14543
14527
// 2. loop-nest
14544
14528
// 3. loop-sequence-generating-construct (i.e OMPLoopTransformationDirective)
14545
14529
//
14546
- // To recognise and traverse this structure the following helper functions
14547
- // have been defined. analyzeLoopSequence serves as the recurisve entry point
14530
+ // To recognise and traverse this structure the helper function
14531
+ // analyzeLoopSequence serves as the recurisve entry point
14548
14532
// and tries to match the input AST to the canonical loop sequence grammar
14549
14533
// structure. This function will perform both a semantic and syntactical
14550
14534
// analysis of the given statement according to OpenMP 6.0 definition of
14551
- // the aforementioned canonical loop sequence
14535
+ // the aforementioned canonical loop sequence.
14536
+
14537
+ // We expect an outer compound statement.
14538
+ if (!isa<CompoundStmt>(AStmt)) {
14539
+ Diag(AStmt->getBeginLoc(), diag::err_omp_not_a_loop_sequence)
14540
+ << getOpenMPDirectiveName(Kind);
14541
+ return false;
14542
+ }
14552
14543
14553
14544
// Recursive entry point to process the main loop sequence
14554
14545
if (!analyzeLoopSequence(AStmt, SeqAnalysis, Context, Kind))
14555
14546
return false;
14556
14547
14548
+ // Diagnose an empty loop sequence.
14557
14549
if (SeqAnalysis.LoopSeqSize <= 0) {
14558
14550
Diag(AStmt->getBeginLoc(), diag::err_omp_empty_loop_sequence)
14559
14551
<< getOpenMPDirectiveName(Kind);
0 commit comments