@@ -1468,6 +1468,9 @@ class OmpVisitor : public virtual DeclarationVisitor {
14681468 AddOmpSourceRange (x.source );
14691469 return true ;
14701470 }
1471+
1472+ bool Pre (const parser::OpenMPDeclareMapperConstruct &);
1473+
14711474 void Post (const parser::OmpBeginLoopDirective &) {
14721475 messageHandler ().set_currStmtSource (std::nullopt );
14731476 }
@@ -1605,6 +1608,37 @@ void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) {
16051608 }
16061609}
16071610
1611+ // This "manually" walks the tree of the construct, because we need
1612+ // to resolve the type before the map clauses are processed - when
1613+ // just following the natural flow, the map clauses gets processed before
1614+ // the type has been fully processed.
1615+ bool OmpVisitor::Pre (const parser::OpenMPDeclareMapperConstruct &x) {
1616+ AddOmpSourceRange (x.source );
1617+ BeginDeclTypeSpec ();
1618+ const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t )};
1619+ Symbol *mapperSym{nullptr };
1620+ if (const auto &mapperName{std::get<std::optional<parser::Name>>(spec.t )}) {
1621+ mapperSym =
1622+ &MakeSymbol (*mapperName, MiscDetails{MiscDetails::Kind::ConstructName});
1623+ mapperName->symbol = mapperSym;
1624+ } else {
1625+ const parser::CharBlock defaultName{" default" , 7 };
1626+ mapperSym = &MakeSymbol (
1627+ defaultName, Attrs{}, MiscDetails{MiscDetails::Kind::ConstructName});
1628+ }
1629+
1630+ PushScope (Scope::Kind::OtherConstruct, nullptr );
1631+ Walk (std::get<parser::TypeSpec>(spec.t ));
1632+ const auto &varName{std::get<parser::ObjectName>(spec.t )};
1633+ DeclareObjectEntity (varName);
1634+
1635+ Walk (std::get<parser::OmpClauseList>(x.t ));
1636+
1637+ EndDeclTypeSpec ();
1638+ PopScope ();
1639+ return false ;
1640+ }
1641+
16081642// Walk the parse tree and resolve names to symbols.
16091643class ResolveNamesVisitor : public virtual ScopeHandler,
16101644 public ModuleVisitor,
0 commit comments