static const SourceName *GetSubmoduleParent(const parser::Program &);
static std::string ModFilePath(
const std::string &, const SourceName &, const std::string &);
+static std::vector<const Symbol *> CollectSymbols(const Scope &);
static void PutEntity(std::ostream &, const Symbol &);
static void PutObjectEntity(std::ostream &, const Symbol &);
static void PutProcEntity(std::ostream &, const 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{
if (details.hasTypeParams()) {
bool first{true};
decls_ << '(';
- for (const auto *symbol : SortSymbols(CollectSymbols(typeScope))) {
+ for (const auto *symbol : CollectSymbols(typeScope)) {
if (symbol->has<TypeParamDetails>()) {
PutLower(first ? decls_ : decls_ << ',', *symbol);
first = false;
}
}
+// Collect the symbols of this scope sorted by their original order, not name.
+std::vector<const Symbol *> CollectSymbols(const Scope &scope) {
+ std::set<const Symbol *> symbols; // to prevent duplicates
+ std::vector<const Symbol *> 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); },