Add ModuleDecl::ReverseFullNameIterator

Package up the logic that generates a full Clang module name, so that
(a) we don't have to deal with clang::Module in quite as many places
in the /Swift/ compiler, and (b) we can avoid the cost of a temporary
string in a few places.

The main places where this is /not/ adopted is where we don't just
want to know the parent module name, but actually the module itself.
This is mostly indexing-related queries, which use the very similar
ModuleEntity class also defined in Module.h. I didn't quite see an
obvious way to unify these, but that might be where we want to go.

No functionality change.
This commit is contained in:
Jordan Rose
2018-09-06 19:47:25 -07:00
parent d6133f408d
commit 37ec248823
7 changed files with 113 additions and 61 deletions

View File

@@ -1005,6 +1005,55 @@ bool ModuleDecl::isSameAccessPath(AccessPathTy lhs, AccessPathTy rhs) {
});
}
ModuleDecl::ReverseFullNameIterator::ReverseFullNameIterator(
const ModuleDecl *M) {
assert(M);
// Note: This will look through overlays as well, but that's fine for name
// generation purposes. The point of an overlay is to
if (auto *clangModule = M->findUnderlyingClangModule())
current = clangModule;
else
current = M;
}
StringRef ModuleDecl::ReverseFullNameIterator::operator*() const {
assert(current && "all name components exhausted");
if (auto *swiftModule = current.dyn_cast<const ModuleDecl *>())
return swiftModule->getName().str();
auto *clangModule =
static_cast<const clang::Module *>(current.get<const void *>());
return clangModule->Name;
}
ModuleDecl::ReverseFullNameIterator &
ModuleDecl::ReverseFullNameIterator::operator++() {
if (!current)
return *this;
if (auto *swiftModule = current.dyn_cast<const ModuleDecl *>()) {
current = nullptr;
return *this;
}
auto *clangModule =
static_cast<const clang::Module *>(current.get<const void *>());
if (clangModule->Parent)
current = clangModule->Parent;
else
current = nullptr;
return *this;
}
void
ModuleDecl::ReverseFullNameIterator::printForward(raw_ostream &out) const {
SmallVector<StringRef, 8> elements(*this, {});
swift::interleave(swift::reversed(elements),
[&out](StringRef next) { out << next; },
[&out] { out << '.'; });
}
void
ModuleDecl::removeDuplicateImports(SmallVectorImpl<ImportedModule> &imports) {
std::sort(imports.begin(), imports.end(),