forked from OSchip/llvm-project
[flang] Write private symbols to .mod files
We were trying to write only symbols that are part of the public API of a module to the .mod file. The problem with that is that submodules need access to the private symbols in their ancestor modules and submodules. For now, just write out all of the symbols, private or otherwise. We could be more precise by omitting some private symbols for modules that don't have separate module procedures and so can't have submodules. Also, the old implementation went into an infinite loop for recursive derived types. This makes CollectSymbols simpler, so have it do both the collecting and sorting. Make it static so that the types don't have to be defined in mod-file.h. Original-commit: flang-compiler/f18@33a10d6238 Reviewed-on: https://github.com/flang-compiler/f18/pull/177 Tree-same-pre-rewrite: false
This commit is contained in:
parent
78c62eaf02
commit
7ebbe7dca4
|
@ -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<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 &);
|
||||
|
@ -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<TypeParamDetails>()) {
|
||||
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<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); },
|
||||
|
|
|
@ -47,9 +47,6 @@ public:
|
|||
bool WriteAll();
|
||||
|
||||
private:
|
||||
using symbolSet = std::set<const Symbol *>;
|
||||
using symbolVector = std::vector<const Symbol *>;
|
||||
|
||||
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 &);
|
||||
|
|
|
@ -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 &);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -36,6 +36,7 @@ end
|
|||
!Expect: m1.mod
|
||||
!module m1
|
||||
!integer::x1
|
||||
!integer,private::x2
|
||||
!end
|
||||
|
||||
!Expect: m2.mod
|
||||
|
|
Loading…
Reference in New Issue