Lines Matching full:symbol
23 #include "flang/Semantics/symbol.h"
53 Symbol::Flag defaultDSA{Symbol::Flag::AccShared}; // TODOACC
54 std::map<const Symbol *, Symbol::Flag> objectWithDSA;
79 void SetContextDefaultDSA(Symbol::Flag flag) {
83 const Symbol &symbol, Symbol::Flag flag, DirContext &context) {
84 context.objectWithDSA.emplace(&symbol, flag);
86 void AddToContextObjectWithDSA(const Symbol &symbol, Symbol::Flag flag) {
87 AddToContextObjectWithDSA(symbol, flag, GetContext());
89 bool IsObjectWithDSA(const Symbol &symbol) {
90 auto it{GetContext().objectWithDSA.find(&symbol)};
96 Symbol &MakeAssocSymbol(
97 const SourceName &name, const Symbol &prev, Scope &scope) {
101 Symbol &MakeAssocSymbol(const SourceName &name, const Symbol &prev) {
110 bool HasDataSharingAttributeObject(const Symbol &);
114 Symbol *DeclareNewPrivateAccessEntity(const Symbol &, Symbol::Flag, Scope &);
115 Symbol *DeclarePrivateAccessEntity(
116 const parser::Name &, Symbol::Flag, Scope &);
117 Symbol *DeclarePrivateAccessEntity(Symbol &, Symbol::Flag, Scope &);
118 Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
175 ResolveAccObjectList(x.v, Symbol::Flag::AccCopy);
181 ResolveAccObjectList(objectList, Symbol::Flag::AccCreate);
191 ResolveAccObjectList(objectList, Symbol::Flag::AccCopyInReadOnly);
193 ResolveAccObjectList(objectList, Symbol::Flag::AccCopyIn);
200 ResolveAccObjectList(objectList, Symbol::Flag::AccCopyOut);
205 ResolveAccObjectList(x.v, Symbol::Flag::AccPresent);
209 ResolveAccObjectList(x.v, Symbol::Flag::AccPrivate);
213 ResolveAccObjectList(x.v, Symbol::Flag::AccFirstPrivate);
218 ResolveAccObjectList(x.v, Symbol::Flag::AccDevice);
223 ResolveAccObjectList(x.v, Symbol::Flag::AccDeviceResident);
228 ResolveAccObjectList(x.v, Symbol::Flag::AccDevicePtr);
233 ResolveAccObjectList(x.v, Symbol::Flag::AccLink);
238 ResolveAccObjectList(x.v, Symbol::Flag::AccHost);
248 ResolveAccObjectList(accObjectList, Symbol::Flag::AccSelf);
258 Symbol::Flags dataSharingAttributeFlags{Symbol::Flag::AccShared,
259 Symbol::Flag::AccPrivate, Symbol::Flag::AccFirstPrivate,
260 Symbol::Flag::AccReduction};
262 Symbol::Flags dataMappingAttributeFlags{Symbol::Flag::AccCreate,
263 Symbol::Flag::AccCopyIn, Symbol::Flag::AccCopyOut,
264 Symbol::Flag::AccDelete, Symbol::Flag::AccPresent};
266 Symbol::Flags accDataMvtFlags{
267 Symbol::Flag::AccDevice, Symbol::Flag::AccHost, Symbol::Flag::AccSelf};
269 Symbol::Flags accFlagsRequireMark{Symbol::Flag::AccCreate,
270 Symbol::Flag::AccCopyIn, Symbol::Flag::AccCopyInReadOnly,
271 Symbol::Flag::AccCopy, Symbol::Flag::AccCopyOut,
272 Symbol::Flag::AccDevicePtr, Symbol::Flag::AccDeviceResident,
273 Symbol::Flag::AccLink, Symbol::Flag::AccPresent};
276 void ResolveAccObjectList(const parser::AccObjectList &, Symbol::Flag);
277 void ResolveAccObject(const parser::AccObject &, Symbol::Flag);
278 Symbol *ResolveAcc(const parser::Name &, Symbol::Flag, Scope &);
279 Symbol *ResolveAcc(Symbol &, Symbol::Flag, Scope &);
280 Symbol *ResolveName(const parser::Name &, bool parentScope = false);
281 Symbol *ResolveFctName(const parser::Name &);
282 Symbol *ResolveAccCommonBlockName(const parser::Name *);
283 Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
284 Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
286 const parser::Name &, const Symbol &, Symbol::Flag);
293 Symbol &, const parser::OpenACCRoutineConstruct &);
345 for (const Symbol &symbol : evaluate::CollectSymbols(*expr)) {
346 if (!IsStmtFunctionDummy(symbol)) {
347 stmtFunctionExprSymbols_.insert(symbol.GetUltimate());
392 ResolveOmpName(*name, Symbol::Flag::OmpDeclareSimd);
401 ResolveOmpObject(object, Symbol::Flag::OmpDependObject);
472 if (name && !name->symbol) {
480 ResolveOmpObjectList(x.v, Symbol::Flag::OmpInclusiveScan);
484 ResolveOmpObjectList(x.v, Symbol::Flag::OmpExclusiveScan);
489 ResolveOmpObjectList(x.v, Symbol::Flag::OmpShared);
493 ResolveOmpObjectList(x.v, Symbol::Flag::OmpPrivate);
498 ResolveOmpObjectList(objectList, Symbol::Flag::OmpAllocate);
502 ResolveOmpObjectList(x.v, Symbol::Flag::OmpFirstPrivate);
507 ResolveOmpObjectList(objList, Symbol::Flag::OmpLastPrivate);
511 ResolveOmpObjectList(x.v, Symbol::Flag::OmpCopyIn);
515 ResolveOmpObjectList(x.v, Symbol::Flag::OmpCopyPrivate);
520 ResolveOmpObjectList(objects, Symbol::Flag::OmpLinear);
526 ResolveOmpObjectList(objList, Symbol::Flag::OmpReduction);
530 // If name resolution failed, create a dummy symbol
537 name->symbol = &newSymbol;
547 if (!name->symbol) {
555 if (!procRef->v.thing.component.symbol) {
567 ResolveOmpObjectList(objList, Symbol::Flag::OmpInScanReduction);
576 ResolveOmpObjectList(alignedNameList, Symbol::Flag::OmpAligned);
582 ResolveOmpNameList(nontemporalNameList, Symbol::Flag::OmpNontemporal);
587 if (const auto &name{std::get<parser::Name>(x.t)}; !name.symbol) {
588 auto *symbol{currScope().FindSymbol(name.source)};
589 if (!symbol) {
592 symbol = &currScope().MakeSymbol(
595 Resolve(name, symbol);
600 ResolveOmpObjectList(x.v, Symbol::Flag::OmpUseDevicePtr);
605 ResolveOmpObjectList(x.v, Symbol::Flag::OmpUseDeviceAddr);
610 ResolveOmpObjectList(x.v, Symbol::Flag::OmpIsDevicePtr);
615 ResolveOmpObjectList(x.v, Symbol::Flag::OmpHasDeviceAddr);
646 Symbol::Flag ompFlag = Symbol::Flag::OmpMapToFrom;
651 ompFlag = Symbol::Flag::OmpMapTo;
654 ompFlag = Symbol::Flag::OmpMapFrom;
657 ompFlag = Symbol::Flag::OmpMapToFrom;
660 ompFlag = Symbol::Flag::OmpMapAlloc;
663 ompFlag = Symbol::Flag::OmpMapRelease;
666 ompFlag = Symbol::Flag::OmpMapDelete;
677 if (name->symbol) {
678 name->symbol->set(ompFlag);
679 AddToContextObjectWithDSA(*name->symbol, ompFlag);
681 if (name->symbol &&
682 semantics::IsAssumedSizeArray(*name->symbol)) {
707 Symbol::Flags dataSharingAttributeFlags{Symbol::Flag::OmpShared,
708 Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
709 Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpReduction,
710 Symbol::Flag::OmpLinear};
712 Symbol::Flags privateDataSharingAttributeFlags{Symbol::Flag::OmpPrivate,
713 Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate};
715 Symbol::Flags ompFlagsRequireNewSymbol{Symbol::Flag::OmpPrivate,
716 Symbol::Flag::OmpLinear, Symbol::Flag::OmpFirstPrivate,
717 Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpReduction,
718 Symbol::Flag::OmpCriticalLock, Symbol::Flag::OmpCopyIn,
719 Symbol::Flag::OmpUseDevicePtr, Symbol::Flag::OmpUseDeviceAddr,
720 Symbol::Flag::OmpIsDevicePtr, Symbol::Flag::OmpHasDeviceAddr};
722 Symbol::Flags ompFlagsRequireMark{Symbol::Flag::OmpThreadprivate,
723 Symbol::Flag::OmpDeclareTarget, Symbol::Flag::OmpExclusiveScan,
724 Symbol::Flag::OmpInclusiveScan, Symbol::Flag::OmpInScanReduction};
726 Symbol::Flags dataCopyingAttributeFlags{
727 Symbol::Flag::OmpCopyIn, Symbol::Flag::OmpCopyPrivate};
758 void ResolveOmpObjectList(const parser::OmpObjectList &, Symbol::Flag);
759 void ResolveOmpObject(const parser::OmpObject &, Symbol::Flag);
760 Symbol *ResolveOmp(const parser::Name &, Symbol::Flag, Scope &);
761 Symbol *ResolveOmp(Symbol &, Symbol::Flag, Scope &);
762 Symbol *ResolveOmpCommonBlockName(const parser::Name *);
763 void ResolveOmpNameList(const std::list<parser::Name> &, Symbol::Flag);
764 void ResolveOmpName(const parser::Name &, Symbol::Flag);
765 Symbol *ResolveName(const parser::Name *);
766 Symbol *ResolveOmpObjectScope(const parser::Name *);
767 Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
768 Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
770 const parser::Name &, const Symbol &, Symbol::Flag);
773 const parser::Name &, const Symbol &, Symbol::Flag);
776 const parser::Name &, const Symbol &, Symbol::Flag);
798 const Symbol *symbol, std::optional<Symbol::Flag> setFlag = std::nullopt);
803 const Symbol &object) {
835 Symbol *DirectiveAttributeVisitor<T>::DeclareNewPrivateAccessEntity(
836 const Symbol &object, Symbol::Flag flag, Scope &scope) {
838 auto &symbol{MakeAssocSymbol(object.name(), object, scope)};
839 symbol.set(flag);
840 if (flag == Symbol::Flag::OmpCopyIn) {
841 // The symbol in copyin clause must be threadprivate entity.
842 symbol.set(Symbol::Flag::OmpThreadprivate);
844 return &symbol;
848 Symbol *DirectiveAttributeVisitor<T>::DeclarePrivateAccessEntity(
849 const parser::Name &name, Symbol::Flag flag, Scope &scope) {
850 if (!name.symbol) {
853 name.symbol = DeclarePrivateAccessEntity(*name.symbol, flag, scope);
854 return name.symbol;
858 Symbol *DirectiveAttributeVisitor<T>::DeclarePrivateAccessEntity(
859 Symbol &object, Symbol::Flag flag, Scope &scope) {
983 Symbol *AccAttributeVisitor::ResolveName(
985 Symbol *prev{currScope().FindSymbol(name.source)};
990 if (prev != name.symbol) {
991 name.symbol = prev;
996 Symbol *AccAttributeVisitor::ResolveFctName(const parser::Name &name) {
997 Symbol *prev{currScope().FindSymbol(name.source)};
1005 if (prev != name.symbol) {
1006 name.symbol = prev;
1025 Symbol &symbol, const parser::OpenACCRoutineConstruct &x) {
1026 if (symbol.has<SubprogramDetails>()) {
1076 if (Symbol *sym = ResolveFctName(*name)) {
1112 symbol.get<SubprogramDetails>().add_openACCRoutineInfo(info);
1126 if (Symbol *sym = ResolveFctName(*optName)) {
1127 Symbol &ultimate{sym->GetUltimate()};
1135 if (currScope().symbol()) {
1136 AddRoutineInfoToSymbol(*currScope().symbol(), x);
1176 const evaluate::DataRef dataRef{*(name.symbol)};
1226 if (name.symbol && semantics::IsAssumedSizeArray(*name.symbol)) {
1249 if (name.symbol && !semantics::IsVariableName(*name.symbol) &&
1250 !semantics::IsNamedConstant(*name.symbol)) {
1333 auto checkExprHasSymbols = [&](llvm::SmallVector<Symbol *> &ivs,
1343 Symbol::Flag flag = Symbol::Flag::AccPrivate;
1344 llvm::SmallVector<Symbol *> ivs;
1349 if (auto *symbol{ResolveAcc(*ivName, flag, currScope())}) {
1364 ivs.push_back(symbol);
1382 if (!IsAllocatableOrObjectPointer(lastName.symbol)) {
1386 lastName.symbol->name(),
1419 SetContextDefaultDSA(Symbol::Flag::AccPresent);
1422 SetContextDefaultDSA(Symbol::Flag::AccNone);
1429 // and adjust the symbol for each Name if necessary
1431 auto *symbol{name.symbol};
1432 if (symbol && !dirContext_.empty() && GetContext().withinConstruct) {
1433 if (!symbol->owner().IsDerivedType() && !symbol->has<ProcEntityDetails>() &&
1434 !symbol->has<SubprogramDetails>() && !IsObjectWithDSA(*symbol)) {
1435 if (Symbol * found{currScope().FindSymbol(name.source)}) {
1436 if (symbol != found) {
1437 name.symbol = found; // adjust the symbol within region
1438 } else if (GetContext().defaultDSA == Symbol::Flag::AccNone) {
1443 symbol->name());
1450 Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
1455 name->symbol = prev;
1461 name->symbol = commonBlockSymbol;
1468 const parser::AccObjectList &accObjectList, Symbol::Flag accFlag) {
1476 const parser::AccObject &accObject, Symbol::Flag accFlag) {
1482 if (auto *symbol{ResolveAcc(*name, accFlag, currScope())}) {
1483 AddToContextObjectWithDSA(*symbol, accFlag);
1485 CheckMultipleAppearances(*name, *symbol, accFlag);
1501 if (auto *symbol{ResolveAccCommonBlockName(&name)}) {
1503 name, *symbol, Symbol::Flag::AccCommonBlock);
1504 for (auto &object : symbol->get<CommonBlockDetails>().objects()) {
1520 Symbol *AccAttributeVisitor::ResolveAcc(
1521 const parser::Name &name, Symbol::Flag accFlag, Scope &scope) {
1525 Symbol *AccAttributeVisitor::ResolveAcc(
1526 Symbol &symbol, Symbol::Flag accFlag, Scope &scope) {
1527 return DeclareOrMarkOtherAccessEntity(symbol, accFlag);
1530 Symbol *AccAttributeVisitor::DeclareOrMarkOtherAccessEntity(
1531 const parser::Name &name, Symbol::Flag accFlag) {
1532 Symbol *prev{currScope().FindSymbol(name.source)};
1533 if (!name.symbol || !prev) {
1535 } else if (prev != name.symbol) {
1536 name.symbol = prev;
1541 Symbol *AccAttributeVisitor::DeclareOrMarkOtherAccessEntity(
1542 Symbol &object, Symbol::Flag accFlag) {
1545 object.set(Symbol::Flag::AccDeclare);
1553 const Symbol &symbol, Symbol::Flag flag) {
1558 const parser::Name &name, const Symbol &symbol, Symbol::Flag accFlag) {
1559 const auto *target{&symbol};
1561 !WithMultipleAppearancesAccException(symbol, accFlag)) {
1628 const Symbol &symbolPrivate{*privateObj};
1755 // If this symbol already has a data-sharing attribute then there is nothing
1757 if (const Symbol * symbol{iv.symbol}) {
1759 if (symMap.first->name() == symbol->name()) {
1764 // If this symbol is already Private or Firstprivate in the enclosing
1766 if (auto *symbol{targetIt->scope.FindSymbol(iv.source)}) {
1767 if (symbol->owner() == targetIt->scope) {
1768 if (symbol->test(Symbol::Flag::OmpPrivate) ||
1769 symbol->test(Symbol::Flag::OmpFirstPrivate)) {
1774 // Otherwise find the symbol and make it Private for the entire enclosing
1776 if (auto *symbol{ResolveOmp(iv, Symbol::Flag::OmpPrivate, targetIt->scope)}) {
1778 symbol->set(Symbol::Flag::OmpPreDetermined);
1779 iv.symbol = symbol; // adjust the symbol within region
1781 AddToContextObjectWithDSA(*symbol, Symbol::Flag::OmpPrivate, *it);
1799 if (iv && iv->symbol)
1804 if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
1810 if (const auto *details{iv->symbol->detailsIf<HostAssocDetails>()}) {
1811 const Symbol *tpSymbol = &details->symbol();
1812 if (tpSymbol->test(Symbol::Flag::OmpThreadprivate)) {
1873 Symbol::Flag ivDSA;
1875 ivDSA = Symbol::Flag::OmpPrivate;
1877 ivDSA = Symbol::Flag::OmpLinear;
1879 ivDSA = Symbol::Flag::OmpLastPrivate;
1888 if (auto *symbol{ResolveOmp(*iv, ivDSA, currScope())}) {
1889 symbol->set(Symbol::Flag::OmpPreDetermined);
1890 iv->symbol = symbol; // adjust the symbol within region
1891 AddToContextObjectWithDSA(*symbol, ivDSA);
1942 ResolveOmpName(*criticalName, Symbol::Flag::OmpCriticalLock);
1946 ResolveOmpName(*endCriticalName, Symbol::Flag::OmpCriticalLock);
1955 ResolveOmpObjectList(*objectList, Symbol::Flag::OmpDeclareTarget);
1961 ResolveOmpObjectList(objList, Symbol::Flag::OmpDeclareTarget);
1964 ResolveOmpObjectList(linkClause->v, Symbol::Flag::OmpDeclareTarget);
1967 ResolveOmpObjectList(enterClause->v, Symbol::Flag::OmpDeclareTarget);
1982 ResolveOmpObjectList(list, Symbol::Flag::OmpThreadprivate);
1989 ResolveOmpObjectList(list, Symbol::Flag::OmpDeclarativeAllocateDirective);
2002 ResolveOmpObjectList(*list, Symbol::Flag::OmpExecutableAllocateDirective);
2014 Symbol::Flag::OmpExecutableAllocateDirective);
2028 SetContextDefaultDSA(Symbol::Flag::OmpPrivate);
2031 SetContextDefaultDSA(Symbol::Flag::OmpFirstPrivate);
2034 SetContextDefaultDSA(Symbol::Flag::OmpShared);
2037 SetContextDefaultDSA(Symbol::Flag::OmpNone);
2121 static bool IsPrivatizable(const Symbol *sym) {
2128 sym->test(Symbol::Flag::CrayPointee)) &&
2143 const Symbol *symbol, std::optional<Symbol::Flag> setFlag) {
2144 if (!IsPrivatizable(symbol)) {
2150 Symbol *lastDeclSymbol = nullptr;
2151 std::optional<Symbol::Flag> prevDSA;
2154 std::optional<Symbol::Flag> dsa;
2157 // if the `symbol` already has a data-sharing attribute
2158 if (symMap.first->name() == symbol->name()) {
2164 // When handling each implicit rule for a given symbol, one of the
2166 // 1. Declare a new private symbol.
2167 // 2. Create a new association symbol with no flags, that will represent
2168 // a shared symbol in the current scope. Note that symbols without
2170 // 3. Use the last declared private symbol, by inserting a new symbol
2172 // If no private symbol was declared previously, then no association
2173 // is needed and the symbol from the enclosing scope will be
2177 // symbol in the last case could lead to the conclusion that a symbol
2188 // If a new x symbol was not inserted in the inner parallel construct
2189 // (p2), it would use the x symbol definition from the enclosing scope.
2191 // symbol from the outer parallel construct (p1) would be collected, as
2195 auto makePrivateSymbol = [&](Symbol::Flag flag) {
2196 const Symbol *hostSymbol =
2197 lastDeclSymbol ? lastDeclSymbol : &symbol->GetUltimate();
2205 auto makeSharedSymbol = [&](std::optional<Symbol::Flag> flag = {}) {
2206 const Symbol *hostSymbol =
2207 lastDeclSymbol ? lastDeclSymbol : &symbol->GetUltimate();
2208 Symbol &assocSymbol = MakeAssocSymbol(symbol->name(), *hostSymbol,
2226 if (dsa.value() == Symbol::Flag::OmpShared &&
2228 makeSharedSymbol(Symbol::Flag::OmpShared);
2235 if (dirContext.defaultDSA == Symbol::Flag::OmpPrivate ||
2236 dirContext.defaultDSA == Symbol::Flag::OmpFirstPrivate ||
2237 dirContext.defaultDSA == Symbol::Flag::OmpShared) {
2243 if (dirContext.defaultDSA != Symbol::Flag::OmpShared) {
2252 dsa = Symbol::Flag::OmpShared;
2262 if (prevDSA == Symbol::Flag::OmpShared) {
2265 dsa = Symbol::Flag::OmpShared;
2268 dsa = Symbol::Flag::OmpFirstPrivate;
2269 makePrivateSymbol(*dsa)->set(Symbol::Flag::OmpImplicit);
2277 // and adjust the symbol for each Name if necessary
2279 auto *symbol{name.symbol};
2281 if (symbol && !dirContext_.empty() && GetContext().withinConstruct) {
2282 if (IsPrivatizable(symbol) && !IsObjectWithDSA(*symbol)) {
2286 if (Symbol * found{currScope().FindSymbol(name.source)}) {
2287 if (symbol != found) {
2288 name.symbol = found; // adjust the symbol within region
2289 } else if (GetContext().defaultDSA == Symbol::Flag::OmpNone &&
2290 !symbol->test(Symbol::Flag::OmpThreadprivate) &&
2294 !symbol->test(Symbol::Flag::OmpPrivate)) {
2295 if (symbol->test(Symbol::Flag::CrayPointee)) {
2297 semantics::GetCrayPointer(*symbol).name().ToString()};
2305 symbol->name());
2311 if (Symbol * found{currScope().FindSymbol(name.source)}) {
2312 if (found->test(semantics::Symbol::Flag::OmpThreadprivate))
2316 CreateImplicitSymbols(symbol);
2320 Symbol *OmpAttributeVisitor::ResolveName(const parser::Name *name) {
2323 name->symbol = resolvedSymbol;
2331 const parser::Name &name, Symbol::Flag ompFlag) {
2338 } else if (ompFlag == Symbol::Flag::OmpCriticalLock) {
2342 name.symbol = &pair.first->second.get();
2347 const std::list<parser::Name> &nameList, Symbol::Flag ompFlag) {
2353 Symbol *OmpAttributeVisitor::ResolveOmpCommonBlockName(
2360 name->symbol = cb;
2367 // resolving, it's symbol flag isn't important and a simple check for resolution
2371 Symbol *OmpAttributeVisitor::ResolveOmpObjectScope(const parser::Name *name) {
2377 name->symbol = prev;
2385 name->symbol = ompSymbol;
2392 const parser::OmpObjectList &ompObjectList, Symbol::Flag ompFlag) {
2399 const parser::OmpObject &ompObject, Symbol::Flag ompFlag) {
2405 if (auto *symbol{ResolveOmp(*name, ompFlag, currScope())}) {
2407 [&](const Symbol *symbol1, Symbol::Flag firstOmpFlag,
2408 const Symbol *symbol2, Symbol::Flag secondOmpFlag) {
2418 Symbol::OmpFlagToClauseName(firstOmpFlag),
2419 Symbol::OmpFlagToClauseName(secondOmpFlag),
2427 CheckDataCopyingClause(*name, *symbol, ompFlag);
2429 AddToContextObjectWithDSA(*symbol, ompFlag);
2431 CheckMultipleAppearances(*name, *symbol, ompFlag);
2434 CheckObjectIsPrivatizable(*name, *symbol, ompFlag);
2437 if (ompFlag == Symbol::Flag::OmpAllocate) {
2441 if (ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective &&
2442 IsAllocatable(*symbol) &&
2449 if ((ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective ||
2451 Symbol::Flag::OmpExecutableAllocateDirective) &&
2461 if (ompFlag == Symbol::Flag::OmpReduction) {
2462 const Symbol &ultimateSymbol{symbol->GetUltimate()};
2470 if (ultimateSymbol.test(Symbol::Flag::InNamelist)) {
2476 if (ompFlag == Symbol::Flag::OmpInclusiveScan ||
2477 ompFlag == Symbol::Flag::OmpExclusiveScan) {
2478 if (!symbol->test(Symbol::Flag::OmpInScanReduction)) {
2488 checkExclusivelists(symbol, Symbol::Flag::OmpUseDevicePtr,
2489 symbol, Symbol::Flag::OmpUseDeviceAddr);
2492 checkExclusivelists(symbol, Symbol::Flag::OmpFirstPrivate,
2493 symbol, Symbol::Flag::OmpLastPrivate);
2496 checkExclusivelists(symbol, Symbol::Flag::OmpIsDevicePtr,
2497 symbol, Symbol::Flag::OmpHasDeviceAddr);
2498 const auto *hostAssocSym{symbol};
2499 if (!(symbol->test(Symbol::Flag::OmpIsDevicePtr) ||
2500 symbol->test(Symbol::Flag::OmpHasDeviceAddr))) {
2502 symbol->detailsIf<HostAssocDetails>()}) {
2503 hostAssocSym = &details->symbol();
2506 Symbol::Flag dataMappingAttributeFlags[] = {
2507 Symbol::Flag::OmpMapTo, Symbol::Flag::OmpMapFrom,
2508 Symbol::Flag::OmpMapToFrom, Symbol::Flag::OmpMapAlloc,
2509 Symbol::Flag::OmpMapRelease, Symbol::Flag::OmpMapDelete,
2510 Symbol::Flag::OmpIsDevicePtr,
2511 Symbol::Flag::OmpHasDeviceAddr};
2513 Symbol::Flag dataSharingAttributeFlags[] = {
2514 Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
2515 Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpShared,
2516 Symbol::Flag::OmpLinear};
2523 for (Symbol::Flag ompFlag1 : dataMappingAttributeFlags) {
2524 for (Symbol::Flag ompFlag2 : dataSharingAttributeFlags) {
2526 hostAssocSym, ompFlag1, symbol, ompFlag2);
2545 if (auto *symbol{ResolveOmpCommonBlockName(&name)}) {
2548 name, *symbol, Symbol::Flag::OmpCommonBlock);
2553 auto &details{symbol->get<CommonBlockDetails>()};
2577 Symbol *OmpAttributeVisitor::ResolveOmp(
2578 const parser::Name &name, Symbol::Flag ompFlag, Scope &scope) {
2586 Symbol *OmpAttributeVisitor::ResolveOmp(
2587 Symbol &symbol, Symbol::Flag ompFlag, Scope &scope) {
2589 return DeclarePrivateAccessEntity(symbol, ompFlag, scope);
2591 return DeclareOrMarkOtherAccessEntity(symbol, ompFlag);
2595 Symbol *OmpAttributeVisitor::DeclareOrMarkOtherAccessEntity(
2596 const parser::Name &name, Symbol::Flag ompFlag) {
2597 Symbol *prev{currScope().FindSymbol(name.source)};
2598 if (!name.symbol || !prev) {
2600 } else if (prev != name.symbol) {
2601 name.symbol = prev;
2606 Symbol *OmpAttributeVisitor::DeclareOrMarkOtherAccessEntity(
2607 Symbol &object, Symbol::Flag ompFlag) {
2615 const Symbol &symbol, Symbol::Flag flag) {
2616 return (flag == Symbol::Flag::OmpFirstPrivate &&
2617 symbol.test(Symbol::Flag::OmpLastPrivate)) ||
2618 (flag == Symbol::Flag::OmpLastPrivate &&
2619 symbol.test(Symbol::Flag::OmpFirstPrivate));
2623 const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
2624 const auto *target{&symbol};
2626 if (const auto *details{symbol.detailsIf<HostAssocDetails>()}) {
2627 target = &details->symbol();
2631 !WithMultipleAppearancesOmpException(symbol, ompFlag)) {
2689 Symbol *symbol{common::visit(
2692 return scope ? scope->symbol() : nullptr;
2695 // FIXME There is no symbol defined for MainProgram units in certain
2698 if (!symbol) {
2705 processFn(*symbol, details);
2708 symbol->details());
2715 processProgramUnits([&](Symbol &symbol, WithOmpDeclarative &details) {
2723 context.Say(symbol.scope()->sourceRange(),
2736 processProgramUnits([&](Symbol &, WithOmpDeclarative &details) {
2746 static bool IsSymbolInCommonBlock(const Symbol &symbol) {
2750 // an OmpInCommonBlock flag to Symbol, to make it possible to quickly
2751 // test if a given symbol is in a common block.
2752 for (const auto &cb : symbol.owner().commonBlocks()) {
2753 if (IsCommonBlockContaining(cb.second.get(), symbol)) {
2760 static bool IsSymbolThreadprivate(const Symbol &symbol) {
2761 if (const auto *details{symbol.detailsIf<HostAssocDetails>()}) {
2762 return details->symbol().test(Symbol::Flag::OmpThreadprivate);
2764 return symbol.test(Symbol::Flag::OmpThreadprivate);
2767 static bool IsSymbolPrivate(const Symbol &symbol) {
2768 if (symbol.test(Symbol::Flag::OmpPrivate) ||
2769 symbol.test(Symbol::Flag::OmpFirstPrivate)) {
2772 // A symbol that has not gone through constructs that may privatize the
2773 // original symbol may be predetermined as private.
2775 if (symbol == symbol.GetUltimate()) {
2776 switch (symbol.owner().kind()) {
2780 return !symbol.attrs().test(Attr::SAVE) &&
2781 !symbol.attrs().test(Attr::PARAMETER) && !IsAssumedShape(symbol) &&
2782 !IsSymbolInCommonBlock(symbol);
2791 const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
2792 if (ompFlag == Symbol::Flag::OmpCopyIn) {
2795 if (!IsSymbolThreadprivate(symbol)) {
2798 symbol.name());
2800 } else if (ompFlag == Symbol::Flag::OmpCopyPrivate &&
2804 if (IsObjectWithDSA(symbol) &&
2805 (symbol.test(Symbol::Flag::OmpPrivate) ||
2806 symbol.test(Symbol::Flag::OmpFirstPrivate))) {
2810 symbol.name());
2811 } else if (!IsSymbolThreadprivate(symbol) && !IsSymbolPrivate(symbol)) {
2817 symbol.name());
2823 const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
2824 const auto &ultimateSymbol{symbol.GetUltimate()};
2826 if (ompFlag == Symbol::Flag::OmpFirstPrivate) {
2828 } else if (ompFlag == Symbol::Flag::OmpLastPrivate) {
2832 if (ultimateSymbol.test(Symbol::Flag::InNamelist)) {
2942 if (Symbol * symbol{scopeIter->symbol()}) {
2945 // Store clauses information into the symbol for the parent and
2970 symbol->details());