Index: clang/include/clang/AST/DeclBase.h =================================================================== --- clang/include/clang/AST/DeclBase.h +++ clang/include/clang/AST/DeclBase.h @@ -1225,34 +1225,38 @@ /// single result (with no stable storage) or a collection of results (with /// stable storage provided by the lookup table). class DeclContextLookupResult { - using ResultTy = ArrayRef; + using ResultTy = std::list; - ResultTy Result; + llvm::iterator_range Result; // If there is only one lookup result, it would be invalidated by // reallocations of the name table, so store it separately. NamedDecl *Single = nullptr; - static NamedDecl *const SingleElementDummyList; + static ResultTy const SingleElementDummyList; public: - DeclContextLookupResult() = default; - DeclContextLookupResult(ArrayRef Result) - : Result(Result) {} + DeclContextLookupResult() + : Result(llvm::make_range(SingleElementDummyList.end(), + SingleElementDummyList.end())) {} + DeclContextLookupResult(const ResultTy &Result) + : Result(llvm::make_range(Result.begin(), Result.end())) {} + DeclContextLookupResult(NamedDecl *Single) - : Result(SingleElementDummyList), Single(Single) {} + : Result(llvm::make_range(SingleElementDummyList.begin(), + SingleElementDummyList.end())), Single(Single) {} class iterator; using IteratorBase = - llvm::iterator_adaptor_base; + llvm::iterator_adaptor_base; class iterator : public IteratorBase { value_type SingleElement; public: - explicit iterator(pointer Pos, value_type Single = nullptr) + explicit iterator(ResultTy::const_iterator Pos, value_type Single = nullptr) : IteratorBase(Pos), SingleElement(Single) {} reference operator*() const { @@ -1268,15 +1272,21 @@ iterator end() const { return iterator(Result.end(), Single); } bool empty() const { return Result.empty(); } - pointer data() const { return Single ? &Single : Result.data(); } - size_t size() const { return Single ? 1 : Result.size(); } - reference front() const { return Single ? Single : Result.front(); } - reference back() const { return Single ? Single : Result.back(); } - reference operator[](size_t N) const { return Single ? Single : Result[N]; } + size_t size() const { + if (empty()) + return 0; + return Single ? 1 : std::distance(begin(), end()); + }; + reference front() const { return Single ? Single : *Result.begin(); } + reference back() const { return Single ? Single : *(--Result.end()); } // FIXME: Remove this from the interface DeclContextLookupResult slice(size_t N) const { - DeclContextLookupResult Sliced = Result.slice(N); + assert(size() >= N); + DeclContextLookupResult Sliced; + auto I = Result.begin(); + std::advance(I, N); + Sliced.Result = llvm::make_range(I, Result.end()); Sliced.Single = Single; return Sliced; } Index: clang/include/clang/AST/DeclContextInternals.h =================================================================== --- clang/include/clang/AST/DeclContextInternals.h +++ clang/include/clang/AST/DeclContextInternals.h @@ -21,9 +21,9 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/SmallVector.h" #include #include +#include namespace clang { @@ -33,7 +33,7 @@ /// one entry. struct StoredDeclsList { /// When in vector form, this is what the Data pointer points to. - using DeclsTy = SmallVector; + using DeclsTy = std::list; /// A collection of declarations, with a flag to indicate if we have /// further external declarations. @@ -215,13 +215,7 @@ // declarations (which are always in IDNS_Using | IDNS_Ordinary) // follow that so that the using declarations will be contiguous. else if (D->getIdentifierNamespace() & Decl::IDNS_Using) { - DeclsTy::iterator I = Vec.begin(); - if (D->getIdentifierNamespace() != Decl::IDNS_Using) { - while (I != Vec.end() && - (*I)->getIdentifierNamespace() == Decl::IDNS_Using) - ++I; - } - Vec.insert(I, D); + Vec.push_back(D); // All other declarations go at the end of the list, but before any // tag declarations. But we can be clever about tag declarations Index: clang/lib/ARCMigrate/ObjCMT.cpp =================================================================== --- clang/lib/ARCMigrate/ObjCMT.cpp +++ clang/lib/ARCMigrate/ObjCMT.cpp @@ -622,7 +622,7 @@ Property->getQueryKind())) return false; } - else if (ObjCPropertyDecl *ClassProperty = dyn_cast(R[0])) { + else if (auto *ClassProperty = dyn_cast(R.front())) { if ((ClassProperty->getPropertyAttributes() != Property->getPropertyAttributes()) || !Ctx.hasSameType(ClassProperty->getType(), Property->getType())) @@ -650,7 +650,7 @@ bool match = false; HasAtleastOneRequiredMethod = true; for (unsigned I = 0, N = R.size(); I != N; ++I) - if (ObjCMethodDecl *ImpMD = dyn_cast(R[0])) + if (ObjCMethodDecl *ImpMD = dyn_cast(R.front())) if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) { match = true; break; Index: clang/lib/AST/DeclBase.cpp =================================================================== --- clang/lib/AST/DeclBase.cpp +++ clang/lib/AST/DeclBase.cpp @@ -37,6 +37,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" @@ -1545,7 +1546,8 @@ assert(Pos != Map->end() && "no lookup entry for decl"); // Remove the decl only if it is contained. StoredDeclsList::DeclsTy *Vec = Pos->second.getAsVector(); - if ((Vec && is_contained(*Vec, ND)) || Pos->second.getAsDecl() == ND) + if ((Vec && llvm::is_contained(*Vec, ND)) || + Pos->second.getAsDecl() == ND) Pos->second.remove(ND); } } while (DC->isTransparentContext() && (DC = DC->getParent())); @@ -1663,7 +1665,8 @@ } } -NamedDecl *const DeclContextLookupResult::SingleElementDummyList = nullptr; +DeclContextLookupResult::ResultTy +const DeclContextLookupResult::SingleElementDummyList = { nullptr }; DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) const { Index: clang/lib/AST/ExternalASTMerger.cpp =================================================================== --- clang/lib/AST/ExternalASTMerger.cpp +++ clang/lib/AST/ExternalASTMerger.cpp @@ -77,7 +77,7 @@ // nothing (rather than a possibly-inaccurate guess) here. return nullptr; } else { - NamedDecl *SearchResultDecl = SearchResult[0]; + NamedDecl *SearchResultDecl = SearchResult.front(); if (isa(SearchResultDecl) && SearchResultDecl->getKind() == DC->getDeclKind()) return cast(SearchResultDecl)->getPrimaryContext(); Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -4106,13 +4106,9 @@ IdentifierInfo *MemberOrBase) { if (SS.getScopeRep() || TemplateTypeTy) return nullptr; - DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase); - if (Result.empty()) - return nullptr; - ValueDecl *Member; - if ((Member = dyn_cast(Result.front())) || - (Member = dyn_cast(Result.front()))) - return Member; + for (auto *D : ClassDecl->lookup(MemberOrBase)) + if (isa(D) || isa(D)) + return cast(D); return nullptr; } @@ -15081,9 +15077,9 @@ // different modules). assert((getLangOpts().Modules || (!Lookup.empty() && Lookup.size() <= 2)) && "more than two lookup results for field name"); - FieldDecl *Pattern = dyn_cast(Lookup[0]); + FieldDecl *Pattern = dyn_cast(Lookup.back()); if (!Pattern) { - assert(isa(Lookup[0]) && + assert(isa(Lookup.back()) && "cannot have other non-field member with same name"); for (auto L : Lookup) if (isa(L)) { Index: clang/lib/Sema/SemaObjCProperty.cpp =================================================================== --- clang/lib/Sema/SemaObjCProperty.cpp +++ clang/lib/Sema/SemaObjCProperty.cpp @@ -112,9 +112,8 @@ return; // Look for a property with the same name. - DeclContext::lookup_result R = Proto->lookup(Prop->getDeclName()); - for (unsigned I = 0, N = R.size(); I != N; ++I) { - if (ObjCPropertyDecl *ProtoProp = dyn_cast(R[I])) { + for (auto *R : Proto->lookup(Prop->getDeclName())) { + if (ObjCPropertyDecl *ProtoProp = dyn_cast(R)) { S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); return; } @@ -233,9 +232,8 @@ bool FoundInSuper = false; ObjCInterfaceDecl *CurrentInterfaceDecl = IFace; while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) { - DeclContext::lookup_result R = Super->lookup(Res->getDeclName()); - for (unsigned I = 0, N = R.size(); I != N; ++I) { - if (ObjCPropertyDecl *SuperProp = dyn_cast(R[I])) { + for (auto *R : Super->lookup(Res->getDeclName())) { + if (ObjCPropertyDecl *SuperProp = dyn_cast(R)) { DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false); FoundInSuper = true; break; @@ -1150,7 +1148,7 @@ for (auto *Ext : IDecl->known_extensions()) { DeclContext::lookup_result R = Ext->lookup(property->getDeclName()); if (!R.empty()) - if (ObjCPropertyDecl *ExtProp = dyn_cast(R[0])) { + if (auto *ExtProp = dyn_cast(R.front())) { PIkind = ExtProp->getPropertyAttributesAsWritten(); if (PIkind & ObjCPropertyAttribute::kind_readwrite) { ReadWriteProperty = true; Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3414,7 +3414,7 @@ Instantiation->getTemplateInstantiationPattern(); DeclContext::lookup_result Lookup = ClassPattern->lookup(Field->getDeclName()); - FieldDecl *Pattern = cast(Lookup.front()); + FieldDecl *Pattern = cast(Lookup.back()); InstantiateInClassInitializer(PointOfInstantiation, Field, Pattern, TemplateArgs); }