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

@@ -151,6 +151,45 @@ public:
}
};
/// Produces the components of a given module's full name in reverse order.
///
/// For a Swift module, this will only ever have one component, but an
/// imported Clang module might actually be a submodule.
class ReverseFullNameIterator {
public:
// Make this look like a valid STL iterator.
using difference_type = int;
using value_type = StringRef;
using pointer = StringRef *;
using reference = StringRef;
using iterator_category = std::forward_iterator_tag;
private:
PointerUnion<const ModuleDecl *, const /* clang::Module */ void *> current;
public:
ReverseFullNameIterator() = default;
explicit ReverseFullNameIterator(const ModuleDecl *M);
explicit ReverseFullNameIterator(const clang::Module *clangModule) {
current = clangModule;
}
StringRef operator*() const;
ReverseFullNameIterator &operator++();
friend bool operator==(ReverseFullNameIterator left,
ReverseFullNameIterator right) {
return left.current == right.current;
}
friend bool operator!=(ReverseFullNameIterator left,
ReverseFullNameIterator right) {
return !(left == right);
}
/// This is a convenience function that writes the entire name, in forward
/// order, to \p out.
void printForward(raw_ostream &out) const;
};
private:
/// If non-NULL, a plug-in that should be used when performing external
/// lookups.
@@ -490,6 +529,15 @@ public:
/// Returns the associated clang module if one exists.
const clang::Module *findUnderlyingClangModule() const;
/// Returns a generator with the components of this module's full,
/// hierarchical name.
///
/// For a Swift module, this will only ever have one component, but an
/// imported Clang module might actually be a submodule.
ReverseFullNameIterator getReverseFullModuleName() const {
return ReverseFullNameIterator(this);
}
SourceRange getSourceRange() const { return SourceRange(); }
static bool classof(const DeclContext *DC) {