[flang] Fix bug in writing PRIVATE subprograms to .mod file

Subprograms can't have the PRIVATE prefix on them when they are defined.
So if they are private, add a private-stmt for them.

Fixes flang-compiler/f18#519

Original-commit: flang-compiler/f18@d3670aa176
Reviewed-on: https://github.com/flang-compiler/f18/pull/523
This commit is contained in:
Tim Keith 2019-06-24 12:35:17 -07:00
parent ba7731ec6b
commit 86132a15dc
2 changed files with 56 additions and 3 deletions

View File

@ -52,6 +52,7 @@ static void PutBound(std::ostream &, const Bound &);
static std::ostream &PutAttrs(std::ostream &, Attrs,
const MaybeExpr & = std::nullopt, std::string before = ","s,
std::string after = ""s);
static std::ostream &PutAttr(std::ostream &, Attr);
static std::ostream &PutLower(std::ostream &, const Symbol &);
static std::ostream &PutLower(std::ostream &, const DeclTypeSpec &);
static std::ostream &PutLower(std::ostream &, const std::string &);
@ -284,6 +285,11 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) {
bindAttrs.set(Attr::BIND_C, true);
attrs.set(Attr::BIND_C, false);
}
if (attrs.test(Attr::PRIVATE)) {
PutAttr(decls_, Attr::PRIVATE) << "::";
PutLower(decls_, symbol) << "\n";
attrs.set(Attr::PRIVATE, false);
}
bool isInterface{details.isInterface()};
std::ostream &os{isInterface ? decls_ : contains_};
if (isInterface) {
@ -365,7 +371,7 @@ void ModFileWriter::PutUse(const Symbol &symbol) {
void ModFileWriter::PutUseExtraAttr(
Attr attr, const Symbol &local, const Symbol &use) {
if (local.attrs().test(attr) && !use.attrs().test(attr)) {
PutLower(useExtraAttrs_, AttrToString(attr)) << "::";
PutAttr(useExtraAttrs_, attr) << "::";
PutLower(useExtraAttrs_, local) << '\n';
}
}
@ -552,12 +558,16 @@ std::ostream &PutAttrs(std::ostream &os, Attrs attrs, const MaybeExpr &bindName,
for (std::size_t i{0}; i < Attr_enumSize; ++i) {
Attr attr{static_cast<Attr>(i)};
if (attrs.test(attr)) {
PutLower(os << before, AttrToString(attr)) << after;
PutAttr(os << before, attr) << after;
}
}
return os;
}
std::ostream &PutAttr(std::ostream &os, Attr attr) {
return PutLower(os, AttrToString(attr));
}
std::ostream &PutLower(std::ostream &os, const Symbol &symbol) {
return PutLower(os, symbol.name().ToString());
}

View File

@ -1,4 +1,4 @@
! Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
! Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
@ -37,3 +37,46 @@ end
!end type
!type(t)::x
!end
! Check correct modfile generation for type with private module procedure.
module m2
private :: s1
contains
subroutine s1()
end
subroutine s2()
end
end
!Expect: m2.mod
!module m2
! private::s1
!contains
! subroutine s1()
! end
! subroutine s2()
! end
!end
module m3
private
public :: f1
contains
real function f1()
end
real function f2()
end
end
!Expect: m3.mod
!module m3
! private::f2
!contains
! function f1()
! real(4)::f1
! end
! function f2()
! real(4)::f2
! end
!end