]> granicus.if.org Git - clang/commitdiff
Give UnresolvedSet the ability to store access specifiers for each declaration.
authorJohn McCall <rjmccall@apple.com>
Wed, 20 Jan 2010 00:46:10 +0000 (00:46 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 20 Jan 2010 00:46:10 +0000 (00:46 +0000)
Change LookupResult to use UnresolvedSet.  Also extract UnresolvedSet into its
own header and make it templated over an inline capacity.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93959 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
include/clang/AST/ASTContext.h
include/clang/AST/Decl.h
include/clang/AST/DeclCXX.h
include/clang/AST/ExprCXX.h
include/clang/AST/UnresolvedSet.h [new file with mode: 0644]
lib/AST/ASTContext.cpp
lib/AST/DeclCXX.cpp
lib/AST/ExprCXX.cpp
lib/Sema/Lookup.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaInit.cpp
lib/Sema/SemaLookup.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaStmt.cpp

index 2d151ff83a502047366d2fb6034ce6c9df5b6a71..e5429bec143c40405f251bc9554ff784260fc76e 100644 (file)
@@ -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,
index 21b59099138a8874a30b19078ed1596f1a6bb8fb..6d52b2b2bc9172b54d877f581c12c6c53cbb4611 100644 (file)
@@ -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;
index 336a895de8cfb0737f3a0bb418d85b5e1b2bb2d3..6588886ac900312645e9cb05da85356475e2dc11 100644 (file)
@@ -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.
index ab22ba30b139981dc3078967ea83a83fc5acd447..6ce95ac5227f4e83ab70fd76a9e70b3f0ea5b1e8 100644 (file)
@@ -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 (file)
index 0000000..e33eecd
--- /dev/null
@@ -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
index c6e3e09fa5a882558d54086eb71624b0581e2064..f8fc626457a446aa5e8eb6861ddaf4469c2b3b31 100644 (file)
@@ -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) &&
index 1cce35c0b39a4c8baf3f19d8850c4b9d4316846a..fe6064df325a5190fedcb50e65c2b2ff62861455 100644 (file)
@@ -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;
index 81584b700270bd06015314c4c3ea2a300afd78d5..a6574efda8ee45230545f5a8ec29cbc513405beb 100644 (file)
@@ -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;
 
index 9064de6aa019e320fa814862c938050797efd7b3..33d11065598865e6e352adc946f0aa3b5d27efac 100644 (file)
@@ -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.
index 669629468de8f00c133e54be11782dec2c7179df..12b4565cb55b29cb38e7292695a43c2330d1f65b 100644 (file)
@@ -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());
index e4812682a08686e467d05b671221abda3bd2b661..b004fc3dba7208dc801448eb5025563ceb275839 100644 (file)
@@ -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))
index 1970f56e284b0221e5552314ed38d5a32833ddaa..29209d97ff782c1f2832f197ea921f8ed766b6ed 100644 (file)
@@ -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;
index 70baefdae77a1d15d94b7e07521dac6af0bb70e1..da7626780caafeefc64f29bcaacff1d5c8582e6d 100644 (file)
@@ -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) {
       FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(*U);
       if (!ConvTemplate)
         continue;
@@ -1243,7 +1242,12 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result) {
         Diag((*DI)->getLocation(), diag::note_hiding_object);
 
     // For recovery purposes, go ahead and implement the hiding.
-    Result.hideDecls(TagDecls);
+    LookupResult::Filter F = Result.makeFilter();
+    while (F.hasNext()) {
+      if (TagDecls.count(F.next()))
+        F.erase();
+    }
+    F.done();
 
     return true;
   }
index d710d96586bd5ecb807e47efc758940c8612cbd9..3b6cf89306be9de0010d01e3615007b6e29b1f81 100644 (file)
@@ -1533,9 +1533,9 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
     if (CXXRecordDecl *FromRecordDecl
          = dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
       // Add all of the conversion functions as candidates.
-      const UnresolvedSet *Conversions
+      const UnresolvedSetImpl *Conversions
         = FromRecordDecl->getVisibleConversionFunctions();
-      for (UnresolvedSet::iterator I = Conversions->begin(),
+      for (UnresolvedSetImpl::iterator I = Conversions->begin(),
              E = Conversions->end(); I != E; ++I) {
         NamedDecl *D = *I;
         CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
@@ -3280,9 +3280,9 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
       }
 
       CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
-      const UnresolvedSet *Conversions
+      const UnresolvedSetImpl *Conversions
         = ClassDecl->getVisibleConversionFunctions();
-      for (UnresolvedSet::iterator I = Conversions->begin(),
+      for (UnresolvedSetImpl::iterator I = Conversions->begin(),
              E = Conversions->end(); I != E; ++I) {
 
         // Skip conversion function templates; they don't tell us anything
@@ -3344,10 +3344,10 @@ static  Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
     }
     
     CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
-    const UnresolvedSet *Conversions =
+    const UnresolvedSetImpl *Conversions =
       ClassDecl->getVisibleConversionFunctions();
     
-    for (UnresolvedSet::iterator I = Conversions->begin(),
+    for (UnresolvedSetImpl::iterator I = Conversions->begin(),
            E = Conversions->end(); I != E; ++I) {
       if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*I)) {
         QualType CanTy = Context.getCanonicalType(Conv->getConversionType());
@@ -5938,9 +5938,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
   //   functions for each conversion function declared in an
   //   accessible base class provided the function is not hidden
   //   within T by another intervening declaration.
-  const UnresolvedSet *Conversions
+  const UnresolvedSetImpl *Conversions
     = cast<CXXRecordDecl>(Record->getDecl())->getVisibleConversionFunctions();
-  for (UnresolvedSet::iterator I = Conversions->begin(),
+  for (UnresolvedSetImpl::iterator I = Conversions->begin(),
          E = Conversions->end(); I != E; ++I) {
     NamedDecl *D = *I;
     CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
index f0bbdfe7624ecfe138e84e17722a02a9de07a8e0..0c207fa6e87dae7482648cca731b3facc98e5341 100644 (file)
@@ -412,10 +412,10 @@ static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
   llvm::SmallVector<CXXConversionDecl *, 4> ViableConversions;
   llvm::SmallVector<CXXConversionDecl *, 4> ExplicitConversions;
   if (const RecordType *RecordTy = CondType->getAs<RecordType>()) {
-    const UnresolvedSet *Conversions
+    const UnresolvedSetImpl *Conversions
       = cast<CXXRecordDecl>(RecordTy->getDecl())
                                              ->getVisibleConversionFunctions();
-    for (UnresolvedSet::iterator I = Conversions->begin(),
+    for (UnresolvedSetImpl::iterator I = Conversions->begin(),
            E = Conversions->end(); I != E; ++I) {
       if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(*I))
         if (Conversion->getConversionType().getNonReferenceType()