aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ASTContext.h5
-rw-r--r--include/clang/AST/Decl.h26
-rw-r--r--include/clang/AST/DeclCXX.h13
-rw-r--r--include/clang/AST/ExprCXX.h14
-rw-r--r--include/clang/AST/UnresolvedSet.h360
-rw-r--r--lib/AST/ASTContext.cpp6
-rw-r--r--lib/AST/DeclCXX.cpp12
-rw-r--r--lib/AST/ExprCXX.cpp9
-rw-r--r--lib/Sema/Lookup.h62
-rw-r--r--lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--lib/Sema/SemaExprCXX.cpp4
-rw-r--r--lib/Sema/SemaInit.cpp11
-rw-r--r--lib/Sema/SemaLookup.cpp18
-rw-r--r--lib/Sema/SemaOverload.cpp16
-rw-r--r--lib/Sema/SemaStmt.cpp4
15 files changed, 449 insertions, 115 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 2d151ff83a..e5429bec14 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -61,6 +61,7 @@ namespace clang {
class TypedefDecl;
class UsingDecl;
class UsingShadowDecl;
+ class UnresolvedSetIterator;
namespace Builtin { class Context; }
@@ -753,8 +754,8 @@ public:
DeclarationName getNameForTemplate(TemplateName Name);
- TemplateName getOverloadedTemplateName(NamedDecl * const *Begin,
- NamedDecl * const *End);
+ TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End);
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 21b5909913..6d52b2b2bc 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -55,32 +55,6 @@ public:
TypeLoc getTypeLoc() const;
};
-/// UnresolvedSet - A set of unresolved declarations. This is needed
-/// in a lot of places, but isn't really worth breaking into its own
-/// header right now.
-class UnresolvedSet {
- typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
- DeclsTy Decls;
-
-public:
- void addDecl(NamedDecl *D) {
- Decls.push_back(D);
- }
-
- bool replace(const NamedDecl* Old, NamedDecl *New) {
- for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
- if (*I == Old)
- return (*I = New, true);
- return false;
- }
-
- unsigned size() const { return Decls.size(); }
-
- typedef DeclsTy::const_iterator iterator;
- iterator begin() const { return Decls.begin(); }
- iterator end() const { return Decls.end(); }
-};
-
/// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 336a895de8..6588886ac9 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -16,6 +16,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/UnresolvedSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -275,13 +276,13 @@ class CXXRecordDecl : public RecordDecl {
/// of this C++ class (but not its inherited conversion
/// functions). Each of the entries in this overload set is a
/// CXXConversionDecl.
- UnresolvedSet Conversions;
+ UnresolvedSet<4> Conversions;
/// VisibleConversions - Overload set containing the conversion functions
/// of this C++ class and all those inherited conversion functions that
/// are visible in this class. Each of the entries in this overload set is
/// a CXXConversionDecl or a FunctionTemplateDecl.
- UnresolvedSet VisibleConversions;
+ UnresolvedSet<4> VisibleConversions;
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
@@ -483,20 +484,20 @@ public:
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
- UnresolvedSet *getConversionFunctions() {
+ UnresolvedSetImpl *getConversionFunctions() {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
}
- const UnresolvedSet *getConversionFunctions() const {
+ const UnresolvedSetImpl *getConversionFunctions() const {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
}
- typedef UnresolvedSet::iterator conversion_iterator;
+ typedef UnresolvedSetImpl::iterator conversion_iterator;
conversion_iterator conversion_begin() const { return Conversions.begin(); }
conversion_iterator conversion_end() const { return Conversions.end(); }
@@ -509,7 +510,7 @@ public:
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
- const UnresolvedSet *getVisibleConversionFunctions();
+ const UnresolvedSetImpl *getVisibleConversionFunctions();
/// addVisibleConversionFunction - Add a new conversion function to the
/// list of visible conversion functions.
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index ab22ba30b1..6ce95ac522 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -16,7 +16,7 @@
#include "clang/Basic/TypeTraits.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/Decl.h"
+#include "clang/AST/UnresolvedSet.h"
#include "clang/AST/TemplateBase.h"
namespace clang {
@@ -1072,7 +1072,7 @@ public:
class UnresolvedLookupExpr : public Expr {
/// The results. These are undesugared, which is to say, they may
/// include UsingShadowDecls.
- UnresolvedSet Results;
+ UnresolvedSet<4> Results;
/// The name declared.
DeclarationName Name;
@@ -1133,15 +1133,15 @@ public:
/// Computes whether an unresolved lookup on the given declarations
/// and optional template arguments is type- and value-dependent.
- static bool ComputeDependence(NamedDecl * const *Begin,
- NamedDecl * const *End,
+ static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
+ UnresolvedSetImpl::const_iterator End,
const TemplateArgumentListInfo *Args);
void addDecl(NamedDecl *Decl) {
Results.addDecl(Decl);
}
- typedef UnresolvedSet::iterator decls_iterator;
+ typedef UnresolvedSetImpl::iterator decls_iterator;
decls_iterator decls_begin() const { return Results.begin(); }
decls_iterator decls_end() const { return Results.end(); }
@@ -1716,7 +1716,7 @@ public:
class UnresolvedMemberExpr : public Expr {
/// The results. These are undesugared, which is to say, they may
/// include UsingShadowDecls.
- UnresolvedSet Results;
+ UnresolvedSet<4> Results;
/// \brief The expression for the base pointer or class reference,
/// e.g., the \c x in x.f. This can be null if this is an 'unbased'
@@ -1795,7 +1795,7 @@ public:
Results.addDecl(Decl);
}
- typedef UnresolvedSet::iterator decls_iterator;
+ typedef UnresolvedSetImpl::iterator decls_iterator;
decls_iterator decls_begin() const { return Results.begin(); }
decls_iterator decls_end() const { return Results.end(); }
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
new file mode 100644
index 0000000000..e33eecdd01
--- /dev/null
+++ b/include/clang/AST/UnresolvedSet.h
@@ -0,0 +1,360 @@
+//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the UnresolvedSet class, which is used to store
+// collections of declarations in the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
+#define LLVM_CLANG_AST_UNRESOLVEDSET_H
+
+#include <iterator>
+#include <llvm/ADT/PointerIntPair.h>
+
+namespace clang {
+
+class NamedDecl;
+
+/// The iterator over UnresolvedSets. Serves as both the const and
+/// non-const iterator.
+class UnresolvedSetIterator {
+
+ typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry;
+ typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy;
+ typedef DeclsTy::iterator IteratorTy;
+
+ IteratorTy ir;
+
+ friend class UnresolvedSetImpl;
+ explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
+ explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
+ ir(const_cast<DeclsTy::iterator>(ir)) {}
+public:
+ UnresolvedSetIterator() {}
+
+ typedef std::iterator_traits<IteratorTy>::difference_type difference_type;
+ typedef NamedDecl *value_type;
+ typedef NamedDecl **pointer;
+ typedef NamedDecl *reference;
+ typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
+
+ NamedDecl *getDecl() const { return ir->getPointer(); }
+ AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); }
+
+ NamedDecl *operator*() const { return getDecl(); }
+
+ UnresolvedSetIterator &operator++() { ++ir; return *this; }
+ UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); }
+ UnresolvedSetIterator &operator--() { --ir; return *this; }
+ UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); }
+
+ UnresolvedSetIterator &operator+=(difference_type d) {
+ ir += d; return *this;
+ }
+ UnresolvedSetIterator operator+(difference_type d) const {
+ return UnresolvedSetIterator(ir + d);
+ }
+ UnresolvedSetIterator &operator-=(difference_type d) {
+ ir -= d; return *this;
+ }
+ UnresolvedSetIterator operator-(difference_type d) const {
+ return UnresolvedSetIterator(ir - d);
+ }
+ value_type operator[](difference_type d) const { return *(*this + d); }
+
+ difference_type operator-(const UnresolvedSetIterator &o) const {
+ return ir - o.ir;
+ }
+
+ bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; }
+ bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; }
+ bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; }
+ bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; }
+ bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; }
+ bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
+};
+
+/// UnresolvedSet - A set of unresolved declarations. This is needed
+/// in a lot of places, but isn't really worth breaking into its own
+/// header right now.
+class UnresolvedSetImpl {
+ typedef UnresolvedSetIterator::DeclEntry DeclEntry;
+ typedef UnresolvedSetIterator::DeclsTy DeclsTy;
+
+ // Don't allow direct construction, and only permit subclassing by
+ // UnresolvedSet.
+private:
+ template <unsigned N> friend class UnresolvedSet;
+ UnresolvedSetImpl() {}
+ UnresolvedSetImpl(const UnresolvedSetImpl &) {}
+
+public:
+ // We don't currently support assignment through this iterator, so we might
+ // as well use the same implementation twice.
+ typedef UnresolvedSetIterator iterator;
+ typedef UnresolvedSetIterator const_iterator;
+
+ iterator begin() { return iterator(decls().begin()); }
+ iterator end() { return iterator(decls().end()); }
+
+ const_iterator begin() const { return const_iterator(decls().begin()); }
+ const_iterator end() const { return const_iterator(decls().end()); }
+
+ void addDecl(NamedDecl *D) {
+ addDecl(D, AS_none);
+ }
+
+ void addDecl(NamedDecl *D, AccessSpecifier AS) {
+ decls().push_back(DeclEntry(D, AS));
+ }
+
+ /// Replaces the given declaration with the new one, once.
+ ///
+ /// \return true if the set changed
+ bool replace(const NamedDecl* Old, NamedDecl *New) {
+ for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
+ if (I->getPointer() == Old)
+ return (I->setPointer(New), true);
+ return false;
+ }
+
+ /// Replaces the declaration at the given iterator with the new one,
+ /// preserving the original access bits.
+ void replace(iterator I, NamedDecl *New) {
+ I.ir->setPointer(New);
+ }
+
+ void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
+ *I.ir = DeclEntry(New, AS);
+ }
+
+ void erase(iterator I) {
+ *I.ir = decls().back();
+ decls().pop_back();
+ }
+
+ void clear() { decls().clear(); }
+ void set_size(unsigned N) { decls().set_size(N); }
+
+ bool empty() const { return decls().empty(); }
+ unsigned size() const { return decls().size(); }
+
+ void append(iterator I, iterator E) {
+ decls().append(I.ir, E.ir);
+ }
+
+ /// A proxy reference for implementing operator[].
+ class Proxy {
+ DeclEntry &Ref;
+
+ friend class UnresolvedSetImpl;
+ Proxy(DeclEntry &Ref) : Ref(Ref) {}
+
+ public:
+ NamedDecl *getDecl() const { return Ref.getPointer(); }
+ void setDecl(NamedDecl *D) { Ref.setPointer(D); }
+
+ AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); }
+ void setAccess(AccessSpecifier AS) const { Ref.setInt(AS); }
+
+ NamedDecl* operator->() const { return getDecl(); }
+ operator NamedDecl*() const { return getDecl(); }
+ Proxy &operator=(const Proxy &D) { Ref = D.Ref; return *this; }
+ };
+ Proxy operator[](unsigned I) { return Proxy(decls()[I]); }
+
+ /// A proxy reference for implementing operator[] const.
+ class ConstProxy {
+ const DeclEntry &Ref;
+
+ friend class UnresolvedSetImpl;
+ ConstProxy(const DeclEntry &Ref) : Ref(Ref) {}
+
+ public:
+ NamedDecl *getDecl() const { return Ref.getPointer(); }
+ AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); }
+
+ NamedDecl *operator->() const { return getDecl(); }
+ operator NamedDecl*() const { return getDecl(); }
+ };
+ ConstProxy operator[](unsigned I) const { return ConstProxy(decls()[I]); }
+
+private:
+ // These work because the only permitted subclass is UnresolvedSetImpl
+
+ DeclsTy &decls() {
+ return *reinterpret_cast<DeclsTy*>(this);
+ }
+ const DeclsTy &decls() const {
+ return *reinterpret_cast<const DeclsTy*>(this);
+ }
+};
+
+/// A set of unresolved declarations
+template <unsigned InlineCapacity> class UnresolvedSet :
+ public UnresolvedSetImpl {
+ llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls;
+};
+
+
+} // namespace clang
+
+#endif
+//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the UnresolvedSet class, which is used to store
+// collections of declarations in the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
+#define LLVM_CLANG_AST_UNRESOLVEDSET_H
+
+#include <iterator>
+#include <llvm/ADT/PointerIntPair.h>
+
+namespace clang {
+
+class NamedDecl;
+
+/// The iterator over UnresolvedSets. Serves as both the const and
+/// non-const iterator.
+class UnresolvedSetIterator {
+
+ typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry;
+ typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy;
+ typedef DeclsTy::const_iterator IteratorTy;
+
+ IteratorTy ir;
+
+ friend class UnresolvedSetImpl;
+ explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
+ explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : ir(ir) {}
+public:
+ UnresolvedSetIterator() {}
+
+ typedef std::iterator_traits<IteratorTy>::difference_type difference_type;
+ typedef NamedDecl *value_type;
+ typedef NamedDecl **pointer;
+ typedef NamedDecl *reference;
+ typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
+
+ NamedDecl *getDecl() const { return ir->getPointer(); }
+ AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); }
+
+ NamedDecl *operator*() const { return getDecl(); }
+
+ UnresolvedSetIterator &operator++() { ++ir; return *this; }
+ UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); }
+ UnresolvedSetIterator &operator--() { --ir; return *this; }
+ UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); }
+
+ UnresolvedSetIterator &operator+=(difference_type d) {
+ ir += d; return *this;
+ }
+ UnresolvedSetIterator operator+(difference_type d) const {
+ return UnresolvedSetIterator(ir + d);
+ }
+ UnresolvedSetIterator &operator-=(difference_type d) {
+ ir -= d; return *this;
+ }
+ UnresolvedSetIterator operator-(difference_type d) const {
+ return UnresolvedSetIterator(ir - d);
+ }
+ value_type operator[](difference_type d) const { return *(*this + d); }
+
+ difference_type operator-(const UnresolvedSetIterator &o) const {
+ return ir - o.ir;
+ }
+
+ bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; }
+ bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; }
+ bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; }
+ bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; }
+ bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; }
+ bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
+};
+
+/// UnresolvedSet - A set of unresolved declarations. This is needed
+/// in a lot of places, but isn't really worth breaking into its own
+/// header right now.
+class UnresolvedSetImpl {
+ typedef UnresolvedSetIterator::DeclEntry DeclEntry;
+ typedef UnresolvedSetIterator::DeclsTy DeclsTy;
+
+ // Don't allow direct construction, and only permit subclassing by
+ // UnresolvedSet.
+private:
+ template <unsigned N> friend class UnresolvedSet;
+ UnresolvedSetImpl() {}
+ UnresolvedSetImpl(const UnresolvedSetImpl &) {}
+
+public:
+ // We don't currently support assignment through this iterator, so we might
+ // as well use the same implementation twice.
+ typedef UnresolvedSetIterator iterator;
+ typedef UnresolvedSetIterator const_iterator;
+
+ iterator begin() { return iterator(decls().begin()); }
+ iterator end() { return iterator(decls().end()); }
+
+ const_iterator begin() const { return const_iterator(decls().begin()); }
+ const_iterator end() const { return const_iterator(decls().end()); }
+
+ void addDecl(NamedDecl *D) {
+ addDecl(D, AS_none);
+ }
+
+ void addDecl(NamedDecl *D, AccessSpecifier AS) {
+ decls().push_back(DeclEntry(D, AS));
+ }
+
+ bool replace(const NamedDecl* Old, NamedDecl *New) {
+ for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
+ if (I->getPointer() == Old)
+ return (I->setPointer(New), true);
+ return false;
+ }
+
+ bool empty() const { return decls().empty(); }
+ unsigned size() const { return decls().size(); }
+
+ void append(iterator I, iterator E) {
+ decls().append(I.ir, E.ir);
+ }
+
+private:
+ // These work because the only permitted subclass is UnresolvedSetImpl
+
+ DeclsTy &decls() {
+ return *reinterpret_cast<DeclsTy*>(this);
+ }
+ const DeclsTy &decls() const {
+ return *reinterpret_cast<const DeclsTy*>(this);
+ }
+};
+
+/// A set of unresolved declarations
+template <unsigned InlineCapacity> class UnresolvedSet :
+ public UnresolvedSetImpl {
+ llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls;
+};
+
+
+} // namespace clang
+
+#endif
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index c6e3e09fa5..f8fc626457 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3759,8 +3759,8 @@ void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
/// \brief Retrieve the template name that corresponds to a non-empty
/// lookup.
-TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin,
- NamedDecl * const *End) {
+TemplateName ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End) {
unsigned size = End - Begin;
assert(size > 1 && "set is not overloaded!");
@@ -3769,7 +3769,7 @@ TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin,
OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size);
NamedDecl **Storage = OT->getStorage();
- for (NamedDecl * const *I = Begin; I != End; ++I) {
+ for (UnresolvedSetIterator I = Begin; I != End; ++I) {
NamedDecl *D = *I;
assert(isa<FunctionTemplateDecl>(D) ||
(isa<UsingShadowDecl>(D) &&
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 1cce35c0b3..fe6064df32 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -312,8 +312,9 @@ void
CXXRecordDecl::collectConversionFunctions(
llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const
{
- const UnresolvedSet *Cs = getConversionFunctions();
- for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
+ const UnresolvedSetImpl *Cs = getConversionFunctions();
+ for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end();
+ I != E; ++I) {
NamedDecl *TopConv = *I;
CanQualType TConvType;
if (FunctionTemplateDecl *TConversionTemplate =
@@ -344,10 +345,11 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
bool inTopClass = (RD == this);
QualType ClassType = getASTContext().getTypeDeclType(this);
if (const RecordType *Record = ClassType->getAs<RecordType>()) {
- const UnresolvedSet *Cs
+ const UnresolvedSetImpl *Cs
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
- for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
+ for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end();
+ I != E; ++I) {
NamedDecl *Conv = *I;
// Only those conversions not exact match of conversions in current
// class are candidateconversion routines.
@@ -410,7 +412,7 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
-const UnresolvedSet *CXXRecordDecl::getVisibleConversionFunctions() {
+const UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() {
// If root class, all conversions are visible.
if (bases_begin() == bases_end())
return &Conversions;
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 81584b7002..a6574efda8 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -135,10 +135,11 @@ UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
return ULE;
}
-bool UnresolvedLookupExpr::ComputeDependence(NamedDecl * const *Begin,
- NamedDecl * const *End,
- const TemplateArgumentListInfo *Args) {
- for (NamedDecl * const *I = Begin; I != End; ++I)
+bool UnresolvedLookupExpr::
+ ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
+ UnresolvedSetImpl::const_iterator End,
+ const TemplateArgumentListInfo *Args) {
+ for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
if ((*I)->getDeclContext()->isDependentContext())
return true;
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
index 9064de6aa0..33d1106559 100644
--- a/lib/Sema/Lookup.h
+++ b/lib/Sema/Lookup.h
@@ -123,9 +123,7 @@ public:
Temporary
};
- typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
- typedef DeclsTy::const_iterator iterator;
-
+ typedef UnresolvedSetImpl::iterator iterator;
typedef bool (*ResultFilter)(NamedDecl*, unsigned IDNS);
LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
@@ -224,8 +222,8 @@ public:
return Ambiguity;
}
- iterator begin() const { return Decls.begin(); }
- iterator end() const { return Decls.end(); }
+ iterator begin() const { return iterator(Decls.begin()); }
+ iterator end() const { return iterator(Decls.end()); }
/// \brief Return true if no decls were found
bool empty() const { return Decls.empty(); }
@@ -247,32 +245,20 @@ public:
return IDNS;
}
- /// \brief Add a declaration to these results. Does not test the
- /// acceptance criteria.
+ /// \brief Add a declaration to these results with no access bits.
+ /// Does not test the acceptance criteria.
void addDecl(NamedDecl *D) {
- Decls.push_back(D);
+ Decls.addDecl(D);
ResultKind = Found;
}
/// \brief Add all the declarations from another set of lookup
/// results.
void addAllDecls(const LookupResult &Other) {
- Decls.append(Other.begin(), Other.end());
+ Decls.append(Other.Decls.begin(), Other.Decls.end());
ResultKind = Found;
}
- /// \brief Hides a set of declarations.
- template <class NamedDeclSet> void hideDecls(const NamedDeclSet &Set) {
- unsigned I = 0, N = Decls.size();
- while (I < N) {
- if (Set.count(Decls[I]))
- Decls[I] = Decls[--N];
- else
- I++;
- }
- Decls.set_size(N);
- }
-
/// \brief Determine whether no result was found because we could not
/// search into dependent base classes of the current instantiation.
bool wasNotFoundInCurrentInstantiation() const {
@@ -319,13 +305,13 @@ public:
NamedDecl *getFoundDecl() const {
assert(getResultKind() == Found
&& "getFoundDecl called on non-unique result");
- return Decls[0]->getUnderlyingDecl();
+ return (*begin())->getUnderlyingDecl();
}
/// Fetches a representative decl. Useful for lazy diagnostics.
NamedDecl *getRepresentativeDecl() const {
assert(!Decls.empty() && "cannot get representative of empty set");
- return Decls[0];
+ return *begin();
}
/// \brief Asks if the result is a single tag decl.
@@ -403,7 +389,7 @@ public:
/// sugared.
class Filter {
LookupResult &Results;
- unsigned I;
+ LookupResult::iterator I;
bool Changed;
#ifndef NDEBUG
bool CalledDone;
@@ -411,7 +397,7 @@ public:
friend class LookupResult;
Filter(LookupResult &Results)
- : Results(Results), I(0), Changed(false)
+ : Results(Results), I(Results.begin()), Changed(false)
#ifndef NDEBUG
, CalledDone(false)
#endif
@@ -426,23 +412,30 @@ public:
#endif
bool hasNext() const {
- return I != Results.Decls.size();
+ return I != Results.end();
}
NamedDecl *next() {
- assert(I < Results.Decls.size() && "next() called on empty filter");
- return Results.Decls[I++];
+ assert(I != Results.end() && "next() called on empty filter");
+ return *I++;
}
/// Erase the last element returned from this iterator.
void erase() {
- Results.Decls[--I] = Results.Decls.back();
- Results.Decls.pop_back();
+ Results.Decls.erase(--I);
Changed = true;
}
+ /// Replaces the current entry with the given one, preserving the
+ /// access bits.
void replace(NamedDecl *D) {
- Results.Decls[I-1] = D;
+ Results.Decls.replace(I-1, D);
+ Changed = true;
+ }
+
+ /// Replaces the current entry with the given one.
+ void replace(NamedDecl *D, AccessSpecifier AS) {
+ Results.Decls.replace(I-1, D, AS);
Changed = true;
}
@@ -482,7 +475,7 @@ private:
assert(ResultKind != Found || Decls.size() == 1);
assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
(Decls.size() == 1 &&
- isa<FunctionTemplateDecl>(Decls[0]->getUnderlyingDecl())));
+ isa<FunctionTemplateDecl>((*begin())->getUnderlyingDecl())));
assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
assert(ResultKind != Ambiguous || Decls.size() > 1 ||
(Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
@@ -492,8 +485,7 @@ private:
}
bool sanityCheckUnresolved() const {
- for (DeclsTy::const_iterator I = Decls.begin(), E = Decls.end();
- I != E; ++I)
+ for (iterator I = begin(), E = end(); I != E; ++I)
if (isa<UnresolvedUsingValueDecl>(*I))
return true;
return false;
@@ -504,7 +496,7 @@ private:
// Results.
LookupResultKind ResultKind;
AmbiguityKind Ambiguity; // ill-defined unless ambiguous
- DeclsTy Decls;
+ UnresolvedSet<8> Decls;
CXXBasePaths *Paths;
// Parameters.
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 669629468d..12b4565cb5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4487,9 +4487,9 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
OverloadCandidateSet CandidateSet;
- const UnresolvedSet *Conversions
+ const UnresolvedSetImpl *Conversions
= T2RecordDecl->getVisibleConversionFunctions();
- for (UnresolvedSet::iterator I = Conversions->begin(),
+ for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
NamedDecl *D = *I;
CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e4812682a0..b004fc3dba 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -893,9 +893,9 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
if (const RecordType *Record = Type->getAs<RecordType>()) {
llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
- const UnresolvedSet *Conversions = RD->getVisibleConversionFunctions();
+ const UnresolvedSetImpl *Conversions = RD->getVisibleConversionFunctions();
- for (UnresolvedSet::iterator I = Conversions->begin(),
+ for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
// Skip over templated conversion functions; they aren't considered.
if (isa<FunctionTemplateDecl>(*I))
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 1970f56e28..29209d97ff 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2141,11 +2141,10 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
// refers to.
QualType ToType = AllowRValues? cv1T1 : DestType;
- const UnresolvedSet *Conversions
+ const UnresolvedSetImpl *Conversions
= T2RecordDecl->getVisibleConversionFunctions();
- for (UnresolvedSet::iterator I = Conversions->begin(),
- E = Conversions->end();
- I != E; ++I) {
+ for (UnresolvedSetImpl::const_iterator I = Conversions->begin(),
+ E = Conversions->end(); I != E; ++I) {
NamedDecl *D = *I;
CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
if (isa<UsingShadowDecl>(D))
@@ -2662,9 +2661,9 @@ static void TryUserDefinedConversion(Sema &S,
CXXRecordDecl *SourceRecordDecl
= cast<CXXRecordDecl>(SourceRecordType->getDecl());
- const UnresolvedSet *Conversions
+ const UnresolvedSetImpl *Conversions
= SourceRecordDecl->getVisibleConversionFunctions();
- for (UnresolvedSet::iterator I = Conversions->begin(),
+ for (UnresolvedSetImpl::const_iterator I = Conversions->begin(),
E = Conversions->end();
I != E; ++I) {
NamedDecl *D = *I;
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 70baefdae7..da7626780c 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -324,9 +324,9 @@ void LookupResult::resolveKind() {
// If there's a single decl, we need to examine it to decide what
// kind of lookup this is.
if (N == 1) {
- if (isa<FunctionTemplateDecl>(Decls[0]))
+ if (isa<FunctionTemplateDecl>(*Decls.begin()))
ResultKind = FoundOverloaded;
- else if (isa<UnresolvedUsingValueDecl>(Decls[0]))
+ else if (isa<UnresolvedUsingValueDecl>(*Decls.begin()))
ResultKind = FoundUnresolvedValue;
return;
}
@@ -463,10 +463,9 @@ static bool LookupDirect(LookupResult &R, const DeclContext *DC) {
if (!Record->isDefinition())
return Found;
- const UnresolvedSet *Unresolved = Record->getConversionFunctions();
- for (UnresolvedSet::iterator U = Unresolved->begin(),
- UEnd = Unresolved->end();
- U != UEnd; ++U) {
+ const UnresolvedSetImpl *Unresolved = Record->getConversionFunctions();
+ for (UnresolvedSetImpl::iterator U = Unresolved->begin(),
+ UEnd = Unresolved->end(); U != UEnd; ++U) {
FunctionTemplateD