@@ -1486,34 +1486,16 @@ class OmpVisitor : public virtual DeclarationVisitor {
1486
1486
bool Pre (const parser::OmpBlockConstruct &);
1487
1487
void Post (const parser::OmpBlockConstruct &);
1488
1488
bool Pre (const parser::OmpBeginDirective &x) {
1489
- AddOmpSourceRange (x.source );
1490
- // Manually resolve names in CRITICAL directives. This is because these
1491
- // names do not denote Fortran objects, and the CRITICAL directive causes
1492
- // them to be "auto-declared", i.e. inserted into the global scope.
1493
- // More specifically, they are not expected to have explicit declarations,
1494
- // and if they do the behavior is unspeficied.
1495
- if (x.DirName ().v == llvm::omp::Directive::OMPD_critical) {
1496
- for (const parser::OmpArgument &arg : x.Arguments ().v ) {
1497
- ResolveCriticalName (arg);
1498
- }
1499
- }
1500
- return true ;
1489
+ return Pre (static_cast <const parser::OmpDirectiveSpecification &>(x));
1501
1490
}
1502
- void Post (const parser::OmpBeginDirective &) {
1503
- messageHandler (). set_currStmtSource (std:: nullopt );
1491
+ void Post (const parser::OmpBeginDirective &x ) {
1492
+ Post ( static_cast < const parser::OmpDirectiveSpecification &>(x) );
1504
1493
}
1505
1494
bool Pre (const parser::OmpEndDirective &x) {
1506
- AddOmpSourceRange (x.source );
1507
- // Manually resolve names in CRITICAL directives.
1508
- if (x.DirName ().v == llvm::omp::Directive::OMPD_critical) {
1509
- for (const parser::OmpArgument &arg : x.Arguments ().v ) {
1510
- ResolveCriticalName (arg);
1511
- }
1512
- }
1513
- return true ;
1495
+ return Pre (static_cast <const parser::OmpDirectiveSpecification &>(x));
1514
1496
}
1515
- void Post (const parser::OmpEndDirective &) {
1516
- messageHandler (). set_currStmtSource (std:: nullopt );
1497
+ void Post (const parser::OmpEndDirective &x ) {
1498
+ Post ( static_cast < const parser::OmpDirectiveSpecification &>(x) );
1517
1499
}
1518
1500
1519
1501
bool Pre (const parser::OpenMPLoopConstruct &) {
@@ -1522,8 +1504,16 @@ class OmpVisitor : public virtual DeclarationVisitor {
1522
1504
}
1523
1505
void Post (const parser::OpenMPLoopConstruct &) { PopScope (); }
1524
1506
bool Pre (const parser::OmpBeginLoopDirective &x) {
1525
- AddOmpSourceRange (x.source );
1526
- return true ;
1507
+ return Pre (static_cast <const parser::OmpDirectiveSpecification &>(x));
1508
+ }
1509
+ void Post (const parser::OmpBeginLoopDirective &x) {
1510
+ Post (static_cast <const parser::OmpDirectiveSpecification &>(x));
1511
+ }
1512
+ bool Pre (const parser::OmpEndLoopDirective &x) {
1513
+ return Pre (static_cast <const parser::OmpDirectiveSpecification &>(x));
1514
+ }
1515
+ void Post (const parser::OmpEndLoopDirective &x) {
1516
+ Post (static_cast <const parser::OmpDirectiveSpecification &>(x));
1527
1517
}
1528
1518
1529
1519
bool Pre (const parser::OpenMPDeclareMapperConstruct &x) {
@@ -1580,35 +1570,22 @@ class OmpVisitor : public virtual DeclarationVisitor {
1580
1570
}
1581
1571
bool Pre (const parser::OmpMapClause &);
1582
1572
1583
- void Post (const parser::OmpBeginLoopDirective &) {
1584
- messageHandler ().set_currStmtSource (std::nullopt );
1585
- }
1586
- bool Pre (const parser::OmpEndLoopDirective &x) {
1587
- AddOmpSourceRange (x.source );
1588
- return true ;
1589
- }
1590
- void Post (const parser::OmpEndLoopDirective &) {
1591
- messageHandler ().set_currStmtSource (std::nullopt );
1592
- }
1593
-
1594
1573
bool Pre (const parser::OpenMPSectionsConstruct &) {
1595
1574
PushScope (Scope::Kind::OtherConstruct, nullptr );
1596
1575
return true ;
1597
1576
}
1598
1577
void Post (const parser::OpenMPSectionsConstruct &) { PopScope (); }
1599
1578
bool Pre (const parser::OmpBeginSectionsDirective &x) {
1600
- AddOmpSourceRange (x.source );
1601
- return true ;
1579
+ return Pre (static_cast <const parser::OmpDirectiveSpecification &>(x));
1602
1580
}
1603
- void Post (const parser::OmpBeginSectionsDirective &) {
1604
- messageHandler (). set_currStmtSource (std:: nullopt );
1581
+ void Post (const parser::OmpBeginSectionsDirective &x ) {
1582
+ Post ( static_cast < const parser::OmpDirectiveSpecification &>(x) );
1605
1583
}
1606
1584
bool Pre (const parser::OmpEndSectionsDirective &x) {
1607
- AddOmpSourceRange (x.source );
1608
- return true ;
1585
+ return Pre (static_cast <const parser::OmpDirectiveSpecification &>(x));
1609
1586
}
1610
- void Post (const parser::OmpEndSectionsDirective &) {
1611
- messageHandler (). set_currStmtSource (std:: nullopt );
1587
+ void Post (const parser::OmpEndSectionsDirective &x ) {
1588
+ Post ( static_cast < const parser::OmpDirectiveSpecification &>(x) );
1612
1589
}
1613
1590
bool Pre (const parser::OpenMPThreadprivate &) {
1614
1591
SkipImplicitTyping (true );
@@ -1718,6 +1695,9 @@ class OmpVisitor : public virtual DeclarationVisitor {
1718
1695
}
1719
1696
}
1720
1697
bool Pre (const parser::OmpDirectiveSpecification &x);
1698
+ void Post (const parser::OmpDirectiveSpecification &) {
1699
+ messageHandler ().set_currStmtSource (std::nullopt );
1700
+ }
1721
1701
1722
1702
bool Pre (const parser::OmpTypeSpecifier &x) {
1723
1703
BeginDeclTypeSpec ();
@@ -1727,6 +1707,16 @@ class OmpVisitor : public virtual DeclarationVisitor {
1727
1707
EndDeclTypeSpec ();
1728
1708
}
1729
1709
1710
+ bool Pre (const parser::OpenMPConstruct &x) {
1711
+ // Indicate that the current directive is not a declarative one.
1712
+ declaratives_.push_back (nullptr );
1713
+ return true ;
1714
+ }
1715
+ void Post (const parser::OpenMPConstruct &) {
1716
+ // Pop the null pointer.
1717
+ declaratives_.pop_back ();
1718
+ }
1719
+
1730
1720
private:
1731
1721
void ProcessMapperSpecifier (const parser::OmpMapperSpecifier &spec,
1732
1722
const parser::OmpClauseList &clauses);
@@ -1994,30 +1984,40 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
1994
1984
1995
1985
const parser::OmpArgumentList &args{x.Arguments ()};
1996
1986
const parser::OmpClauseList &clauses{x.Clauses ()};
1987
+ bool visitClauses{true };
1988
+
1989
+ for (const parser::OmpArgument &arg : args.v ) {
1990
+ common::visit ( //
1991
+ common::visitors{
1992
+ [&](const parser::OmpMapperSpecifier &spec) {
1993
+ ProcessMapperSpecifier (spec, clauses);
1994
+ visitClauses = false ;
1995
+ },
1996
+ [&](const parser::OmpReductionSpecifier &spec) {
1997
+ ProcessReductionSpecifier (spec, clauses, declaratives_.back ());
1998
+ visitClauses = false ;
1999
+ },
2000
+ [&](const parser::OmpLocator &locator) {
2001
+ // Manually resolve names in CRITICAL directives. This is because
2002
+ // these names do not denote Fortran objects, and the CRITICAL
2003
+ // directive causes them to be "auto-declared", i.e. inserted into
2004
+ // the global scope. More specifically, they are not expected to
2005
+ // have explicit declarations, and if they do the behavior is
2006
+ // unspeficied.
2007
+ if (x.DirId () == llvm::omp::Directive::OMPD_critical) {
2008
+ ResolveCriticalName (arg);
2009
+ } else {
2010
+ Walk (locator);
2011
+ }
2012
+ },
2013
+ },
2014
+ arg.u );
2015
+ }
1997
2016
1998
- switch (x.DirId ()) {
1999
- case llvm::omp::Directive::OMPD_declare_mapper:
2000
- if (!args.v .empty ()) {
2001
- const parser::OmpArgument &first{args.v .front ()};
2002
- if (auto *spec{std::get_if<parser::OmpMapperSpecifier>(&first.u )}) {
2003
- ProcessMapperSpecifier (*spec, clauses);
2004
- }
2005
- }
2006
- break ;
2007
- case llvm::omp::Directive::OMPD_declare_reduction:
2008
- if (!args.v .empty ()) {
2009
- const parser::OmpArgument &first{args.v .front ()};
2010
- if (auto *spec{std::get_if<parser::OmpReductionSpecifier>(&first.u )}) {
2011
- ProcessReductionSpecifier (*spec, clauses, declaratives_.back ());
2012
- }
2013
- }
2014
- break ;
2015
- default :
2016
- // Default processing.
2017
- Walk (args);
2017
+ if (visitClauses) {
2018
2018
Walk (clauses);
2019
- break ;
2020
2019
}
2020
+
2021
2021
return false ;
2022
2022
}
2023
2023
0 commit comments