@@ -2828,6 +2828,16 @@ Scope &ScopeHandler::NonDerivedTypeScope() {
2828
2828
return currScope_->IsDerivedType () ? currScope_->parent () : *currScope_;
2829
2829
}
2830
2830
2831
+ static void SetImplicitCUDADevice (Symbol &symbol) {
2832
+ if (auto *object{symbol.detailsIf <ObjectEntityDetails>()}) {
2833
+ if (!object->cudaDataAttr () && !IsValue (symbol) &&
2834
+ !IsFunctionResult (symbol)) {
2835
+ // Implicitly set device attribute if none is set in device context.
2836
+ object->set_cudaDataAttr (common::CUDADataAttr::Device);
2837
+ }
2838
+ }
2839
+ }
2840
+
2831
2841
void ScopeHandler::PushScope (Scope::Kind kind, Symbol *symbol) {
2832
2842
PushScope (currScope ().MakeScope (kind, symbol));
2833
2843
}
@@ -2867,9 +2877,35 @@ void ScopeHandler::PopScope() {
2867
2877
// Entities that are not yet classified as objects or procedures are now
2868
2878
// assumed to be objects.
2869
2879
// TODO: Statement functions
2880
+ bool inDeviceSubprogram{false };
2881
+ const Symbol *scopeSym{currScope ().GetSymbol ()};
2882
+ if (currScope ().kind () == Scope::Kind::BlockConstruct) {
2883
+ scopeSym = GetProgramUnitContaining (currScope ()).GetSymbol ();
2884
+ }
2885
+ if (scopeSym) {
2886
+ if (auto *details{scopeSym->detailsIf <SubprogramDetails>()}) {
2887
+ // Check the current procedure is a device procedure to apply implicit
2888
+ // attribute at the end.
2889
+ if (auto attrs{details->cudaSubprogramAttrs ()}) {
2890
+ if (*attrs == common::CUDASubprogramAttrs::Device ||
2891
+ *attrs == common::CUDASubprogramAttrs::Global ||
2892
+ *attrs == common::CUDASubprogramAttrs::Grid_Global) {
2893
+ inDeviceSubprogram = true ;
2894
+ }
2895
+ }
2896
+ }
2897
+ }
2870
2898
for (auto &pair : currScope ()) {
2871
2899
ConvertToObjectEntity (*pair.second );
2872
2900
}
2901
+
2902
+ // Apply CUDA device attributes if in a device subprogram
2903
+ if (inDeviceSubprogram && currScope ().kind () == Scope::Kind::BlockConstruct) {
2904
+ for (auto &pair : currScope ()) {
2905
+ SetImplicitCUDADevice (*pair.second );
2906
+ }
2907
+ }
2908
+
2873
2909
funcResultStack_.Pop ();
2874
2910
// If popping back into a global scope, pop back to the top scope.
2875
2911
Scope *hermetic{context ().currentHermeticModuleFileScope ()};
@@ -9555,40 +9591,11 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
9555
9591
info.Resolve (&MakeSymbol (symbolName, Attrs{}, std::move (genericDetails)));
9556
9592
}
9557
9593
9558
- static void SetImplicitCUDADevice (bool inDeviceSubprogram, Symbol &symbol) {
9559
- if (inDeviceSubprogram && symbol.has <ObjectEntityDetails>()) {
9560
- auto *object{symbol.detailsIf <ObjectEntityDetails>()};
9561
- if (!object->cudaDataAttr () && !IsValue (symbol) &&
9562
- !IsFunctionResult (symbol)) {
9563
- // Implicitly set device attribute if none is set in device context.
9564
- object->set_cudaDataAttr (common::CUDADataAttr::Device);
9565
- }
9566
- }
9567
- }
9568
-
9569
9594
void ResolveNamesVisitor::FinishSpecificationPart (
9570
9595
const std::list<parser::DeclarationConstruct> &decls) {
9571
9596
misparsedStmtFuncFound_ = false ;
9572
9597
funcResultStack ().CompleteFunctionResultType ();
9573
9598
CheckImports ();
9574
- bool inDeviceSubprogram{false };
9575
- Symbol *scopeSym{currScope ().symbol ()};
9576
- if (currScope ().kind () == Scope::Kind::BlockConstruct) {
9577
- scopeSym = currScope ().parent ().symbol ();
9578
- }
9579
- if (scopeSym) {
9580
- if (auto *details{scopeSym->detailsIf <SubprogramDetails>()}) {
9581
- // Check the current procedure is a device procedure to apply implicit
9582
- // attribute at the end.
9583
- if (auto attrs{details->cudaSubprogramAttrs ()}) {
9584
- if (*attrs == common::CUDASubprogramAttrs::Device ||
9585
- *attrs == common::CUDASubprogramAttrs::Global ||
9586
- *attrs == common::CUDASubprogramAttrs::Grid_Global) {
9587
- inDeviceSubprogram = true ;
9588
- }
9589
- }
9590
- }
9591
- }
9592
9599
for (auto &pair : currScope ()) {
9593
9600
auto &symbol{*pair.second };
9594
9601
if (inInterfaceBlock ()) {
@@ -9623,11 +9630,6 @@ void ResolveNamesVisitor::FinishSpecificationPart(
9623
9630
SetBindNameOn (symbol);
9624
9631
}
9625
9632
}
9626
- if (currScope ().kind () == Scope::Kind::BlockConstruct) {
9627
- // Only look for specification in BlockConstruct. Other cases are done in
9628
- // ResolveSpecificationParts.
9629
- SetImplicitCUDADevice (inDeviceSubprogram, symbol);
9630
- }
9631
9633
}
9632
9634
currScope ().InstantiateDerivedTypes ();
9633
9635
for (const auto &decl : decls) {
@@ -10187,7 +10189,9 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
10187
10189
}
10188
10190
ApplyImplicitRules (symbol);
10189
10191
// Apply CUDA implicit attributes if needed.
10190
- SetImplicitCUDADevice (inDeviceSubprogram, symbol);
10192
+ if (inDeviceSubprogram) {
10193
+ SetImplicitCUDADevice (symbol);
10194
+ }
10191
10195
// Main program local objects usually don't have an implied SAVE attribute,
10192
10196
// as one might think, but in the exceptional case of a derived type
10193
10197
// local object that contains a coarray, we have to mark it as an
0 commit comments