[llvm-branch-commits] [flang] d55627d - [flang] Fix bugs in .mod file for abstract interface
Tim Keith via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Dec 28 08:54:47 PST 2020
Author: Tim Keith
Date: 2020-12-28T08:50:32-08:00
New Revision: d55627d221be8154cbdf454fa727afcc3f716b08
URL: https://github.com/llvm/llvm-project/commit/d55627d221be8154cbdf454fa727afcc3f716b08
DIFF: https://github.com/llvm/llvm-project/commit/d55627d221be8154cbdf454fa727afcc3f716b08.diff
LOG: [flang] Fix bugs in .mod file for abstract interface
When an abstract interface is defined, add the ABSTRACT attribute to
subprogram symbols that define the interface body. Make use of that
when writing .mod files to include "abstract" on the interface statement.
Also, fix a problem with the order of symbols in a .mod file. Sometimes
a name is mentioned before the "real" declaration, e.g. in an access
statement. We want the order to be based on the real definitions. In
these cases we replace the symbol name with an identical name with a
different source location. Then by sorting based on the source location
we get symbols in the right order.
Differential Revision: https://reviews.llvm.org/D93572
Added:
Modified:
flang/lib/Semantics/mod-file.cpp
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/modfile10.f90
flang/test/Semantics/procinterface01.f90
flang/test/Semantics/symbol15.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 99ea65b753a6..f8e5889e4698 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -319,6 +319,10 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) {
bindAttrs.set(Attr::BIND_C, true);
attrs.set(Attr::BIND_C, false);
}
+ bool isAbstract{attrs.test(Attr::ABSTRACT)};
+ if (isAbstract) {
+ attrs.set(Attr::ABSTRACT, false);
+ }
Attrs prefixAttrs{subprogramPrefixAttrs & attrs};
// emit any non-prefix attributes in an attribute statement
attrs &= ~subprogramPrefixAttrs;
@@ -331,7 +335,7 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) {
bool isInterface{details.isInterface()};
llvm::raw_ostream &os{isInterface ? decls_ : contains_};
if (isInterface) {
- os << "interface\n";
+ os << (isAbstract ? "abstract " : "") << "interface\n";
}
PutAttrs(os, prefixAttrs, std::nullopt, ""s, " "s);
os << (details.isFunction() ? "function " : "subroutine ");
@@ -457,6 +461,11 @@ void CollectSymbols(
}
}
}
+ // Sort most symbols by name: use of Symbol::ReplaceName ensures the source
+ // location of a symbol's name is the first "real" use.
+ std::sort(sorted.begin(), sorted.end(), [](SymbolRef x, SymbolRef y) {
+ return x->name().begin() < y->name().begin();
+ });
sorted.insert(sorted.end(), namelist.begin(), namelist.end());
for (const auto &pair : scope.commonBlocks()) {
sorted.push_back(*pair.second);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 8d5284131cc0..73c624aefa22 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3085,11 +3085,14 @@ Symbol &SubprogramVisitor::PushSubprogramScope(
symbol = &MakeSymbol(name, SubprogramDetails{});
}
symbol->set(subpFlag);
+ symbol->ReplaceName(name.source);
PushScope(Scope::Kind::Subprogram, symbol);
auto &details{symbol->get<SubprogramDetails>()};
if (inInterfaceBlock()) {
details.set_isInterface();
- if (!isAbstract()) {
+ if (isAbstract()) {
+ symbol->attrs().set(Attr::ABSTRACT);
+ } else {
MakeExternal(*symbol);
}
if (isGeneric()) {
diff --git a/flang/test/Semantics/modfile10.f90 b/flang/test/Semantics/modfile10.f90
index ef10f1f23e8e..996178f5896d 100644
--- a/flang/test/Semantics/modfile10.f90
+++ b/flang/test/Semantics/modfile10.f90
@@ -90,3 +90,40 @@ subroutine test
! subroutine test()
! end
!end
+
+! Ensure the type is emitted before its use
+module m2
+ private s
+ type :: t
+ contains
+ procedure :: foo
+ end type
+ abstract interface
+ subroutine s(x)
+ import
+ type(t) :: x
+ end subroutine
+ end interface
+contains
+ subroutine foo(x)
+ class(t) :: x
+ end subroutine
+end module
+!Expect: m2.mod
+!module m2
+! type::t
+! contains
+! procedure::foo
+! end type
+! private::s
+! abstract interface
+! subroutine s(x)
+! import::t
+! type(t)::x
+! end
+! end interface
+!contains
+! subroutine foo(x)
+! class(t)::x
+! end
+!end
diff --git a/flang/test/Semantics/procinterface01.f90 b/flang/test/Semantics/procinterface01.f90
index a960922d5637..dd9fd3b66041 100644
--- a/flang/test/Semantics/procinterface01.f90
+++ b/flang/test/Semantics/procinterface01.f90
@@ -5,7 +5,7 @@
!DEF: /module1 Module
module module1
abstract interface
- !DEF: /module1/abstract1 PUBLIC (Function) Subprogram REAL(4)
+ !DEF: /module1/abstract1 ABSTRACT, PUBLIC (Function) Subprogram REAL(4)
!DEF: /module1/abstract1/x INTENT(IN) ObjectEntity REAL(4)
real function abstract1(x)
!REF: /module1/abstract1/x
diff --git a/flang/test/Semantics/symbol15.f90 b/flang/test/Semantics/symbol15.f90
index ddd3772252dc..cc230ff1fc03 100644
--- a/flang/test/Semantics/symbol15.f90
+++ b/flang/test/Semantics/symbol15.f90
@@ -5,7 +5,7 @@
module m
implicit none
abstract interface
- !DEF: /m/iface PUBLIC (Subroutine) Subprogram
+ !DEF: /m/iface ABSTRACT, PUBLIC (Subroutine) Subprogram
subroutine iface
end subroutine
end interface
More information about the llvm-branch-commits
mailing list