Skip to content

Commit d0708e6

Browse files
authored
[flang] Refine IMPORT processing in module file generation (llvm#77133)
Procedure interfaces emitted to module files are including IMPORT statements for some symbols that don't need to be imported (base types and procedure interfaces for components of imported derived types) and omitting others (procedure interfaces for bindings in locally-defined derived types that are material to the interface).
1 parent 6719a5a commit d0708e6

File tree

2 files changed

+146
-9
lines changed

2 files changed

+146
-9
lines changed

flang/lib/Semantics/mod-file.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,9 @@ void SubprogramSymbolCollector::DoSymbol(
14641464
DoType(details.type());
14651465
}
14661466
},
1467+
[this](const ProcBindingDetails &details) {
1468+
DoSymbol(details.symbol());
1469+
},
14671470
[](const auto &) {},
14681471
},
14691472
symbol.details());
@@ -1489,17 +1492,21 @@ void SubprogramSymbolCollector::DoType(const DeclTypeSpec *type) {
14891492
default:
14901493
if (const DerivedTypeSpec * derived{type->AsDerived()}) {
14911494
const auto &typeSymbol{derived->typeSymbol()};
1492-
if (const DerivedTypeSpec * extends{typeSymbol.GetParentTypeSpec()}) {
1493-
DoSymbol(extends->name(), extends->typeSymbol());
1494-
}
14951495
for (const auto &pair : derived->parameters()) {
14961496
DoParamValue(pair.second);
14971497
}
1498-
for (const auto &pair : *typeSymbol.scope()) {
1499-
const Symbol &comp{*pair.second};
1500-
DoSymbol(comp);
1498+
// The components of the type (including its parent component, if
1499+
// any) matter to IMPORT symbol collection only for derived types
1500+
// defined in the subprogram.
1501+
if (typeSymbol.owner() == scope_) {
1502+
if (const DerivedTypeSpec * extends{typeSymbol.GetParentTypeSpec()}) {
1503+
DoSymbol(extends->name(), extends->typeSymbol());
1504+
}
1505+
for (const auto &pair : *typeSymbol.scope()) {
1506+
DoSymbol(*pair.second);
1507+
}
15011508
}
1502-
DoSymbol(derived->name(), derived->typeSymbol());
1509+
DoSymbol(derived->name(), typeSymbol);
15031510
}
15041511
}
15051512
}
@@ -1531,8 +1538,8 @@ bool SubprogramSymbolCollector::NeedImport(
15311538
// detect import from ancestor of use-associated symbol
15321539
return found->has<UseDetails>() && found->owner() != scope_;
15331540
} else {
1534-
// "found" can be null in the case of a use-associated derived type's parent
1535-
// type
1541+
// "found" can be null in the case of a use-associated derived type's
1542+
// parent type
15361543
CHECK(symbol.has<DerivedTypeDetails>());
15371544
return false;
15381545
}

flang/test/Semantics/modfile61.f90

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
! RUN: %python %S/test_modfile.py %s %flang_fc1
2+
module m
3+
type t1
4+
procedure(p1), pointer, nopass :: p
5+
end type
6+
type t2
7+
procedure(p2), pointer, nopass :: p
8+
end type
9+
type t3
10+
procedure(p4), pointer, nopass :: p
11+
end type
12+
type t4
13+
procedure(p6), pointer, nopass :: p
14+
end type
15+
type t5
16+
procedure(p7), pointer, nopass :: p
17+
end type
18+
interface
19+
subroutine p1
20+
end
21+
subroutine p2
22+
end
23+
subroutine p3
24+
end
25+
subroutine p4
26+
end
27+
subroutine p5(c)
28+
import
29+
type(t3), intent(in) :: c
30+
end
31+
subroutine p6(d)
32+
import
33+
type(t5), intent(in) :: d
34+
end
35+
subroutine p7
36+
end
37+
subroutine p8
38+
end
39+
function f(a,b,dp)
40+
import
41+
type(t1), intent(in) :: a
42+
type, extends(t2) :: localt1
43+
procedure(p3), pointer, nopass :: p
44+
end type
45+
type, extends(localt1) :: localt2
46+
contains
47+
procedure, nopass :: p8
48+
end type
49+
type(localt2), intent(in) :: b
50+
procedure(p5) dp
51+
type(t4), pointer :: f
52+
end
53+
end interface
54+
end
55+
56+
!Expect: m.mod
57+
!module m
58+
!type::t1
59+
!procedure(p1),nopass,pointer::p
60+
!end type
61+
!type::t2
62+
!procedure(p2),nopass,pointer::p
63+
!end type
64+
!type::t3
65+
!procedure(p4),nopass,pointer::p
66+
!end type
67+
!type::t4
68+
!procedure(p6),nopass,pointer::p
69+
!end type
70+
!type::t5
71+
!procedure(p7),nopass,pointer::p
72+
!end type
73+
!interface
74+
!subroutine p1()
75+
!end
76+
!end interface
77+
!interface
78+
!subroutine p2()
79+
!end
80+
!end interface
81+
!interface
82+
!subroutine p3()
83+
!end
84+
!end interface
85+
!interface
86+
!subroutine p4()
87+
!end
88+
!end interface
89+
!interface
90+
!subroutine p5(c)
91+
!import::t3
92+
!type(t3),intent(in)::c
93+
!end
94+
!end interface
95+
!interface
96+
!subroutine p6(d)
97+
!import::t5
98+
!type(t5),intent(in)::d
99+
!end
100+
!end interface
101+
!interface
102+
!subroutine p7()
103+
!end
104+
!end interface
105+
!interface
106+
!subroutine p8()
107+
!end
108+
!end interface
109+
!interface
110+
!function f(a,b,dp)
111+
!import::p3
112+
!import::p5
113+
!import::p8
114+
!import::t1
115+
!import::t2
116+
!import::t4
117+
!type(t1),intent(in)::a
118+
!type,extends(t2)::localt1
119+
!procedure(p3),nopass,pointer::p
120+
!end type
121+
!type,extends(localt1)::localt2
122+
!contains
123+
!procedure,nopass::p8
124+
!end type
125+
!type(localt2),intent(in)::b
126+
!procedure(p5)::dp
127+
!type(t4),pointer::f
128+
!end
129+
!end interface
130+
!end

0 commit comments

Comments
 (0)