diff options
-rw-r--r-- | include/clang/AST/ASTContext.h | 5 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 26 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 13 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 14 | ||||
-rw-r--r-- | include/clang/AST/UnresolvedSet.h | 360 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 6 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 12 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/Lookup.h | 62 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 4 |
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 |