@@ -1087,6 +1087,52 @@ std::optional<common::CUDADataAttr> GetCUDADataAttr(const Symbol *symbol) {
10871087 return object ? object->cudaDataAttr () : std::nullopt ;
10881088}
10891089
1090+ bool IsDeviceAllocatable (const Symbol &symbol) {
1091+ if (IsAllocatable (symbol)) {
1092+ if (const auto *details{
1093+ symbol.GetUltimate ().detailsIf <semantics::ObjectEntityDetails>()}) {
1094+ if (details->cudaDataAttr () &&
1095+ *details->cudaDataAttr () != common::CUDADataAttr::Pinned) {
1096+ return true ;
1097+ }
1098+ }
1099+ }
1100+ return false ;
1101+ }
1102+
1103+ UltimateComponentIterator::const_iterator
1104+ FindCUDADeviceAllocatableUltimateComponent (const DerivedTypeSpec &derived) {
1105+ UltimateComponentIterator ultimates{derived};
1106+ return std::find_if (ultimates.begin (), ultimates.end (), IsDeviceAllocatable);
1107+ }
1108+
1109+ bool CanCUDASymbolBeGlobal (const Symbol &sym) {
1110+ const Symbol &symbol{GetAssociationRoot (sym)};
1111+ const Scope &scope{symbol.owner ()};
1112+ auto scopeKind{scope.kind ()};
1113+ const common::LanguageFeatureControl &features{
1114+ scope.context ().languageFeatures ()};
1115+ if (features.IsEnabled (common::LanguageFeature::CUDA) &&
1116+ scopeKind == Scope::Kind::MainProgram) {
1117+ if (const auto *details{
1118+ sym.GetUltimate ().detailsIf <semantics::ObjectEntityDetails>()}) {
1119+ const Fortran::semantics::DeclTypeSpec *type{details->type ()};
1120+ const Fortran::semantics::DerivedTypeSpec *derived{
1121+ type ? type->AsDerived () : nullptr };
1122+ if (derived) {
1123+ if (FindCUDADeviceAllocatableUltimateComponent (*derived)) {
1124+ return false ;
1125+ }
1126+ }
1127+ if (details->cudaDataAttr () &&
1128+ *details->cudaDataAttr () != common::CUDADataAttr::Unified) {
1129+ return false ;
1130+ }
1131+ }
1132+ }
1133+ return true ;
1134+ }
1135+
10901136bool IsAccessible (const Symbol &original, const Scope &scope) {
10911137 const Symbol &ultimate{original.GetUltimate ()};
10921138 if (ultimate.attrs ().test (Attr::PRIVATE)) {
@@ -1788,4 +1834,4 @@ bool HadUseError(
17881834 }
17891835}
17901836
1791- } // namespace Fortran::semantics
1837+ } // namespace Fortran::semantics
0 commit comments