From 563e65ded1613ba8bb3ec8735a966315ddc56835 Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Tue, 26 Feb 2019 13:08:59 -0800 Subject: [PATCH] [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@1778efe981812b1d1d1b684647c72085f44c3209 Reviewed-on: https://github.com/flang-compiler/f18/pull/305 Tree-same-pre-rewrite: false --- flang/lib/semantics/mod-file.cc | 45 ++++++++++++++++++++++---------------- flang/lib/semantics/mod-file.h | 2 +- flang/lib/semantics/symbol.h | 1 + flang/test/semantics/modfile07.f90 | 27 ++++++++++++++++++++++- 4 files changed, 54 insertions(+), 21 deletions(-) diff --git a/flang/lib/semantics/mod-file.cc b/flang/lib/semantics/mod-file.cc index d70b3ea..1f0d38f 100644 --- a/flang/lib/semantics/mod-file.cc +++ b/flang/lib/semantics/mod-file.cc @@ -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) { diff --git a/flang/lib/semantics/mod-file.h b/flang/lib/semantics/mod-file.h index 6b08c79..38d7bc0 100644 --- a/flang/lib/semantics/mod-file.h +++ b/flang/lib/semantics/mod-file.h @@ -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 &); diff --git a/flang/lib/semantics/symbol.h b/flang/lib/semantics/symbol.h index 8b5fdec..e88deef 100644 --- a/flang/lib/semantics/symbol.h +++ b/flang/lib/semantics/symbol.h @@ -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. diff --git a/flang/test/semantics/modfile07.f90 b/flang/test/semantics/modfile07.f90 index ec6843eee..a1ca7ce 100644 --- a/flang/test/semantics/modfile07.f90 +++ b/flang/test/semantics/modfile07.f90 @@ -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 -- 2.7.4