[flang] Emit missing IMPORTs in module file interfaces

When a symbol from the enclosing scope is necessary to declare
a procedure or procedure pointer dummy argument or function result
for a procedure interface, note it in the collection of symbols to
be imported when scanning that interface.

Differential Revision: https://reviews.llvm.org/D132683
This commit is contained in:
Peter Klausler 2022-08-25 10:22:10 -07:00
parent b05486dbf9
commit df3e5f18d0
3 changed files with 51 additions and 2 deletions

View File

@ -1185,6 +1185,12 @@ void SubprogramSymbolCollector::DoSymbol(
DoSymbol(*object);
}
},
[this](const ProcEntityDetails &details) {
if (const Symbol * symbol{details.interface().symbol()}) {
DoSymbol(*symbol);
}
DoType(details.interface().type());
},
[](const auto &) {},
},
symbol.details());
@ -1241,6 +1247,8 @@ bool SubprogramSymbolCollector::NeedImport(
const SourceName &name, const Symbol &symbol) {
if (!isInterface_) {
return false;
} else if (&symbol == scope_.symbol()) {
return false;
} else if (symbol.owner().Contains(scope_)) {
return true;
} else if (const Symbol * found{scope_.FindSymbol(name)}) {

View File

@ -39,17 +39,17 @@ end module m
!contains
!function f(x)
!real(4),intent(in)::x
!procedure(used_int),pointer::f
!abstract interface
!subroutine used_int(x,p)
!real(4),intent(out)::x
!procedure(inner_int)::p
!interface
!subroutine inner_int(x)
!real(4),intent(out)::x
!end
!end interface
!procedure(inner_int)::p
!end
!end interface
!procedure(used_int),pointer::f
!end
!end

View File

@ -0,0 +1,41 @@
! RUN: %python %S/test_modfile.py %s %flang_fc1
! Ensure that symbols and types needed to declare procedures and procedure pointers
! are properly imported into interfaces.
module m
type :: t
end type
procedure(sin) :: ext
interface
subroutine subr(p1,p2)
import ext, t
procedure(ext) :: p1
procedure(type(t)), pointer :: p2
end subroutine
function fun() result(res)
import subr
procedure(subr), pointer :: res
end function
end interface
end module
!Expect: m.mod
!module m
!type::t
!end type
!intrinsic::sin
!procedure(sin)::ext
!interface
!subroutine subr(p1,p2)
!import::ext
!import::t
!procedure(ext)::p1
!procedure(type(t)),pointer::p2
!end
!end interface
!interface
!function fun() result(res)
!import::subr
!procedure(subr),pointer::res
!end
!end interface
!end