diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-11-19 09:00:00 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-11-19 09:00:00 +0000 |
commit | 6df2408694f81a03eb8b0e3b013272042233c061 (patch) | |
tree | c7f5a7b6fd212399d821b83b22c1e6a42e8c4a0d /lib/Sema/Lookup.h | |
parent | 741c13ecc20fb35b836ad690aeecd402f002d654 (diff) | |
download | FreeBSD-src-6df2408694f81a03eb8b0e3b013272042233c061.zip FreeBSD-src-6df2408694f81a03eb8b0e3b013272042233c061.tar.gz |
Update clang to r89337.
Diffstat (limited to 'lib/Sema/Lookup.h')
-rw-r--r-- | lib/Sema/Lookup.h | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h index 6e72dce..10cc818 100644 --- a/lib/Sema/Lookup.h +++ b/lib/Sema/Lookup.h @@ -201,6 +201,13 @@ public: return getResultKind() == Ambiguous; } + /// Determines if this names a single result which is not an + /// unresolved value using decl. If so, it is safe to call + /// getFoundDecl(). + bool isSingleResult() const { + return getResultKind() == Found; + } + LookupResultKind getResultKind() const { sanity(); return ResultKind; @@ -248,12 +255,24 @@ public: Decls.set_size(N); } - /// \brief Resolves the kind of the lookup, possibly hiding decls. + /// \brief Resolves the result kind of the lookup, possibly hiding + /// decls. /// /// This should be called in any environment where lookup might /// generate multiple lookup results. void resolveKind(); + /// \brief Re-resolves the result kind of the lookup after a set of + /// removals has been performed. + void resolveKindAfterFilter() { + if (Decls.empty()) + ResultKind = NotFound; + else { + ResultKind = Found; + resolveKind(); + } + } + /// \brief Fetch this as an unambiguous single declaration /// (possibly an overloaded one). /// @@ -272,6 +291,12 @@ public: return Decls[0]->getUnderlyingDecl(); } + /// Fetches a representative decl. Useful for lazy diagnostics. + NamedDecl *getRepresentativeDecl() const { + assert(!Decls.empty() && "cannot get representative of empty set"); + return Decls[0]; + } + /// \brief Asks if the result is a single tag decl. bool isSingleTagDecl() const { return getResultKind() == Found && isa<TagDecl>(getFoundDecl()); @@ -337,6 +362,65 @@ public: return NameLoc; } + /// A class for iterating through a result set and possibly + /// filtering out results. The results returned are possibly + /// sugared. + class Filter { + LookupResult &Results; + unsigned I; + bool ErasedAny; +#ifndef NDEBUG + bool CalledDone; +#endif + + friend class LookupResult; + Filter(LookupResult &Results) + : Results(Results), I(0), ErasedAny(false) +#ifndef NDEBUG + , CalledDone(false) +#endif + {} + + public: +#ifndef NDEBUG + ~Filter() { + assert(CalledDone && + "LookupResult::Filter destroyed without done() call"); + } +#endif + + bool hasNext() const { + return I != Results.Decls.size(); + } + + NamedDecl *next() { + assert(I < Results.Decls.size() && "next() called on empty filter"); + return Results.Decls[I++]; + } + + /// Erase the last element returned from this iterator. + void erase() { + Results.Decls[--I] = Results.Decls.back(); + Results.Decls.pop_back(); + ErasedAny = true; + } + + void done() { +#ifndef NDEBUG + assert(!CalledDone && "done() called twice"); + CalledDone = true; +#endif + + if (ErasedAny) + Results.resolveKindAfterFilter(); + } + }; + + /// Create a filter for this result set. + Filter makeFilter() { + return Filter(*this); + } + private: void diagnose() { if (isAmbiguous()) |