Index: clang-tools-extra/clangd/unittests/TestTU.cpp =================================================================== --- clang-tools-extra/clangd/unittests/TestTU.cpp +++ clang-tools-extra/clangd/unittests/TestTU.cpp @@ -192,7 +192,7 @@ llvm::StringRef Name) -> const NamedDecl & { auto LookupRes = Scope.lookup(DeclarationName(&Ctx.Idents.get(Name))); assert(!LookupRes.empty() && "Lookup failed"); - assert(LookupRes.size() == 1 && "Lookup returned multiple results"); + assert(LookupRes.isSingleResult() && "Lookup returned multiple results"); return *LookupRes.front(); }; Index: clang/include/clang/AST/ASTContext.h =================================================================== --- clang/include/clang/AST/ASTContext.h +++ clang/include/clang/AST/ASTContext.h @@ -592,6 +592,9 @@ std::unique_ptr InterpContext; std::unique_ptr ParentMapCtx; + /// Keeps track of the deallocated DeclListNodes for future reuse. + DeclListNode *ListNodeFreeList = nullptr; + public: IdentifierTable &Idents; SelectorTable &Selectors; @@ -643,6 +646,24 @@ } void Deallocate(void *Ptr) const {} + /// Allocates a \c DeclListNode or returns one from the \c ListNodeFreeList + /// pool. + DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) { + if (DeclListNode *Alloc = ListNodeFreeList) { + ListNodeFreeList = Alloc->Rest.dyn_cast(); + Alloc->D = ND; + Alloc->Rest = nullptr; + return Alloc; + } + return new (*this) DeclListNode(ND); + } + /// Deallcates a \c DeclListNode by returning it to the \c ListNodeFreeList + /// pool. + void DeallocateDeclListNode(DeclListNode *N) { + N->Rest = ListNodeFreeList; + ListNodeFreeList = N; + } + /// Return the total amount of physical memory allocated for representing /// AST nodes and type information. size_t getASTAllocatedMemory() const { Index: clang/include/clang/AST/CXXInheritance.h =================================================================== --- clang/include/clang/AST/CXXInheritance.h +++ clang/include/clang/AST/CXXInheritance.h @@ -76,9 +76,8 @@ CXXBasePath() = default; - /// The set of declarations found inside this base class - /// subobject. - DeclContext::lookup_result Decls; + /// The declarations found inside this base class subobject. + DeclContext::lookup_iterator Decls; void clear() { SmallVectorImpl::clear(); Index: clang/include/clang/AST/Decl.h =================================================================== --- clang/include/clang/AST/Decl.h +++ clang/include/clang/AST/Decl.h @@ -579,6 +579,16 @@ AnonOrFirstNamespaceAndInline.setInt(Inline); } + /// Returns true if the inline qualifier for \c Name is redundant. + bool isRedundantInlineQualifierFor(DeclarationName Name) const { + if (!isInline()) + return false; + auto X = lookup(Name); + auto Y = getParent()->lookup(Name); + return std::distance(X.begin(), X.end()) == + std::distance(Y.begin(), Y.end()); + } + /// Get the original (first) namespace declaration. NamespaceDecl *getOriginalNamespace(); Index: clang/include/clang/AST/DeclBase.h =================================================================== --- clang/include/clang/AST/DeclBase.h +++ clang/include/clang/AST/DeclBase.h @@ -1221,64 +1221,94 @@ void print(raw_ostream &OS) const override; }; +/// A list storing NamedDecls in the lookup tables. +class DeclListNode { + friend class ASTContext; // allocate, deallocate nodes. + friend class StoredDeclsList; +public: + using Decls = llvm::PointerUnion; + class iterator { + friend class DeclContextLookupResult; + + Decls Ptr; + iterator(Decls Node) : Ptr(Node) { } + public: + using difference_type = ptrdiff_t; + using value_type = NamedDecl*; + using pointer = value_type; + using reference = value_type; + using iterator_category = std::forward_iterator_tag; + + iterator() = default; + + reference operator*() const { + assert(Ptr && "dereferencing end() iterator"); + if (DeclListNode *CurNode = Ptr.dyn_cast()) + return CurNode->D; + return Ptr.get(); + } + void operator->() const { } // Unsupported. + bool operator==(const iterator &X) const { return Ptr == X.Ptr; } + bool operator!=(const iterator &X) const { return Ptr != X.Ptr; } + inline iterator &operator++() { // ++It + assert(!Ptr.isNull() && "Advancing empty iterator"); + + if (DeclListNode *CurNode = Ptr.dyn_cast()) + Ptr = CurNode->Rest; + else + Ptr = nullptr; + return *this; + } + iterator operator++(int) { // It++ + iterator temp = *this; + ++(*this); + return temp; + } + // Enables the pattern for (iterator I =..., E = I.end(); I != E; ++I) + iterator end() { return iterator(); } + }; +private: + NamedDecl *D = nullptr; + Decls Rest = nullptr; + DeclListNode(NamedDecl *ND) : D(ND) {} +}; + /// The results of name lookup within a DeclContext. This is either a /// single result (with no stable storage) or a collection of results (with /// stable storage provided by the lookup table). class DeclContextLookupResult { - using ResultTy = ArrayRef; + friend class StoredDeclsList; - ResultTy Result; + using Decls = DeclListNode::Decls; - // 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; + /// When in collection form, this is what the Data pointer points to. + Decls Result; public: DeclContextLookupResult() = default; - DeclContextLookupResult(ArrayRef Result) - : Result(Result) {} - DeclContextLookupResult(NamedDecl *Single) - : Result(SingleElementDummyList), Single(Single) {} - - class iterator; + DeclContextLookupResult(Decls Result) : Result(Result) {} - using IteratorBase = - llvm::iterator_adaptor_base; - - class iterator : public IteratorBase { - value_type SingleElement; + using iterator = DeclListNode::iterator; + using const_iterator = iterator; + using reference = iterator::reference; - public: - explicit iterator(pointer Pos, value_type Single = nullptr) - : IteratorBase(Pos), SingleElement(Single) {} + iterator begin() { return iterator(Result); } + iterator end() { return iterator(); } + const_iterator begin() const { + return const_cast(this)->begin(); + } + const_iterator end() const { return iterator(); } - reference operator*() const { - return SingleElement ? SingleElement : IteratorBase::operator*(); - } - }; + bool empty() const { return Result.isNull(); } + bool isSingleResult() const { return Result.dyn_cast(); } + reference front() const { return *begin(); } - using const_iterator = iterator; - using pointer = iterator::pointer; - using reference = iterator::reference; + template T *find_first() const { + for (auto *D : *this) + if (T *Decl = dyn_cast(D)) + return Decl; - iterator begin() const { return iterator(Result.begin(), Single); } - 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]; } - - // FIXME: Remove this from the interface - DeclContextLookupResult slice(size_t N) const { - DeclContextLookupResult Sliced = Result.slice(N); - Sliced.Single = Single; - return Sliced; + return nullptr; } }; Index: clang/include/clang/AST/DeclContextInternals.h =================================================================== --- clang/include/clang/AST/DeclContextInternals.h +++ clang/include/clang/AST/DeclContextInternals.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H #define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -21,7 +22,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/SmallVector.h" #include #include @@ -31,97 +31,166 @@ /// An array of decls optimized for the common case of only containing /// one entry. -struct StoredDeclsList { - /// When in vector form, this is what the Data pointer points to. - using DeclsTy = SmallVector; +class StoredDeclsList { + using DeclsTy = DeclListNode; + using Decls = DeclListNode::Decls; /// A collection of declarations, with a flag to indicate if we have /// further external declarations. - using DeclsAndHasExternalTy = llvm::PointerIntPair; + using DeclsAndHasExternalTy = llvm::PointerIntPair; /// The stored data, which will be either a pointer to a NamedDecl, - /// or a pointer to a vector with a flag to indicate if there are further + /// or a pointer to a list with a flag to indicate if there are further /// external declarations. - llvm::PointerUnion Data; + DeclsAndHasExternalTy Data; + + void setOnlyValue(NamedDecl *ND) { + assert(!getAsList() && "Not inline"); + Data.setPointer(ND); + // Make sure that Data is a plain NamedDecl* so we can use its address + // at getLookupResult. + assert(*(NamedDecl **)Data.getPointer().getAddrOfPtr1() == ND && + "PointerUnion mangles the NamedDecl pointer!"); + } + + void push_front(NamedDecl *ND) { + assert(!isNull() && "No need to call push_front"); + + ASTContext &C = getASTContext(); + + // If this is the second decl added optimize the use by setting the pointer + // to the next to point to OldD. This way we save an extra allocation. + if (NamedDecl *OldD = getAsDecl()) { + //assert(OldD != ND && "list already contains decl"); + DeclsTy *Node = C.AllocateDeclListNode(OldD); + Node->Rest = ND; + Data.setPointer(Node); + return; + } + // auto Vec = getLookupResult(); + // (void)Vec; + // assert(llvm::find(Vec, ND) == Vec.end() && "list still contains decl"); + + DeclsTy *Node = C.AllocateDeclListNode(ND); + // DeclsTy *Cur = getAsList(); + // while(Cur->Rest.dyn_cast()) + // Cur = Cur->Rest.get(); + // Node->Rest = Cur->Rest; + // Cur->Rest = Node; + Node->Rest = Data.getPointer(); + Data.setPointer(Node); + } + + template + void erase_if(Pred pred) { + assert(getAsList() && "Not in list mode!"); + ASTContext &C = getASTContext(); + for (Decls N = Data.getPointer(), Prev = N; N; ) { + if (DeclsTy *L = N.dyn_cast()) { + if (pred(L->D)) { + if (L == getAsList()) + Data.setPointer(L->Rest); + else + Prev.get()->Rest = L->Rest; + N = L->Rest; + C.DeallocateDeclListNode(L); + } else { + N = L->Rest; + Prev = L; + } + } else { + NamedDecl *ND = N.get(); + if (pred(ND)) { + if (getAsDecl()) + Data.setPointer(nullptr); + else + Prev.get()->Rest = nullptr; + } + break; + } + } + + assert(llvm::find_if(getLookupResult(), pred) == getLookupResult().end() && + "Still exists!"); + } + + void erase(NamedDecl *ND) { + erase_if([ND](NamedDecl *D){ return D == ND; }); + } public: StoredDeclsList() = default; StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) { - RHS.Data = (NamedDecl *)nullptr; + RHS.Data.setPointer(nullptr); + RHS.Data.setInt(0); + } + + void MaybeDeallocList() { + if (isNull()) + return; + // If this is a list-form, free the list. + ASTContext &C = getASTContext(); + Decls List = Data.getPointer(); + while(List.is()) { + DeclsTy *ToDealloc = List.get(); + List = ToDealloc->Rest; + C.DeallocateDeclListNode(ToDealloc); + } } ~StoredDeclsList() { - // If this is a vector-form, free the vector. - if (DeclsTy *Vector = getAsVector()) - delete Vector; + MaybeDeallocList(); } StoredDeclsList &operator=(StoredDeclsList &&RHS) { - if (DeclsTy *Vector = getAsVector()) - delete Vector; + MaybeDeallocList(); + Data = RHS.Data; - RHS.Data = (NamedDecl *)nullptr; + RHS.Data.setPointer(nullptr); + RHS.Data.setInt(0); return *this; } - bool isNull() const { return Data.isNull(); } + bool isNull() const { return Data.getPointer().isNull(); } - NamedDecl *getAsDecl() const { - return Data.dyn_cast(); + ASTContext &getASTContext() { + assert(!isNull() && "No ASTContext."); + if (NamedDecl *ND = getAsDecl()) + return ND->getASTContext(); + return getAsList()->D->getASTContext(); } - DeclsAndHasExternalTy getAsVectorAndHasExternal() const { - return Data.dyn_cast(); + DeclsAndHasExternalTy getAsListAndHasExternal() const { return Data; } + + NamedDecl *getAsDecl() const { + return getAsListAndHasExternal().getPointer().dyn_cast(); } - DeclsTy *getAsVector() const { - return getAsVectorAndHasExternal().getPointer(); + DeclsTy *getAsList() const { + return getAsListAndHasExternal().getPointer().dyn_cast(); } bool hasExternalDecls() const { - return getAsVectorAndHasExternal().getInt(); + return getAsListAndHasExternal().getInt(); } void setHasExternalDecls() { - if (DeclsTy *Vec = getAsVector()) - Data = DeclsAndHasExternalTy(Vec, true); - else { - DeclsTy *VT = new DeclsTy(); - if (NamedDecl *OldD = getAsDecl()) - VT->push_back(OldD); - Data = DeclsAndHasExternalTy(VT, true); - } - } - - void setOnlyValue(NamedDecl *ND) { - assert(!getAsVector() && "Not inline"); - Data = ND; - // Make sure that Data is a plain NamedDecl* so we can use its address - // at getLookupResult. - assert(*(NamedDecl **)&Data == ND && - "PointerUnion mangles the NamedDecl pointer!"); + Data.setInt(1); } void remove(NamedDecl *D) { assert(!isNull() && "removing from empty list"); if (NamedDecl *Singleton = getAsDecl()) { - assert(Singleton == D && "list is different singleton"); - (void)Singleton; - Data = (NamedDecl *)nullptr; + if (Singleton == D) + Data.setPointer(nullptr); return; } - DeclsTy &Vec = *getAsVector(); - DeclsTy::iterator I = llvm::find(Vec, D); - assert(I != Vec.end() && "list does not contain decl"); - Vec.erase(I); - - assert(llvm::find(Vec, D) == Vec.end() && "list still contains decl"); + erase(D); } - /// Remove any declarations which were imported from an external - /// AST source. + /// Remove any declarations which were imported from an external AST source. void removeExternalDecls() { if (isNull()) { // Nothing to do. @@ -129,38 +198,20 @@ if (Singleton->isFromASTFile()) *this = StoredDeclsList(); } else { - DeclsTy &Vec = *getAsVector(); - Vec.erase(std::remove_if(Vec.begin(), Vec.end(), - [](Decl *D) { return D->isFromASTFile(); }), - Vec.end()); + erase_if([](NamedDecl *ND){ return ND->isFromASTFile(); }); // Don't have any external decls any more. - Data = DeclsAndHasExternalTy(&Vec, false); + Data.setInt(0); } } /// getLookupResult - Return an array of all the decls that this list /// represents. - DeclContext::lookup_result getLookupResult() { - if (isNull()) - return DeclContext::lookup_result(); - - // If we have a single NamedDecl, return it. - if (NamedDecl *ND = getAsDecl()) { - assert(!isNull() && "Empty list isn't allowed"); - - // Data is a raw pointer to a NamedDecl*, return it. - return DeclContext::lookup_result(ND); - } - - assert(getAsVector() && "Must have a vector at this point"); - DeclsTy &Vector = *getAsVector(); - - // Otherwise, we have a range result. - return DeclContext::lookup_result(Vector); + DeclContext::lookup_result getLookupResult() const { + return DeclContext::lookup_result(Data.getPointer()); } /// HandleRedeclaration - If this is a redeclaration of an existing decl, - /// replace the old one with D and return true. Otherwise return false. + /// replace the old one with D and return true. Otherwise return false. bool HandleRedeclaration(NamedDecl *D, bool IsKnownNewer) { // Most decls only have one entry in their list, special case it. if (NamedDecl *OldD = getAsDecl()) { @@ -171,91 +222,55 @@ } // Determine if this declaration is actually a redeclaration. - DeclsTy &Vec = *getAsVector(); - for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); - OD != ODEnd; ++OD) { - NamedDecl *OldD = *OD; - if (D->declarationReplaces(OldD, IsKnownNewer)) { - *OD = D; + for (DeclsTy* N = getAsList(); N; N = N->Rest.dyn_cast()) { + if (D->declarationReplaces(N->D, IsKnownNewer)) { + N->D = D; return true; } + if (auto *ND = N->Rest.dyn_cast()) // the two element case + if (D->declarationReplaces(ND, IsKnownNewer)) { + N->Rest = D; + return true; + } } return false; } - /// AddSubsequentDecl - This is called on the second and later decl when it is - /// not a redeclaration to merge it into the appropriate place in our list. - void AddSubsequentDecl(NamedDecl *D) { - assert(!isNull() && "don't AddSubsequentDecl when we have no decls"); - - // If this is the second decl added to the list, convert this to vector - // form. - if (NamedDecl *OldD = getAsDecl()) { - DeclsTy *VT = new DeclsTy(); - VT->push_back(OldD); - Data = DeclsAndHasExternalTy(VT, false); + /// AddDecl - Called to add declarations when it is not a redeclaration to + /// merge it into the appropriate place in our list. + void AddDecl(NamedDecl *D) { + if (isNull()) { + setOnlyValue(D); + return; } - DeclsTy &Vec = *getAsVector(); - - // Using directives end up in a special entry which contains only - // other using directives, so all this logic is wasted for them. - // But avoiding the logic wastes time in the far-more-common case - // that we're *not* adding a new using directive. - - // Tag declarations always go at the end of the list so that an - // iterator which points at the first tag will start a span of - // decls that only contains tags. - if (D->hasTagIdentifierNamespace()) - Vec.push_back(D); - - // Resolved using declarations go at the front of the list so that - // they won't show up in other lookup results. Unresolved using - // 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); - - // All other declarations go at the end of the list, but before any - // tag declarations. But we can be clever about tag declarations - // because there can only ever be one in a scope. - } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) { - NamedDecl *TagD = Vec.back(); - Vec.back() = D; - Vec.push_back(TagD); - } else - Vec.push_back(D); + push_front(D); + } + + LLVM_DUMP_METHOD void dump() const { + for (auto *ND : getLookupResult()) + llvm::errs() << ND->getNameAsString() << " " << ND << "\n"; } }; class StoredDeclsMap : public llvm::SmallDenseMap { -public: - static void DestroyAll(StoredDeclsMap *Map, bool Dependent); - -private: friend class ASTContext; // walks the chain deleting these friend class DeclContext; llvm::PointerIntPair Previous; +public: + static void DestroyAll(StoredDeclsMap *Map, bool Dependent); }; class DependentStoredDeclsMap : public StoredDeclsMap { -public: - DependentStoredDeclsMap() = default; - -private: friend class DeclContext; // iterates over diagnostics friend class DependentDiagnostic; DependentDiagnostic *FirstDiagnostic = nullptr; +public: + DependentStoredDeclsMap() = default; }; } // namespace clang Index: clang/lib/ARCMigrate/ObjCMT.cpp =================================================================== --- clang/lib/ARCMigrate/ObjCMT.cpp +++ clang/lib/ARCMigrate/ObjCMT.cpp @@ -613,7 +613,7 @@ continue; HasAtleastOneRequiredProperty = true; DeclContext::lookup_result R = IDecl->lookup(Property->getDeclName()); - if (R.size() == 0) { + if (R.empty()) { // Relax the rule and look into class's implementation for a synthesize // or dynamic declaration. Class is implementing a property coming from // another protocol. This still makes the target protocol as conforming. @@ -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())) @@ -645,12 +645,12 @@ if (MD->getImplementationControl() == ObjCMethodDecl::Optional) continue; DeclContext::lookup_result R = ImpDecl->lookup(MD->getDeclName()); - if (R.size() == 0) + if (R.empty()) return false; bool match = false; HasAtleastOneRequiredMethod = true; - for (unsigned I = 0, N = R.size(); I != N; ++I) - if (ObjCMethodDecl *ImpMD = dyn_cast(R[0])) + for (NamedDecl *ND : R) + if (ObjCMethodDecl *ImpMD = dyn_cast(ND)) if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) { match = true; break; Index: clang/lib/AST/CXXInheritance.cpp =================================================================== --- clang/lib/AST/CXXInheritance.cpp +++ clang/lib/AST/CXXInheritance.cpp @@ -386,9 +386,9 @@ static bool findOrdinaryMember(const CXXRecordDecl *RD, CXXBasePath &Path, DeclarationName Name) { - Path.Decls = RD->lookup(Name); - for (NamedDecl *ND : Path.Decls) - if (isOrdinaryMember(ND)) + Path.Decls = RD->lookup(Name).begin(); + for (DeclContext::lookup_iterator I = Path.Decls, E = I.end(); I != E; ++I) + if (isOrdinaryMember(*I)) return true; return false; @@ -453,9 +453,10 @@ }, Paths, /*LookupInDependent=*/true)) return Results; - for (const NamedDecl *ND : Paths.front().Decls) { - if (isOrdinaryMember(ND) && Filter(ND)) - Results.push_back(ND); + for (DeclContext::lookup_iterator I = Paths.front().Decls, E = I.end(); + I != E; ++I) { + if (isOrdinaryMember(*I) && Filter(*I)) + Results.push_back(*I); } return Results; } Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -1609,8 +1609,7 @@ // Suppress inline namespace if it doesn't make the result ambiguous. if (P.SuppressInlineNamespace && Ctx->isInlineNamespace() && NameInScope && - Ctx->lookup(NameInScope).size() == - Ctx->getParent()->lookup(NameInScope).size()) + cast(Ctx)->isRedundantInlineQualifierFor(NameInScope)) continue; // Skip non-named contexts such as linkage specifications and ExportDecls. Index: clang/lib/AST/DeclBase.cpp =================================================================== --- clang/lib/AST/DeclBase.cpp +++ clang/lib/AST/DeclBase.cpp @@ -1420,15 +1420,12 @@ if (I == Skip[SkipPos]) ++SkipPos; else - List.AddSubsequentDecl(Decls[I]); + List.AddDecl(Decls[I]); } } else { // Convert the array to a StoredDeclsList. for (auto *D : Decls) { - if (List.isNull()) - List.setOnlyValue(D); - else - List.AddSubsequentDecl(D); + List.AddDecl(D); } } @@ -1543,10 +1540,7 @@ if (Map) { StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); 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) - Pos->second.remove(ND); + Pos->second.remove(ND); } } while (DC->isTransparentContext() && (DC = DC->getParent())); } @@ -1663,8 +1657,6 @@ } } -NamedDecl *const DeclContextLookupResult::SingleElementDummyList = nullptr; - DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) const { assert(getDeclKind() != Decl::LinkageSpec && @@ -1940,12 +1932,12 @@ // In this case, we never try to replace an existing declaration; we'll // handle that when we finalize the list of declarations for this name. DeclNameEntries.setHasExternalDecls(); - DeclNameEntries.AddSubsequentDecl(D); + DeclNameEntries.AddDecl(D); return; } if (DeclNameEntries.isNull()) { - DeclNameEntries.setOnlyValue(D); + DeclNameEntries.AddDecl(D); return; } @@ -1956,7 +1948,7 @@ } // Put this declaration into the appropriate slot. - DeclNameEntries.AddSubsequentDecl(D); + DeclNameEntries.AddDecl(D); } UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const { Index: clang/lib/AST/ExternalASTMerger.cpp =================================================================== --- clang/lib/AST/ExternalASTMerger.cpp +++ clang/lib/AST/ExternalASTMerger.cpp @@ -64,24 +64,24 @@ Source SourceName = *SourceNameOrErr; DeclContext::lookup_result SearchResult = SourceParentDC.get()->lookup(SourceName.get()); - size_t SearchResultSize = SearchResult.size(); - if (SearchResultSize == 0 || SearchResultSize > 1) { - // There are two cases here. First, we might not find the name. - // We might also find multiple copies, in which case we have no - // guarantee that the one we wanted is the one we pick. (E.g., - // if we have two specializations of the same template it is - // very hard to determine which is the one you want.) - // - // The Origins map fixes this problem by allowing the origin to be - // explicitly recorded, so we trigger that recording by returning - // nothing (rather than a possibly-inaccurate guess) here. - return nullptr; - } else { - NamedDecl *SearchResultDecl = SearchResult[0]; + + // There are two cases here. First, we might not find the name. + // We might also find multiple copies, in which case we have no + // guarantee that the one we wanted is the one we pick. (E.g., + // if we have two specializations of the same template it is + // very hard to determine which is the one you want.) + // + // The Origins map fixes this problem by allowing the origin to be + // explicitly recorded, so we trigger that recording by returning + // nothing (rather than a possibly-inaccurate guess) here. + if (SearchResult.isSingleResult()) { + NamedDecl *SearchResultDecl = SearchResult.front(); if (isa(SearchResultDecl) && SearchResultDecl->getKind() == DC->getDeclKind()) return cast(SearchResultDecl)->getPrimaryContext(); return nullptr; // This type of lookup is unsupported + } else { + return nullptr; } } Index: clang/lib/AST/TypePrinter.cpp =================================================================== --- clang/lib/AST/TypePrinter.cpp +++ clang/lib/AST/TypePrinter.cpp @@ -1230,8 +1230,7 @@ // Only suppress an inline namespace if the name has the same lookup // results in the enclosing namespace. if (Policy.SuppressInlineNamespace && NS->isInline() && NameInScope && - DC->getParent()->lookup(NameInScope).size() == - DC->lookup(NameInScope).size()) + NS->isRedundantInlineQualifierFor(NameInScope)) return AppendScope(DC->getParent(), OS, NameInScope); AppendScope(DC->getParent(), OS, NS->getDeclName()); Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -4614,7 +4614,6 @@ struct MultiVersionResolverOption { llvm::Function *Function; - FunctionDecl *FD; struct Conds { StringRef Architecture; llvm::SmallVector Features; Index: clang/lib/Sema/MultiplexExternalSemaSource.cpp =================================================================== --- clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// #include "clang/Sema/MultiplexExternalSemaSource.h" -#include "clang/AST/DeclContextInternals.h" #include "clang/Sema/Lookup.h" using namespace clang; Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -4120,13 +4120,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; } @@ -9657,9 +9653,9 @@ bool foundSameNameMethod = false; SmallVector overloadedMethods; - for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - NamedDecl *D = Path.Decls.front(); + for (Path.Decls = BaseRecord->lookup(Name).begin(); + Path.Decls != DeclContext::lookup_iterator(); ++Path.Decls) { + NamedDecl *D = *Path.Decls; if (CXXMethodDecl *MD = dyn_cast(D)) { MD = MD->getCanonicalDecl(); foundSameNameMethod = true; Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -638,8 +638,8 @@ void LookupResult::addDeclsFromBasePaths(const CXXBasePaths &P) { CXXBasePaths::const_paths_iterator I, E; for (I = P.begin(), E = P.end(); I != E; ++I) - for (DeclContext::lookup_iterator DI = I->Decls.begin(), - DE = I->Decls.end(); DI != DE; ++DI) + for (DeclContext::lookup_iterator DI = I->Decls, DE = DI.end(); DI != DE; + ++DI) addDecl(*DI); } @@ -2191,9 +2191,9 @@ CXXRecordDecl *BaseRecord = Specifier->getType()->getAsCXXRecordDecl(); // Drop leading non-matching lookup results from the declaration list so // we don't need to consider them again below. - for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - if (Path.Decls.front()->isInIdentifierNamespace(IDNS)) + for (Path.Decls = BaseRecord->lookup(Name).begin(); + Path.Decls != Path.Decls.end(); ++Path.Decls) { + if ((*Path.Decls)->isInIdentifierNamespace(IDNS)) return true; } return false; @@ -2217,9 +2217,9 @@ AccessSpecifier SubobjectAccess = AS_none; // Check whether the given lookup result contains only static members. - auto HasOnlyStaticMembers = [&](DeclContextLookupResult Result) { - for (NamedDecl *ND : Result) - if (ND->isInIdentifierNamespace(IDNS) && ND->isCXXInstanceMember()) + auto HasOnlyStaticMembers = [&](DeclContext::lookup_iterator Result) { + for (DeclContext::lookup_iterator I = Result, E = I.end(); I != E; ++I) + if ((*I)->isInIdentifierNamespace(IDNS) && (*I)->isCXXInstanceMember()) return false; return true; }; @@ -2228,8 +2228,8 @@ // Determine whether two sets of members contain the same members, as // required by C++ [class.member.lookup]p6. - auto HasSameDeclarations = [&](DeclContextLookupResult A, - DeclContextLookupResult B) { + auto HasSameDeclarations = [&](DeclContext::lookup_iterator A, + DeclContext::lookup_iterator B) { using Iterator = DeclContextLookupResult::iterator; using Result = const void *; @@ -2266,7 +2266,7 @@ // We'll often find the declarations are in the same order. Handle this // case (and the special case of only one declaration) efficiently. - Iterator AIt = A.begin(), BIt = B.begin(), AEnd = A.end(), BEnd = B.end(); + Iterator AIt = A, BIt = B, AEnd, BEnd; while (true) { Result AResult = Next(AIt, AEnd); Result BResult = Next(BIt, BEnd); @@ -2349,10 +2349,11 @@ // Lookup in a base class succeeded; return these results. - for (auto *D : Paths.front().Decls) { + for (DeclContext::lookup_iterator I = Paths.front().Decls, E = I.end(); + I != E; ++I) { AccessSpecifier AS = CXXRecordDecl::MergeAccess(SubobjectAccess, - D->getAccess()); - if (NamedDecl *ND = R.getAcceptableDecl(D)) + (*I)->getAccess()); + if (NamedDecl *ND = R.getAcceptableDecl(*I)) R.addDecl(ND, AS); } R.resolveKind(); @@ -2495,7 +2496,7 @@ << Name << SubobjectType << getAmbiguousPathsDisplayString(*Paths) << LookupRange; - DeclContext::lookup_iterator Found = Paths->front().Decls.begin(); + DeclContext::lookup_iterator Found = Paths->front().Decls; while (isa(*Found) && cast(*Found)->isStatic()) ++Found; @@ -2513,7 +2514,7 @@ for (CXXBasePaths::paths_iterator Path = Paths->begin(), PathEnd = Paths->end(); Path != PathEnd; ++Path) { - const NamedDecl *D = Path->Decls.front(); + const NamedDecl *D = *Path->Decls; if (!D->isInIdentifierNamespace(Result.getIdentifierNamespace())) continue; if (DeclsPrinted.insert(D).second) { Index: clang/lib/Sema/SemaObjCProperty.cpp =================================================================== --- clang/lib/Sema/SemaObjCProperty.cpp +++ clang/lib/Sema/SemaObjCProperty.cpp @@ -112,12 +112,10 @@ 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])) { - S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); - return; - } + if (ObjCPropertyDecl *ProtoProp = + Proto->lookup(Prop->getDeclName()).find_first()) { + S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); + return; } // Check this property against any protocols we inherit. @@ -233,13 +231,11 @@ 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])) { - DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false); - FoundInSuper = true; - break; - } + if (ObjCPropertyDecl *SuperProp = + Super->lookup(Res->getDeclName()).find_first()) { + DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false); + FoundInSuper = true; + break; } if (FoundInSuper) break; @@ -1149,14 +1145,13 @@ // redeclared 'readwrite', then no warning is to be issued. for (auto *Ext : IDecl->known_extensions()) { DeclContext::lookup_result R = Ext->lookup(property->getDeclName()); - if (!R.empty()) - if (ObjCPropertyDecl *ExtProp = dyn_cast(R[0])) { - PIkind = ExtProp->getPropertyAttributesAsWritten(); - if (PIkind & ObjCPropertyAttribute::kind_readwrite) { - ReadWriteProperty = true; - break; - } + if (auto *ExtProp = R.find_first()) { + PIkind = ExtProp->getPropertyAttributesAsWritten(); + if (PIkind & ObjCPropertyAttribute::kind_readwrite) { + ReadWriteProperty = true; + break; } + } } if (!ReadWriteProperty) { Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3417,7 +3417,8 @@ Instantiation->getTemplateInstantiationPattern(); DeclContext::lookup_result Lookup = ClassPattern->lookup(Field->getDeclName()); - FieldDecl *Pattern = cast(Lookup.front()); + FieldDecl *Pattern = Lookup.find_first(); + assert(Pattern); InstantiateInClassInitializer(PointOfInstantiation, Field, Pattern, TemplateArgs); } Index: clang/lib/Serialization/ASTWriterDecl.cpp =================================================================== --- clang/lib/Serialization/ASTWriterDecl.cpp +++ clang/lib/Serialization/ASTWriterDecl.cpp @@ -13,7 +13,6 @@ #include "ASTCommon.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclContextInternals.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/Expr.h" Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -841,7 +841,7 @@ llvm::Optional operator()(StringRef Name) { IdentifierInfo &II = ACtx.Idents.get(Name); auto LookupRes = ACtx.getTranslationUnitDecl()->lookup(&II); - if (LookupRes.size() == 0) + if (LookupRes.empty()) return None; // Prioritze typedef declarations. @@ -993,7 +993,7 @@ return false; IdentifierInfo &II = ACtx.Idents.get(Name); auto LookupRes = ACtx.getTranslationUnitDecl()->lookup(&II); - if (LookupRes.size() == 0) + if (LookupRes.empty()) return false; for (Decl *D : LookupRes) { if (auto *FD = dyn_cast(D)) { Index: clang/test/CodeCompletion/function-overloads.cpp =================================================================== --- clang/test/CodeCompletion/function-overloads.cpp +++ clang/test/CodeCompletion/function-overloads.cpp @@ -36,8 +36,8 @@ // CHECK-CC1-NOT, CHECK-CC2-NOT: OVERLOAD: A( // CHECK-CC2: OVERLOAD: [#int#]f(float x, float y) // CHECK-CC2-NOT: OVERLOAD: [#int#]f(int i) +// CHECK-CC3: OVERLOAD: A(<#A &&#>) // CHECK-CC3: OVERLOAD: A(<#int#>, int, int) // CHECK-CC3: OVERLOAD: A(<#const A &#>) -// CHECK-CC3: OVERLOAD: A(<#A &&#>) // CHECK-CC4: OVERLOAD: A(int, <#int#>, int) // CHECK-CC5: OVERLOAD: [#void#]g(X, <#Y#>) Index: clang/test/Index/complete-call.cpp =================================================================== --- clang/test/Index/complete-call.cpp +++ clang/test/Index/complete-call.cpp @@ -850,9 +850,9 @@ // CHECK-CC59-NEXT: Objective-C interface // RUN: c-index-test -code-completion-at=%s:104:14 %s | FileCheck -check-prefix=CHECK-CC60 %s +// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) // CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) -// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC60: Completion contexts: // CHECK-CC60-NEXT: Any type // CHECK-CC60-NEXT: Any value @@ -864,9 +864,9 @@ // CHECK-CC60-NEXT: Objective-C interface // RUN: c-index-test -code-completion-at=%s:106:11 %s | FileCheck -check-prefix=CHECK-CC61 %s +// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) // CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) -// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC61: Completion contexts: // CHECK-CC61-NEXT: Any type // CHECK-CC61-NEXT: Any value @@ -878,9 +878,9 @@ // CHECK-CC61-NEXT: Objective-C interface // RUN: c-index-test -code-completion-at=%s:111:16 %s | FileCheck -check-prefix=CHECK-CC62 %s +// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) // CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) -// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC62: Completion contexts: // CHECK-CC62-NEXT: Any type // CHECK-CC62-NEXT: Any value @@ -892,25 +892,24 @@ // CHECK-CC62-NEXT: Objective-C interface // RUN: c-index-test -code-completion-at=%s:131:23 %s | FileCheck -check-prefix=CHECK-CC63 %s +// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) // CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) -// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) -// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{Comma , }{Placeholder float c}{RightParen )} (1) // CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1) +// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{Comma , }{Placeholder float c}{RightParen )} (1) +// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) // RUN: c-index-test -code-completion-at=%s:133:11 %s | FileCheck -check-prefix=CHECK-CC64 %s +// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) // CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) -// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) // CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1) +// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) // RUN: c-index-test -code-completion-at=%s:138:25 %s | FileCheck -check-prefix=CHECK-CC65 %s +// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) // CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) // CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) -// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) -// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{Comma , }{Placeholder float c}{RightParen )} (1) // CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1) - +// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{Comma , }{Placeholder float c}{RightParen )} (1) +// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) Index: clang/test/Index/complete-exprs.cpp =================================================================== --- clang/test/Index/complete-exprs.cpp +++ clang/test/Index/complete-exprs.cpp @@ -53,9 +53,9 @@ // CHECK-CC1: NotImplemented:{TypedText operator} (40) // CHECK-CC1-NOT: push_back // CHECK-CC1: ClassDecl:{TypedText string} (50) +// CHECK-CC1: CXXConstructor:{TypedText string}{LeftParen (}{Placeholder const char *}{Comma , }{Placeholder int n}{RightParen )} (50) // CHECK-CC1: CXXConstructor:{TypedText string}{LeftParen (}{RightParen )} (50) // CHECK-CC1: CXXConstructor:{TypedText string}{LeftParen (}{Placeholder const char *}{RightParen )} (50) -// CHECK-CC1: CXXConstructor:{TypedText string}{LeftParen (}{Placeholder const char *}{Comma , }{Placeholder int n}{RightParen )} (50) // CHECK-CC1: ClassTemplate:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >} (50) // CHECK-CC1: CXXConstructor:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >}{LeftParen (}{Placeholder const T &}{Comma , }{Placeholder unsigned int n}{RightParen )} (50) // CHECK-CC1: FunctionTemplate:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >}{LeftParen (}{Placeholder InputIterator first}{Comma , }{Placeholder InputIterator last}{RightParen )} (50) Index: clang/test/Index/complete-functor-call.cpp =================================================================== --- clang/test/Index/complete-functor-call.cpp +++ clang/test/Index/complete-functor-call.cpp @@ -25,8 +25,8 @@ // RUN: c-index-test -code-completion-at=%s:16:5 %s | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC1: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC1: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter void *}{Comma , }{Placeholder T}{Comma , }{Placeholder T}{RightParen )} (1) +// CHECK-CC1: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC1: Completion contexts: // CHECK-CC1-NEXT: Any type // CHECK-CC1-NEXT: Any value @@ -39,8 +39,8 @@ // RUN: c-index-test -code-completion-at=%s:17:5 %s | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC2: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC2: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter void *}{Comma , }{Placeholder T}{Comma , }{Placeholder T}{RightParen )} (1) +// CHECK-CC2: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC2: Completion contexts: // CHECK-CC2-NEXT: Any type // CHECK-CC2-NEXT: Any value @@ -53,8 +53,8 @@ // RUN: c-index-test -code-completion-at=%s:18:5 %s | FileCheck -check-prefix=CHECK-CC3 %s // CHECK-CC3: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC3: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC3: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter void *}{Comma , }{Placeholder T}{Comma , }{Placeholder T}{RightParen )} (1) +// CHECK-CC3: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC3: Completion contexts: // CHECK-CC3-NEXT: Any type // CHECK-CC3-NEXT: Any value @@ -91,9 +91,9 @@ // RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC6 %s // CHECK-CC6: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC6: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) -// CHECK-CC6: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter void *}{Comma , }{Placeholder T}{Comma , }{Placeholder T}{RightParen )} (1) // CHECK-CC6: OverloadCandidate:{ResultType const S *}{Text operator()}{LeftParen (}{CurrentParameter const S &s}{RightParen )} (1) +// CHECK-CC6: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter void *}{Comma , }{Placeholder T}{Comma , }{Placeholder T}{RightParen )} (1) +// CHECK-CC6: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC6: Completion contexts: // CHECK-CC6-NEXT: Any type // CHECK-CC6-NEXT: Any value @@ -106,9 +106,9 @@ // RUN: c-index-test -code-completion-at=%s:19:28 %s | FileCheck -check-prefix=CHECK-CC7 %s // CHECK-CC7: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC7: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) -// CHECK-CC7: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter int}{Comma , }{Placeholder T}{Comma , }{Placeholder T}{RightParen )} (1) // CHECK-CC7: OverloadCandidate:{ResultType const S *}{Text operator()}{LeftParen (}{CurrentParameter const S &s}{RightParen )} (1) +// CHECK-CC7: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter int}{Comma , }{Placeholder T}{Comma , }{Placeholder T}{RightParen )} (1) +// CHECK-CC7: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC7: Completion contexts: // CHECK-CC7-NEXT: Any type // CHECK-CC7-NEXT: Any value @@ -178,8 +178,8 @@ // RUN: c-index-test -code-completion-at=%s:12:28 %s | FileCheck -check-prefix=CHECK-CC13 %s // CHECK-CC13: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter int}{RightParen )} (1) -// CHECK-CC13: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC13: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter void *}{Comma , }{Placeholder T}{Comma , }{Placeholder T}{RightParen )} (1) +// CHECK-CC13: OverloadCandidate:{ResultType void}{Text operator()}{LeftParen (}{CurrentParameter T}{RightParen )} (1) // CHECK-CC13: Completion contexts: // CHECK-CC13-NEXT: Any type // CHECK-CC13-NEXT: Any value Index: clang/tools/libclang/CXType.cpp =================================================================== --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -1030,7 +1030,7 @@ // and we would return InvalidFieldName instead of Incomplete. // But this erroneous results does protects again a hidden assertion failure // in the RecordLayoutBuilder - if (Res.size() != 1) + if (!Res.isSingleResult()) return CXTypeLayoutError_InvalidFieldName; if (const FieldDecl *FD = dyn_cast(Res.front())) return Ctx.getFieldOffset(FD); Index: clang/unittests/AST/ASTImporterTest.cpp =================================================================== --- clang/unittests/AST/ASTImporterTest.cpp +++ clang/unittests/AST/ASTImporterTest.cpp @@ -2529,9 +2529,9 @@ auto FromName = FromD->getDeclName(); auto *Class = FirstDeclMatcher().match(FromTU, ClassPattern); auto LookupRes = Class->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 0u); + ASSERT_TRUE(LookupRes.empty()); LookupRes = FromTU->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); } auto *ToD = cast(Import(FromD, Lang_CXX03)); @@ -2540,9 +2540,9 @@ TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); auto *Class = FirstDeclMatcher().match(ToTU, ClassPattern); auto LookupRes = Class->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 0u); + EXPECT_TRUE(LookupRes.empty()); LookupRes = ToTU->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); EXPECT_EQ(DeclCounter().match(ToTU, FunctionPattern), 1u); auto *To0 = FirstDeclMatcher().match(ToTU, FunctionPattern); @@ -2576,9 +2576,9 @@ auto *FromClass = FirstDeclMatcher().match(FromTU, ClassPattern); auto LookupRes = FromClass->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 0u); + ASSERT_TRUE(LookupRes.empty()); LookupRes = FromTU->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); auto *ToFriend = cast(Import(FromFriend, Lang_CXX03)); auto ToName = ToFriend->getDeclName(); @@ -2586,10 +2586,10 @@ TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); auto *ToClass = FirstDeclMatcher().match(ToTU, ClassPattern); LookupRes = ToClass->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 0u); + EXPECT_TRUE(LookupRes.empty()); LookupRes = ToTU->noload_lookup(ToName); // Test is disabled because this result is 2. - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); ASSERT_EQ(DeclCounter().match(ToTU, FunctionPattern), 2u); ToFriend = FirstDeclMatcher().match(ToTU, FunctionPattern); @@ -2620,9 +2620,9 @@ auto *FromClass = FirstDeclMatcher().match(FromTU, ClassPattern); auto LookupRes = FromClass->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 0u); + ASSERT_TRUE(LookupRes.empty()); LookupRes = FromTU->noload_lookup(FromName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); auto *ToNormal = cast(Import(FromNormal, Lang_CXX03)); auto ToName = ToNormal->getDeclName(); @@ -2630,9 +2630,9 @@ auto *ToClass = FirstDeclMatcher().match(ToTU, ClassPattern); LookupRes = ToClass->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 0u); + EXPECT_TRUE(LookupRes.empty()); LookupRes = ToTU->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); EXPECT_EQ(DeclCounter().match(ToTU, FunctionPattern), 2u); ToNormal = FirstDeclMatcher().match(ToTU, FunctionPattern); @@ -2662,9 +2662,9 @@ ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); auto LookupRes = FromNormalTU->noload_lookup(FromNormalName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); LookupRes = FromFriendTU->noload_lookup(FromFriendName); - ASSERT_EQ(LookupRes.size(), 1u); + ASSERT_TRUE(LookupRes.isSingleResult()); auto *ToNormalF = cast(Import(FromNormalF, Lang_CXX03)); TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); @@ -2672,12 +2672,12 @@ EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); LookupRes = ToTU->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u); auto *ToFriendF = cast(Import(FromFriendF, Lang_CXX03)); LookupRes = ToTU->noload_lookup(ToName); - EXPECT_EQ(LookupRes.size(), 1u); + EXPECT_TRUE(LookupRes.isSingleResult()); EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u); EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); @@ -3999,11 +3999,11 @@ ASSERT_TRUE(L.getAsDecl()); // Simulate the private function DeclContext::reconcileExternalVisibleStorage. - // The point here is to have a Vec with only one element, which is not the - // one we are going to delete from the DC later. + // We do not have a list with one element. L.setHasExternalDecls(); - ASSERT_TRUE(L.getAsVector()); - ASSERT_EQ(1u, L.getAsVector()->size()); + ASSERT_FALSE(L.getAsList()); + auto Results = L.getLookupResult(); + ASSERT_EQ(1u, std::distance(Results.begin(), Results.end())); // This asserts in the old implementation. DC->removeDecl(A0); Index: lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp =================================================================== --- lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -59,7 +59,7 @@ clang::DeclContext::lookup_result result = non_const_interface_decl->lookup(name); - return (result.size() != 0); + return (!result.empty()); } while (false); SetNoExternalVisibleDeclsForName(decl_ctx, name); @@ -555,7 +555,7 @@ if (!lookup_result.empty()) { if (clang::ObjCInterfaceDecl *result_iface_decl = - llvm::dyn_cast(lookup_result[0])) { + llvm::dyn_cast(*lookup_result.begin())) { if (log) { clang::QualType result_iface_type = ast_ctx.getObjCInterfaceType(result_iface_decl); Index: lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -326,7 +326,7 @@ if (result.empty()) return nullptr; - return result[0]; + return *result.begin(); } static bool IsAnonymousNamespaceName(llvm::StringRef name) { Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -265,7 +265,7 @@ clang::DeclContext::lookup_result result = decl_context->lookup(myName); if (!result.empty()) { - clang::NamedDecl *named_decl = result[0]; + clang::NamedDecl *named_decl = *result.begin(); if (const RecordDeclType *record_decl = llvm::dyn_cast(named_decl)) compiler_type.SetCompilerType( Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -163,7 +163,6 @@ if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) if (auto *baseDtorDecl = base_record->getDestructor()) { if (baseDtorDecl->isVirtual()) { - path.Decls = baseDtorDecl; decls.push_back(baseDtorDecl); return true; } else @@ -171,12 +170,11 @@ } // Otherwise, search for name in the base class. - for (path.Decls = base_record->lookup(name); !path.Decls.empty(); - path.Decls = path.Decls.slice(1)) { + for (path.Decls = base_record->lookup(name).begin(); + path.Decls != path.Decls.end(); ++path.Decls) { if (auto *method_decl = - llvm::dyn_cast(path.Decls.front())) + llvm::dyn_cast(*path.Decls)) if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { - path.Decls = method_decl; decls.push_back(method_decl); return true; } @@ -6536,10 +6534,11 @@ if (cxx_record_decl->lookupInBases( [decl_name](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) { - path.Decls = - specifier->getType()->getAsCXXRecordDecl()->lookup( - decl_name); - return !path.Decls.empty(); + CXXRecordDecl *record = + specifier->getType()->getAsCXXRecordDecl(); + auto r = record->lookup(decl_name); + path.Decls = r.begin(); + return !r.empty(); }, paths)) { clang::CXXBasePaths::const_paths_iterator path, @@ -6562,9 +6561,10 @@ ->getDecl()); } } - for (clang::NamedDecl *path_decl : path->Decls) { + for (clang::DeclContext::lookup_iterator I = path->Decls, E; + I != E; ++I) { child_idx = GetIndexForRecordChild( - parent_record_decl, path_decl, omit_empty_base_classes); + parent_record_decl, *I, omit_empty_base_classes); if (child_idx == UINT32_MAX) { child_indexes.clear(); return 0;