diff --git a/flang/lib/semantics/mod-file.cc b/flang/lib/semantics/mod-file.cc index b93e4c85f23b..403daf3b2e05 100644 --- a/flang/lib/semantics/mod-file.cc +++ b/flang/lib/semantics/mod-file.cc @@ -40,6 +40,7 @@ static constexpr auto magic{"!mod$ v1 sum:"}; static const SourceName *GetSubmoduleParent(const parser::Program &); static std::string ModFilePath( const std::string &, const SourceName &, const std::string &); +static std::vector CollectSymbols(const Scope &); static void PutEntity(std::ostream &, const Symbol &); static void PutObjectEntity(std::ostream &, const Symbol &); static void PutProcEntity(std::ostream &, const Symbol &); @@ -123,50 +124,11 @@ std::string ModFileWriter::GetAsString(const Symbol &symbol) { // Put out the visible symbols from scope. void ModFileWriter::PutSymbols(const Scope &scope) { bool didContains{false}; - for (const auto *symbol : SortSymbols(CollectSymbols(scope))) { + for (const auto *symbol : CollectSymbols(scope)) { PutSymbol(*symbol, didContains); } } -// Sort symbols by their original order, not by name. -ModFileWriter::symbolVector ModFileWriter::SortSymbols( - const ModFileWriter::symbolSet symbols) { - ModFileWriter::symbolVector sorted; - sorted.reserve(symbols.size()); - for (const auto *symbol : symbols) { - sorted.push_back(symbol); - } - auto compare{[](const Symbol *x, const Symbol *y) { - return x->name().begin() < y->name().begin(); - }}; - std::sort(sorted.begin(), sorted.end(), compare); - return sorted; -} - -// Return all symbols needed from this scope. -ModFileWriter::symbolSet ModFileWriter::CollectSymbols(const Scope &scope) { - ModFileWriter::symbolSet symbols; - for (const auto &pair : scope) { - auto *symbol{pair.second}; - // include all components of derived types and other non-private symbols - if (scope.kind() == Scope::Kind::DerivedType || - !symbol->attrs().test(Attr::PRIVATE)) { - symbols.insert(symbol); - // ensure the type symbol is included too, even if private - if (const auto *type{symbol->GetType()}) { - auto category{type->category()}; - if (category == DeclTypeSpec::TypeDerived || - category == DeclTypeSpec::ClassDerived) { - auto *typeSymbol{type->derivedTypeSpec().scope()->symbol()}; - symbols.insert(typeSymbol); - } - } - // TODO: other related symbols, e.g. in initial values - } - } - return symbols; -} - void ModFileWriter::PutSymbol(const Symbol &symbol, bool &didContains) { std::visit( common::visitors{ @@ -216,7 +178,7 @@ void ModFileWriter::PutDerivedType(const Symbol &typeSymbol) { if (details.hasTypeParams()) { bool first{true}; decls_ << '('; - for (const auto *symbol : SortSymbols(CollectSymbols(typeScope))) { + for (const auto *symbol : CollectSymbols(typeScope)) { if (symbol->has()) { PutLower(first ? decls_ : decls_ << ',', *symbol); first = false; @@ -311,10 +273,26 @@ void ModFileWriter::PutUseExtraAttr( } } +// Collect the symbols of this scope sorted by their original order, not name. +std::vector CollectSymbols(const Scope &scope) { + std::set symbols; // to prevent duplicates + std::vector sorted; + sorted.reserve(scope.size()); + for (const auto &pair : scope) { + auto *symbol{pair.second}; + if (symbols.insert(symbol).second) { + sorted.push_back(symbol); + } + } + std::sort(sorted.begin(), sorted.end(), [](const Symbol *x, const Symbol *y) { + return x->name().begin() < y->name().begin(); + }); + return sorted; +} + void PutEntity(std::ostream &os, const Symbol &symbol) { std::visit( common::visitors{ - [&](const EntityDetails &) { PutObjectEntity(os, symbol); }, [&](const ObjectEntityDetails &) { PutObjectEntity(os, symbol); }, [&](const ProcEntityDetails &) { PutProcEntity(os, symbol); }, [&](const TypeParamDetails &) { PutTypeParam(os, symbol); }, diff --git a/flang/lib/semantics/mod-file.h b/flang/lib/semantics/mod-file.h index 091f520da29f..aad20294681a 100644 --- a/flang/lib/semantics/mod-file.h +++ b/flang/lib/semantics/mod-file.h @@ -47,9 +47,6 @@ public: bool WriteAll(); private: - using symbolSet = std::set; - using symbolVector = std::vector; - std::string dir_{"."}; // The mod file consists of uses, declarations, and contained subprograms: std::stringstream uses_; @@ -64,8 +61,6 @@ private: void Write(const Symbol &); std::string GetAsString(const Symbol &); void PutSymbols(const Scope &); - symbolVector SortSymbols(const symbolSet); - symbolSet CollectSymbols(const Scope &); void PutSymbol(const Symbol &, bool &); void PutDerivedType(const Symbol &); void PutSubprogram(const Symbol &); diff --git a/flang/lib/semantics/scope.h b/flang/lib/semantics/scope.h index c786e517d6b1..8db42a4d2581 100644 --- a/flang/lib/semantics/scope.h +++ b/flang/lib/semantics/scope.h @@ -86,6 +86,7 @@ public: iterator find(const SourceName &name); const_iterator find(const SourceName &name) const; size_type erase(const SourceName &); + size_type size() const { return symbols_.size(); } // Look for symbol by name in this scope and host (depending on imports). Symbol *FindSymbol(const SourceName &); diff --git a/flang/test/semantics/modfile01.f90 b/flang/test/semantics/modfile01.f90 index a16b811a8020..73f33254e70b 100644 --- a/flang/test/semantics/modfile01.f90 +++ b/flang/test/semantics/modfile01.f90 @@ -28,9 +28,12 @@ end !Expect: m.mod !module m !integer::i +!integer,private::j !type::t !integer::i !integer,private::j !end type +!type,private::u +!end type !type(t)::x !end diff --git a/flang/test/semantics/modfile02.f90 b/flang/test/semantics/modfile02.f90 index 1841cae3512a..e852221035e7 100644 --- a/flang/test/semantics/modfile02.f90 +++ b/flang/test/semantics/modfile02.f90 @@ -30,5 +30,9 @@ end !type,private::t1 !integer::i !end type +!type,private::t2 +!integer::i +!end type !type(t1)::x1 +!type(t2),private::x2 !end diff --git a/flang/test/semantics/modfile03.f90 b/flang/test/semantics/modfile03.f90 index fb743d0dfa78..91f0009d183f 100644 --- a/flang/test/semantics/modfile03.f90 +++ b/flang/test/semantics/modfile03.f90 @@ -36,6 +36,7 @@ end !Expect: m1.mod !module m1 !integer::x1 +!integer,private::x2 !end !Expect: m2.mod