std::string CurNameSpecifier;
SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
- bool isSorted;
- SpecifierInfoList Specifiers;
- llvm::SmallSetVector<unsigned, 4> Distances;
- llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap;
+ std::map<unsigned, SpecifierInfoList> DistanceMap;
/// \brief Helper for building the list of DeclContexts between the current
/// context and the top of the translation unit
static DeclContextList buildContextChain(DeclContext *Start);
- void sortNamespaces();
-
unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
NestedNameSpecifier *&NNS);
/// the corresponding NestedNameSpecifier and its distance in the process.
void addNameSpecifier(DeclContext *Ctx);
- typedef SpecifierInfoList::iterator iterator;
- iterator begin() {
- if (!isSorted) sortNamespaces();
- return Specifiers.begin();
- }
- iterator end() { return Specifiers.end(); }
+ /// \brief Provides flat iteration over specifiers, sorted by distance.
+ class iterator
+ : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
+ SpecifierInfo> {
+ /// Always points to the last element in the distance map.
+ const std::map<unsigned, SpecifierInfoList>::iterator OuterBack;
+ /// Iterator on the distance map.
+ std::map<unsigned, SpecifierInfoList>::iterator Outer;
+ /// Iterator on an element in the distance map.
+ SpecifierInfoList::iterator Inner;
+
+ public:
+ iterator(NamespaceSpecifierSet &Set, bool IsAtEnd)
+ : OuterBack(std::prev(Set.DistanceMap.end())),
+ Outer(Set.DistanceMap.begin()),
+ Inner(!IsAtEnd ? Outer->second.begin() : OuterBack->second.end()) {
+ assert(!Set.DistanceMap.empty());
+ }
+
+ iterator &operator++() {
+ ++Inner;
+ if (Inner == Outer->second.end() && Outer != OuterBack) {
+ ++Outer;
+ Inner = Outer->second.begin();
+ }
+ return *this;
+ }
+
+ SpecifierInfo &operator*() { return *Inner; }
+ bool operator==(const iterator &RHS) const { return Inner == RHS.Inner; }
+ };
+
+ iterator begin() { return iterator(*this, /*IsAtEnd=*/false); }
+ iterator end() { return iterator(*this, /*IsAtEnd=*/true); }
};
void addName(StringRef Name, NamedDecl *ND,
TypoCorrectionConsumer::NamespaceSpecifierSet::NamespaceSpecifierSet(
ASTContext &Context, DeclContext *CurContext, CXXScopeSpec *CurScopeSpec)
- : Context(Context), CurContextChain(buildContextChain(CurContext)),
- isSorted(false) {
+ : Context(Context), CurContextChain(buildContextChain(CurContext)) {
if (NestedNameSpecifier *NNS =
CurScopeSpec ? CurScopeSpec->getScopeRep() : nullptr) {
llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
}
// Add the global context as a NestedNameSpecifier
- Distances.insert(1);
SpecifierInfo SI = {cast<DeclContext>(Context.getTranslationUnitDecl()),
NestedNameSpecifier::GlobalSpecifier(Context), 1};
DistanceMap[1].push_back(SI);
return Chain;
}
-void TypoCorrectionConsumer::NamespaceSpecifierSet::sortNamespaces() {
- SmallVector<unsigned, 4> sortedDistances;
- sortedDistances.append(Distances.begin(), Distances.end());
-
- if (sortedDistances.size() > 1)
- std::sort(sortedDistances.begin(), sortedDistances.end());
-
- Specifiers.clear();
- for (auto D : sortedDistances) {
- SpecifierInfoList &SpecList = DistanceMap[D];
- Specifiers.append(SpecList.begin(), SpecList.end());
- }
-
- isSorted = true;
-}
-
unsigned
TypoCorrectionConsumer::NamespaceSpecifierSet::buildNestedNameSpecifier(
DeclContextList &DeclChain, NestedNameSpecifier *&NNS) {
llvm::makeArrayRef(NewNameSpecifierIdentifiers));
}
- isSorted = false;
- Distances.insert(NumSpecifiers);
SpecifierInfo SI = {Ctx, NNS, NumSpecifiers};
DistanceMap[NumSpecifiers].push_back(SI);
}