forked from OSchip/llvm-project
[flang] Fix .mod file for symbols with same name as generic
When a generic has the same name as a module procedure or derived type, the latter weren't being written to the `.mod` file. Fix that by calling `PutSymbol()` on those symbols from the generic. Change `PutSymbol()` to accept `Symbol *` to make that more convenient. Original-commit: flang-compiler/f18@1778efe981 Reviewed-on: https://github.com/flang-compiler/f18/pull/305 Tree-same-pre-rewrite: false
This commit is contained in:
parent
9a497ddbad
commit
563e65ded1
|
@ -125,7 +125,7 @@ std::string ModFileWriter::GetAsString(const Symbol &symbol) {
|
|||
void ModFileWriter::PutSymbols(const Scope &scope) {
|
||||
std::stringstream typeBindings; // stuff after CONTAINS in derived type
|
||||
for (const auto *symbol : CollectSymbols(scope)) {
|
||||
PutSymbol(typeBindings, *symbol);
|
||||
PutSymbol(typeBindings, symbol);
|
||||
}
|
||||
if (auto str{typeBindings.str()}; !str.empty()) {
|
||||
decls_ << "contains\n" << str;
|
||||
|
@ -135,37 +135,44 @@ void ModFileWriter::PutSymbols(const Scope &scope) {
|
|||
// Emit a symbol to decls_, except for bindings in a derived type (type-bound
|
||||
// procedures, type-bound generics, final procedures) which go to typeBindings.
|
||||
void ModFileWriter::PutSymbol(
|
||||
std::stringstream &typeBindings, const Symbol &symbol) {
|
||||
std::stringstream &typeBindings, const Symbol *symbol) {
|
||||
if (symbol == nullptr) {
|
||||
return;
|
||||
}
|
||||
std::visit(
|
||||
common::visitors{
|
||||
[&](const ModuleDetails &) { /* should be current module */ },
|
||||
[&](const DerivedTypeDetails &) { PutDerivedType(symbol); },
|
||||
[&](const SubprogramDetails &) { PutSubprogram(symbol); },
|
||||
[&](const GenericDetails &) { PutGeneric(symbol); },
|
||||
[&](const UseDetails &) { PutUse(symbol); },
|
||||
[&](const DerivedTypeDetails &) { PutDerivedType(*symbol); },
|
||||
[&](const SubprogramDetails &) { PutSubprogram(*symbol); },
|
||||
[&](const GenericDetails &x) {
|
||||
PutGeneric(*symbol);
|
||||
PutSymbol(typeBindings, x.specific());
|
||||
PutSymbol(typeBindings, x.derivedType());
|
||||
},
|
||||
[&](const UseDetails &) { PutUse(*symbol); },
|
||||
[](const UseErrorDetails &) {},
|
||||
[&](const ProcBindingDetails &x) {
|
||||
bool deferred{symbol.attrs().test(Attr::DEFERRED)};
|
||||
bool deferred{symbol->attrs().test(Attr::DEFERRED)};
|
||||
typeBindings << "procedure";
|
||||
if (deferred) {
|
||||
PutLower(typeBindings << '(', x.symbol()) << ')';
|
||||
}
|
||||
PutPassName(typeBindings, x.passName());
|
||||
PutAttrs(typeBindings, symbol.attrs());
|
||||
PutLower(typeBindings << "::", symbol);
|
||||
if (!deferred && x.symbol().name() != symbol.name()) {
|
||||
PutAttrs(typeBindings, symbol->attrs());
|
||||
PutLower(typeBindings << "::", *symbol);
|
||||
if (!deferred && x.symbol().name() != symbol->name()) {
|
||||
PutLower(typeBindings << "=>", x.symbol());
|
||||
}
|
||||
typeBindings << '\n';
|
||||
},
|
||||
[&](const GenericBindingDetails &x) {
|
||||
for (const auto *proc : x.specificProcs()) {
|
||||
PutLower(typeBindings << "generic::", symbol);
|
||||
PutLower(typeBindings << "generic::", *symbol);
|
||||
PutLower(typeBindings << "=>", *proc) << '\n';
|
||||
}
|
||||
},
|
||||
[&](const NamelistDetails &x) {
|
||||
PutLower(decls_ << "namelist/", symbol);
|
||||
PutLower(decls_ << "namelist/", *symbol);
|
||||
char sep{'/'};
|
||||
for (const auto *object : x.objects()) {
|
||||
PutLower(decls_ << sep, *object);
|
||||
|
@ -174,26 +181,26 @@ void ModFileWriter::PutSymbol(
|
|||
decls_ << '\n';
|
||||
},
|
||||
[&](const CommonBlockDetails &x) {
|
||||
PutLower(decls_ << "common/", symbol);
|
||||
PutLower(decls_ << "common/", *symbol);
|
||||
char sep = '/';
|
||||
for (const auto *object : x.objects()) {
|
||||
PutLower(decls_ << sep, *object);
|
||||
sep = ',';
|
||||
}
|
||||
decls_ << '\n';
|
||||
if (symbol.attrs().test(Attr::BIND_C)) {
|
||||
PutAttrs(decls_, symbol.attrs(), x.bindName(), ""s);
|
||||
PutLower(decls_ << "::/", symbol) << "/\n";
|
||||
if (symbol->attrs().test(Attr::BIND_C)) {
|
||||
PutAttrs(decls_, symbol->attrs(), x.bindName(), ""s);
|
||||
PutLower(decls_ << "::/", *symbol) << "/\n";
|
||||
}
|
||||
},
|
||||
[&](const FinalProcDetails &) {
|
||||
PutLower(typeBindings << "final::", symbol) << '\n';
|
||||
PutLower(typeBindings << "final::", *symbol) << '\n';
|
||||
},
|
||||
[](const HostAssocDetails &) {},
|
||||
[](const MiscDetails &) {},
|
||||
[&](const auto &) { PutEntity(decls_, symbol); },
|
||||
[&](const auto &) { PutEntity(decls_, *symbol); },
|
||||
},
|
||||
symbol.details());
|
||||
symbol->details());
|
||||
}
|
||||
|
||||
void ModFileWriter::PutDerivedType(const Symbol &typeSymbol) {
|
||||
|
|
|
@ -51,7 +51,7 @@ private:
|
|||
void Write(const Symbol &);
|
||||
std::string GetAsString(const Symbol &);
|
||||
void PutSymbols(const Scope &);
|
||||
void PutSymbol(std::stringstream &, const Symbol &);
|
||||
void PutSymbol(std::stringstream &, const Symbol *);
|
||||
void PutDerivedType(const Symbol &);
|
||||
void PutSubprogram(const Symbol &);
|
||||
void PutGeneric(const Symbol &);
|
||||
|
|
|
@ -371,6 +371,7 @@ public:
|
|||
void add_specificProc(const Symbol &proc) { specificProcs_.push_back(&proc); }
|
||||
|
||||
Symbol *specific() { return specific_; }
|
||||
const Symbol *specific() const { return specific_; }
|
||||
void set_specific(Symbol &specific);
|
||||
|
||||
// Derived type with same name as generic, if any.
|
||||
|
|
|
@ -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,6 +37,19 @@ contains
|
|||
end
|
||||
end
|
||||
|
||||
module m2
|
||||
interface foo
|
||||
procedure foo
|
||||
end interface
|
||||
type :: foo
|
||||
real :: x
|
||||
end type
|
||||
contains
|
||||
complex function foo()
|
||||
foo = 1.0
|
||||
end
|
||||
end
|
||||
|
||||
!Expect: m.mod
|
||||
!module m
|
||||
! generic::foo=>s1,s2
|
||||
|
@ -59,3 +72,15 @@ end
|
|||
! integer(4)::x
|
||||
! end
|
||||
!end
|
||||
|
||||
!Expect: m2.mod
|
||||
!module m2
|
||||
! generic::foo=>foo
|
||||
! type::foo
|
||||
! real(4)::x
|
||||
! end type
|
||||
!contains
|
||||
! function foo()
|
||||
! complex(4)::foo
|
||||
! end
|
||||
!end
|
||||
|
|
Loading…
Reference in New Issue