2929#include " llvm/Support/Debug.h"
3030#include < list>
3131#include < map>
32- #include < sstream>
3332
3433template <typename T>
3534static Fortran::semantics::Scope *GetScope (
@@ -61,6 +60,13 @@ template <typename T> class DirectiveAttributeVisitor {
6160 parser::OmpDefaultmapClause::ImplicitBehavior>
6261 defaultMap;
6362
63+ std::optional<Symbol::Flag> FindSymbolWithDSA (const Symbol &symbol) {
64+ if (auto it{objectWithDSA.find (&symbol)}; it != objectWithDSA.end ()) {
65+ return it->second ;
66+ }
67+ return std::nullopt ;
68+ }
69+
6470 bool withinConstruct{false };
6571 std::int64_t associatedLoopLevel{0 };
6672 };
@@ -75,10 +81,19 @@ template <typename T> class DirectiveAttributeVisitor {
7581 : std::make_optional<DirContext>(dirContext_.back ());
7682 }
7783 void PushContext (const parser::CharBlock &source, T dir, Scope &scope) {
78- dirContext_.emplace_back (source, dir, scope);
84+ if constexpr (std::is_same_v<T, llvm::acc::Directive>) {
85+ dirContext_.emplace_back (source, dir, scope);
86+ if (std::size_t size{dirContext_.size ()}; size > 1 ) {
87+ std::size_t lastIndex{size - 1 };
88+ dirContext_[lastIndex].defaultDSA =
89+ dirContext_[lastIndex - 1 ].defaultDSA ;
90+ }
91+ } else {
92+ dirContext_.emplace_back (source, dir, scope);
93+ }
7994 }
8095 void PushContext (const parser::CharBlock &source, T dir) {
81- dirContext_. emplace_back (source, dir, context_.FindScope (source));
96+ PushContext (source, dir, context_.FindScope (source));
8297 }
8398 void PopContext () { dirContext_.pop_back (); }
8499 void SetContextDirectiveSource (parser::CharBlock &dir) {
@@ -100,9 +115,21 @@ template <typename T> class DirectiveAttributeVisitor {
100115 AddToContextObjectWithDSA (symbol, flag, GetContext ());
101116 }
102117 bool IsObjectWithDSA (const Symbol &symbol) {
103- auto it{GetContext ().objectWithDSA .find (&symbol)};
104- return it != GetContext ().objectWithDSA .end ();
118+ return GetContext ().FindSymbolWithDSA (symbol).has_value ();
119+ }
120+ bool IsObjectWithVisibleDSA (const Symbol &symbol) {
121+ for (std::size_t i{dirContext_.size ()}; i != 0 ; i--) {
122+ if (dirContext_[i - 1 ].FindSymbolWithDSA (symbol).has_value ()) {
123+ return true ;
124+ }
125+ }
126+ return false ;
105127 }
128+
129+ bool WithinConstruct () {
130+ return !dirContext_.empty () && GetContext ().withinConstruct ;
131+ }
132+
106133 void SetContextAssociatedLoopLevel (std::int64_t level) {
107134 GetContext ().associatedLoopLevel = level;
108135 }
@@ -1573,10 +1600,10 @@ void AccAttributeVisitor::Post(const parser::AccDefaultClause &x) {
15731600// and adjust the symbol for each Name if necessary
15741601void AccAttributeVisitor::Post (const parser::Name &name) {
15751602 auto *symbol{name.symbol };
1576- if (symbol && !dirContext_. empty () && GetContext (). withinConstruct ) {
1603+ if (symbol && WithinConstruct () ) {
15771604 symbol = &symbol->GetUltimate ();
15781605 if (!symbol->owner ().IsDerivedType () && !symbol->has <ProcEntityDetails>() &&
1579- !symbol->has <SubprogramDetails>() && !IsObjectWithDSA (*symbol)) {
1606+ !symbol->has <SubprogramDetails>() && !IsObjectWithVisibleDSA (*symbol)) {
15801607 if (Symbol * found{currScope ().FindSymbol (name.source )}) {
15811608 if (symbol != found) {
15821609 name.symbol = found; // adjust the symbol within region
@@ -1959,7 +1986,7 @@ void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct(
19591986// till OpenMP-5.0 standard.
19601987// In above both cases we skip the privatization of iteration variables.
19611988bool OmpAttributeVisitor::Pre (const parser::DoConstruct &x) {
1962- if (!dirContext_. empty () && GetContext (). withinConstruct ) {
1989+ if (WithinConstruct () ) {
19631990 llvm::SmallVector<const parser::Name *> ivs;
19641991 if (x.IsDoNormal ()) {
19651992 const parser::Name *iv{GetLoopIndex (x)};
@@ -2685,7 +2712,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {
26852712void OmpAttributeVisitor::Post (const parser::Name &name) {
26862713 auto *symbol{name.symbol };
26872714
2688- if (symbol && !dirContext_. empty () && GetContext (). withinConstruct ) {
2715+ if (symbol && WithinConstruct () ) {
26892716 if (IsPrivatizable (symbol) && !IsObjectWithDSA (*symbol)) {
26902717 // TODO: create a separate function to go through the rules for
26912718 // predetermined, explicitly determined, and implicitly
0 commit comments