@@ -861,6 +861,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
861
861
862
862
bool IsNestedInDirective (llvm::omp::Directive directive);
863
863
void ResolveOmpObjectList (const parser::OmpObjectList &, Symbol::Flag);
864
+ void ResolveOmpDesignator (
865
+ const parser::Designator &designator, Symbol::Flag ompFlag);
866
+ void ResolveOmpCommonBlock (const parser::Name &name, Symbol::Flag ompFlag);
864
867
void ResolveOmpObject (const parser::OmpObject &, Symbol::Flag);
865
868
Symbol *ResolveOmp (const parser::Name &, Symbol::Flag, Scope &);
866
869
Symbol *ResolveOmp (Symbol &, Symbol::Flag, Scope &);
@@ -2683,196 +2686,182 @@ static bool SymbolOrEquivalentIsInNamelist(const Symbol &symbol) {
2683
2686
});
2684
2687
}
2685
2688
2686
- void OmpAttributeVisitor::ResolveOmpObject (
2687
- const parser::OmpObject &ompObject , Symbol::Flag ompFlag) {
2689
+ void OmpAttributeVisitor::ResolveOmpDesignator (
2690
+ const parser::Designator &designator , Symbol::Flag ompFlag) {
2688
2691
unsigned version{context_.langOptions ().OpenMPVersion };
2689
- common::visit (
2690
- common::visitors{
2691
- [&](const parser::Designator &designator) {
2692
- if (const auto *name{
2693
- semantics::getDesignatorNameIfDataRef (designator)}) {
2694
- if (auto *symbol{ResolveOmp (*name, ompFlag, currScope ())}) {
2695
- auto checkExclusivelists =
2696
- [&](const Symbol *symbol1, Symbol::Flag firstOmpFlag,
2697
- const Symbol *symbol2, Symbol::Flag secondOmpFlag) {
2698
- if ((symbol1->test (firstOmpFlag) &&
2699
- symbol2->test (secondOmpFlag)) ||
2700
- (symbol1->test (secondOmpFlag) &&
2701
- symbol2->test (firstOmpFlag))) {
2702
- context_.Say (designator.source ,
2703
- " Variable '%s' may not "
2704
- " appear on both %s and %s "
2705
- " clauses on a %s construct" _err_en_US,
2706
- symbol2->name (),
2707
- Symbol::OmpFlagToClauseName (firstOmpFlag),
2708
- Symbol::OmpFlagToClauseName (secondOmpFlag),
2709
- parser::ToUpperCaseLetters (
2710
- llvm::omp::getOpenMPDirectiveName (
2711
- GetContext ().directive , version)
2712
- .str ()));
2713
- }
2714
- };
2715
- if (dataCopyingAttributeFlags.test (ompFlag)) {
2716
- CheckDataCopyingClause (*name, *symbol, ompFlag);
2717
- } else {
2718
- AddToContextObjectWithExplicitDSA (*symbol, ompFlag);
2719
- if (dataSharingAttributeFlags.test (ompFlag)) {
2720
- CheckMultipleAppearances (*name, *symbol, ompFlag);
2721
- }
2722
- if (privateDataSharingAttributeFlags.test (ompFlag)) {
2723
- CheckObjectIsPrivatizable (*name, *symbol, ompFlag);
2724
- }
2692
+ llvm::omp::Directive directive{GetContext ().directive };
2725
2693
2726
- if (ompFlag == Symbol::Flag::OmpAllocate) {
2727
- AddAllocateName (name);
2728
- }
2729
- }
2730
- if (ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective &&
2731
- IsAllocatable (*symbol) &&
2732
- !IsNestedInDirective (llvm::omp::Directive::OMPD_allocate)) {
2733
- context_.Say (designator.source ,
2734
- " List items specified in the ALLOCATE directive must not "
2735
- " have the ALLOCATABLE attribute unless the directive is "
2736
- " associated with an ALLOCATE statement" _err_en_US);
2737
- }
2738
- if ((ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective ||
2739
- ompFlag ==
2740
- Symbol::Flag::OmpExecutableAllocateDirective) &&
2741
- ResolveOmpObjectScope (name) == nullptr ) {
2742
- context_.Say (designator.source , // 2.15.3
2743
- " List items must be declared in the same scoping unit "
2744
- " in which the %s directive appears" _err_en_US,
2745
- parser::ToUpperCaseLetters (
2746
- llvm::omp::getOpenMPDirectiveName (
2747
- GetContext ().directive , version)
2748
- .str ()));
2749
- }
2750
- if (ompFlag == Symbol::Flag::OmpReduction) {
2751
- // Using variables inside of a namelist in OpenMP reductions
2752
- // is allowed by the standard, but is not allowed for
2753
- // privatisation. This looks like an oversight. If the
2754
- // namelist is hoisted to a global, we cannot apply the
2755
- // mapping for the reduction variable: resulting in incorrect
2756
- // results. Disabling this hoisting could make some real
2757
- // production code go slower. See discussion in #109303
2758
- if (SymbolOrEquivalentIsInNamelist (*symbol)) {
2759
- context_.Say (name->source ,
2760
- " Variable '%s' in NAMELIST cannot be in a REDUCTION clause" _err_en_US,
2761
- name->ToString ());
2762
- }
2763
- }
2764
- if (ompFlag == Symbol::Flag::OmpInclusiveScan ||
2765
- ompFlag == Symbol::Flag::OmpExclusiveScan) {
2766
- if (!symbol->test (Symbol::Flag::OmpInScanReduction)) {
2767
- context_.Say (name->source ,
2768
- " List item %s must appear in REDUCTION clause "
2769
- " with the INSCAN modifier of the parent "
2770
- " directive" _err_en_US,
2771
- name->ToString ());
2772
- }
2773
- }
2774
- if (ompFlag == Symbol::Flag::OmpDeclareTarget) {
2775
- if (symbol->IsFuncResult ()) {
2776
- if (Symbol * func{currScope ().symbol ()}) {
2777
- CHECK (func->IsSubprogram ());
2778
- func->set (ompFlag);
2779
- name->symbol = func;
2780
- }
2781
- }
2782
- }
2783
- if (GetContext ().directive ==
2784
- llvm::omp::Directive::OMPD_target_data) {
2785
- checkExclusivelists (symbol, Symbol::Flag::OmpUseDevicePtr,
2786
- symbol, Symbol::Flag::OmpUseDeviceAddr);
2787
- }
2788
- if (llvm::omp::allDistributeSet.test (GetContext ().directive )) {
2789
- checkExclusivelists (symbol, Symbol::Flag::OmpFirstPrivate,
2790
- symbol, Symbol::Flag::OmpLastPrivate);
2791
- }
2792
- if (llvm::omp::allTargetSet.test (GetContext ().directive )) {
2793
- checkExclusivelists (symbol, Symbol::Flag::OmpIsDevicePtr,
2794
- symbol, Symbol::Flag::OmpHasDeviceAddr);
2795
- const auto *hostAssocSym{symbol};
2796
- if (!(symbol->test (Symbol::Flag::OmpIsDevicePtr) ||
2797
- symbol->test (Symbol::Flag::OmpHasDeviceAddr))) {
2798
- if (const auto *details{
2799
- symbol->detailsIf <HostAssocDetails>()}) {
2800
- hostAssocSym = &details->symbol ();
2801
- }
2802
- }
2803
- Symbol::Flag dataMappingAttributeFlags[] = {
2804
- Symbol::Flag::OmpMapTo, Symbol::Flag::OmpMapFrom,
2805
- Symbol::Flag::OmpMapToFrom, Symbol::Flag::OmpMapStorage,
2806
- Symbol::Flag::OmpMapDelete, Symbol::Flag::OmpIsDevicePtr,
2807
- Symbol::Flag::OmpHasDeviceAddr};
2808
-
2809
- Symbol::Flag dataSharingAttributeFlags[] = {
2810
- Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
2811
- Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpShared,
2812
- Symbol::Flag::OmpLinear};
2813
-
2814
- // For OMP TARGET TEAMS directive some sharing attribute
2815
- // flags and mapping attribute flags can co-exist.
2816
- if (!(llvm::omp::allTeamsSet.test (GetContext ().directive ) ||
2817
- llvm::omp::allParallelSet.test (
2818
- GetContext ().directive ))) {
2819
- for (Symbol::Flag ompFlag1 : dataMappingAttributeFlags) {
2820
- for (Symbol::Flag ompFlag2 : dataSharingAttributeFlags) {
2821
- if ((hostAssocSym->test (ompFlag2) &&
2822
- hostAssocSym->test (
2823
- Symbol::Flag::OmpExplicit)) ||
2824
- (symbol->test (ompFlag2) &&
2825
- symbol->test (Symbol::Flag::OmpExplicit))) {
2826
- checkExclusivelists (
2827
- hostAssocSym, ompFlag1, symbol, ompFlag2);
2828
- }
2829
- }
2830
- }
2831
- }
2832
- }
2833
- }
2834
- } else {
2835
- // Array sections to be changed to substrings as needed
2836
- if (AnalyzeExpr (context_, designator)) {
2837
- if (std::holds_alternative<parser::Substring>(designator.u )) {
2838
- context_.Say (designator.source ,
2839
- " Substrings are not allowed on OpenMP "
2840
- " directives or clauses" _err_en_US);
2841
- }
2842
- }
2843
- // other checks, more TBD
2844
- }
2845
- },
2846
- [&](const parser::Name &name) { // common block
2847
- if (auto *symbol{ResolveOmpCommonBlockName (&name)}) {
2848
- if (!dataCopyingAttributeFlags.test (ompFlag)) {
2849
- CheckMultipleAppearances (
2850
- name, *symbol, Symbol::Flag::OmpCommonBlock);
2851
- }
2852
- // 2.15.3 When a named common block appears in a list, it has the
2853
- // same meaning as if every explicit member of the common block
2854
- // appeared in the list
2855
- auto &details{symbol->get <CommonBlockDetails>()};
2856
- unsigned index{0 };
2857
- for (auto &object : details.objects ()) {
2858
- if (auto *resolvedObject{
2859
- ResolveOmp (*object, ompFlag, currScope ())}) {
2860
- if (dataCopyingAttributeFlags.test (ompFlag)) {
2861
- CheckDataCopyingClause (name, *resolvedObject, ompFlag);
2862
- } else {
2863
- AddToContextObjectWithExplicitDSA (*resolvedObject, ompFlag);
2864
- }
2865
- details.replace_object (*resolvedObject, index);
2866
- }
2867
- index++;
2868
- }
2869
- } else {
2870
- context_.Say (name.source , // 2.15.3
2871
- " COMMON block must be declared in the same scoping unit "
2872
- " in which the OpenMP directive or clause appears" _err_en_US);
2694
+ const auto *name{semantics::getDesignatorNameIfDataRef (designator)};
2695
+ if (!name) {
2696
+ // Array sections to be changed to substrings as needed
2697
+ if (AnalyzeExpr (context_, designator)) {
2698
+ if (std::holds_alternative<parser::Substring>(designator.u )) {
2699
+ context_.Say (designator.source ,
2700
+ " Substrings are not allowed on OpenMP directives or clauses" _err_en_US);
2701
+ }
2702
+ }
2703
+ // other checks, more TBD
2704
+ return ;
2705
+ }
2706
+
2707
+ if (auto *symbol{ResolveOmp (*name, ompFlag, currScope ())}) {
2708
+ auto checkExclusivelists{//
2709
+ [&](const Symbol *symbol1, Symbol::Flag firstOmpFlag,
2710
+ const Symbol *symbol2, Symbol::Flag secondOmpFlag) {
2711
+ if ((symbol1->test (firstOmpFlag) && symbol2->test (secondOmpFlag)) ||
2712
+ (symbol1->test (secondOmpFlag) && symbol2->test (firstOmpFlag))) {
2713
+ context_.Say (designator.source ,
2714
+ " Variable '%s' may not appear on both %s and %s clauses on a %s construct" _err_en_US,
2715
+ symbol2->name (), Symbol::OmpFlagToClauseName (firstOmpFlag),
2716
+ Symbol::OmpFlagToClauseName (secondOmpFlag),
2717
+ parser::ToUpperCaseLetters (
2718
+ llvm::omp::getOpenMPDirectiveName (directive, version)));
2719
+ }
2720
+ }};
2721
+ if (dataCopyingAttributeFlags.test (ompFlag)) {
2722
+ CheckDataCopyingClause (*name, *symbol, ompFlag);
2723
+ } else {
2724
+ AddToContextObjectWithExplicitDSA (*symbol, ompFlag);
2725
+ if (dataSharingAttributeFlags.test (ompFlag)) {
2726
+ CheckMultipleAppearances (*name, *symbol, ompFlag);
2727
+ }
2728
+ if (privateDataSharingAttributeFlags.test (ompFlag)) {
2729
+ CheckObjectIsPrivatizable (*name, *symbol, ompFlag);
2730
+ }
2731
+
2732
+ if (ompFlag == Symbol::Flag::OmpAllocate) {
2733
+ AddAllocateName (name);
2734
+ }
2735
+ }
2736
+ if (ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective &&
2737
+ IsAllocatable (*symbol) &&
2738
+ !IsNestedInDirective (llvm::omp::Directive::OMPD_allocate)) {
2739
+ context_.Say (designator.source ,
2740
+ " List items specified in the ALLOCATE directive must not have the ALLOCATABLE attribute unless the directive is associated with an ALLOCATE statement" _err_en_US);
2741
+ }
2742
+ if ((ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective ||
2743
+ ompFlag == Symbol::Flag::OmpExecutableAllocateDirective) &&
2744
+ ResolveOmpObjectScope (name) == nullptr ) {
2745
+ context_.Say (designator.source , // 2.15.3
2746
+ " List items must be declared in the same scoping unit in which the %s directive appears" _err_en_US,
2747
+ parser::ToUpperCaseLetters (
2748
+ llvm::omp::getOpenMPDirectiveName (directive, version)));
2749
+ }
2750
+ if (ompFlag == Symbol::Flag::OmpReduction) {
2751
+ // Using variables inside of a namelist in OpenMP reductions
2752
+ // is allowed by the standard, but is not allowed for
2753
+ // privatisation. This looks like an oversight. If the
2754
+ // namelist is hoisted to a global, we cannot apply the
2755
+ // mapping for the reduction variable: resulting in incorrect
2756
+ // results. Disabling this hoisting could make some real
2757
+ // production code go slower. See discussion in #109303
2758
+ if (SymbolOrEquivalentIsInNamelist (*symbol)) {
2759
+ context_.Say (name->source ,
2760
+ " Variable '%s' in NAMELIST cannot be in a REDUCTION clause" _err_en_US,
2761
+ name->ToString ());
2762
+ }
2763
+ }
2764
+ if (ompFlag == Symbol::Flag::OmpInclusiveScan ||
2765
+ ompFlag == Symbol::Flag::OmpExclusiveScan) {
2766
+ if (!symbol->test (Symbol::Flag::OmpInScanReduction)) {
2767
+ context_.Say (name->source ,
2768
+ " List item %s must appear in REDUCTION clause with the INSCAN modifier of the parent directive" _err_en_US,
2769
+ name->ToString ());
2770
+ }
2771
+ }
2772
+ if (ompFlag == Symbol::Flag::OmpDeclareTarget) {
2773
+ if (symbol->IsFuncResult ()) {
2774
+ if (Symbol * func{currScope ().symbol ()}) {
2775
+ CHECK (func->IsSubprogram ());
2776
+ func->set (ompFlag);
2777
+ name->symbol = func;
2778
+ }
2779
+ }
2780
+ }
2781
+ if (directive == llvm::omp::Directive::OMPD_target_data) {
2782
+ checkExclusivelists (symbol, Symbol::Flag::OmpUseDevicePtr, symbol,
2783
+ Symbol::Flag::OmpUseDeviceAddr);
2784
+ }
2785
+ if (llvm::omp::allDistributeSet.test (directive)) {
2786
+ checkExclusivelists (symbol, Symbol::Flag::OmpFirstPrivate, symbol,
2787
+ Symbol::Flag::OmpLastPrivate);
2788
+ }
2789
+ if (llvm::omp::allTargetSet.test (directive)) {
2790
+ checkExclusivelists (symbol, Symbol::Flag::OmpIsDevicePtr, symbol,
2791
+ Symbol::Flag::OmpHasDeviceAddr);
2792
+ const auto *hostAssocSym{symbol};
2793
+ if (!symbol->test (Symbol::Flag::OmpIsDevicePtr) &&
2794
+ !symbol->test (Symbol::Flag::OmpHasDeviceAddr)) {
2795
+ if (const auto *details{symbol->detailsIf <HostAssocDetails>()}) {
2796
+ hostAssocSym = &details->symbol ();
2797
+ }
2798
+ }
2799
+ static Symbol::Flag dataMappingAttributeFlags[] = {//
2800
+ Symbol::Flag::OmpMapTo, Symbol::Flag::OmpMapFrom,
2801
+ Symbol::Flag::OmpMapToFrom, Symbol::Flag::OmpMapStorage,
2802
+ Symbol::Flag::OmpMapDelete, Symbol::Flag::OmpIsDevicePtr,
2803
+ Symbol::Flag::OmpHasDeviceAddr};
2804
+
2805
+ static Symbol::Flag dataSharingAttributeFlags[] = {//
2806
+ Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
2807
+ Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpShared,
2808
+ Symbol::Flag::OmpLinear};
2809
+
2810
+ // For OMP TARGET TEAMS directive some sharing attribute
2811
+ // flags and mapping attribute flags can co-exist.
2812
+ if (!llvm::omp::allTeamsSet.test (directive) &&
2813
+ !llvm::omp::allParallelSet.test (directive)) {
2814
+ for (Symbol::Flag ompFlag1 : dataMappingAttributeFlags) {
2815
+ for (Symbol::Flag ompFlag2 : dataSharingAttributeFlags) {
2816
+ if ((hostAssocSym->test (ompFlag2) &&
2817
+ hostAssocSym->test (Symbol::Flag::OmpExplicit)) ||
2818
+ (symbol->test (ompFlag2) &&
2819
+ symbol->test (Symbol::Flag::OmpExplicit))) {
2820
+ checkExclusivelists (hostAssocSym, ompFlag1, symbol, ompFlag2);
2873
2821
}
2874
- },
2875
- },
2822
+ }
2823
+ }
2824
+ }
2825
+ }
2826
+ }
2827
+ }
2828
+
2829
+ void OmpAttributeVisitor::ResolveOmpCommonBlock (
2830
+ const parser::Name &name, Symbol::Flag ompFlag) {
2831
+ if (auto *symbol{ResolveOmpCommonBlockName (&name)}) {
2832
+ if (!dataCopyingAttributeFlags.test (ompFlag)) {
2833
+ CheckMultipleAppearances (name, *symbol, Symbol::Flag::OmpCommonBlock);
2834
+ }
2835
+ // 2.15.3 When a named common block appears in a list, it has the
2836
+ // same meaning as if every explicit member of the common block
2837
+ // appeared in the list
2838
+ auto &details{symbol->get <CommonBlockDetails>()};
2839
+ for (auto [index, object] : llvm::enumerate (details.objects ())) {
2840
+ if (auto *resolvedObject{ResolveOmp (*object, ompFlag, currScope ())}) {
2841
+ if (dataCopyingAttributeFlags.test (ompFlag)) {
2842
+ CheckDataCopyingClause (name, *resolvedObject, ompFlag);
2843
+ } else {
2844
+ AddToContextObjectWithExplicitDSA (*resolvedObject, ompFlag);
2845
+ }
2846
+ details.replace_object (*resolvedObject, index);
2847
+ }
2848
+ }
2849
+ } else {
2850
+ context_.Say (name.source , // 2.15.3
2851
+ " COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears" _err_en_US);
2852
+ }
2853
+ }
2854
+
2855
+ void OmpAttributeVisitor::ResolveOmpObject (
2856
+ const parser::OmpObject &ompObject, Symbol::Flag ompFlag) {
2857
+ common::visit (common::visitors{
2858
+ [&](const parser::Designator &designator) {
2859
+ ResolveOmpDesignator (designator, ompFlag);
2860
+ },
2861
+ [&](const parser::Name &name) { // common block
2862
+ ResolveOmpCommonBlock (name, ompFlag);
2863
+ },
2864
+ },
2876
2865
ompObject.u );
2877
2866
}
2878
2867
0 commit comments