Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -3984,7 +3984,8 @@ LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc = SourceLocation()); - DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); + void LookupConstructors(CXXRecordDecl *Class, + llvm::SmallVectorImpl &Constructors); CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class); CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class, unsigned Quals); Index: clang/lib/Sema/SemaCodeComplete.cpp =================================================================== --- clang/lib/Sema/SemaCodeComplete.cpp +++ clang/lib/Sema/SemaCodeComplete.cpp @@ -5685,7 +5685,9 @@ OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); - for (NamedDecl *C : LookupConstructors(RD)) { + llvm::SmallVector Ctors; + LookupConstructors(RD, Ctors); + for (NamedDecl *C : Ctors) { if (auto *FD = dyn_cast(C)) { AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args, CandidateSet, Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -12106,7 +12106,9 @@ UsingName.setName(Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(Context.getRecordType(CurClass)))); UsingName.setNamedTypeInfo(nullptr); - for (auto *Ctor : LookupConstructors(RD)) + llvm::SmallVector Ctors; + LookupConstructors(RD, Ctors); + for (auto *Ctor : Ctors) R.addDecl(Ctor); R.resolveKind(); } else { Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -5001,7 +5001,9 @@ bool FoundConstructor = false; unsigned FoundTQs; - for (const auto *ND : Self.LookupConstructors(RD)) { + llvm::SmallVector Ctors; + Self.LookupConstructors(RD, Ctors); + for (const auto *ND : Ctors) { // A template constructor is never a copy constructor. // FIXME: However, it may actually be selected at the actual overload // resolution point. @@ -5041,7 +5043,9 @@ return true; bool FoundConstructor = false; - for (const auto *ND : Self.LookupConstructors(RD)) { + llvm::SmallVector Ctors; + Self.LookupConstructors(RD, Ctors); + for (const auto *ND : Ctors) { // FIXME: In C++0x, a constructor template can be a default constructor. if (isa(ND->getUnderlyingDecl())) continue; Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -3890,7 +3890,7 @@ MultiExprArg Args, OverloadCandidateSet &CandidateSet, QualType DestType, - DeclContext::lookup_result Ctors, + const llvm::SmallVectorImpl& Ctors, OverloadCandidateSet::iterator &Best, bool CopyInitializing, bool AllowExplicit, bool OnlyListConstructors, bool IsListInit, @@ -4065,7 +4065,8 @@ // - Otherwise, if T is a class type, constructors are considered. The // applicable constructors are enumerated, and the best one is chosen // through overload resolution. - DeclContext::lookup_result Ctors = S.LookupConstructors(DestRecordDecl); + llvm::SmallVector Ctors; + S.LookupConstructors(DestRecordDecl, Ctors); OverloadingResult Result = OR_No_Viable_Function; OverloadCandidateSet::iterator Best; @@ -4514,7 +4515,9 @@ // to see if there is a suitable conversion. CXXRecordDecl *T1RecordDecl = cast(T1RecordType->getDecl()); - for (NamedDecl *D : S.LookupConstructors(T1RecordDecl)) { + llvm::SmallVector Ctors; + S.LookupConstructors(T1RecordDecl, Ctors); + for (NamedDecl *D : Ctors) { auto Info = getConstructorInfo(D); if (!Info.Constructor) continue; @@ -5183,7 +5186,9 @@ // Try to complete the type we're converting to. if (S.isCompleteType(Kind.getLocation(), DestType)) { - for (NamedDecl *D : S.LookupConstructors(DestRecordDecl)) { + llvm::SmallVector Ctors; + S.LookupConstructors(DestRecordDecl, Ctors); + for (NamedDecl *D : Ctors) { auto Info = getConstructorInfo(D); if (!Info.Constructor) continue; @@ -6175,7 +6180,8 @@ // C++11 [dcl.init]p16, second bullet for class types, this initialization // is direct-initialization. OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); - DeclContext::lookup_result Ctors = S.LookupConstructors(Class); + llvm::SmallVector Ctors; + S.LookupConstructors(Class, Ctors); OverloadCandidateSet::iterator Best; switch (ResolveConstructorOverload( @@ -6317,8 +6323,8 @@ // Find constructors which would have been considered. OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); - DeclContext::lookup_result Ctors = - S.LookupConstructors(cast(Record->getDecl())); + llvm::SmallVector Ctors; + S.LookupConstructors(cast(Record->getDecl()), Ctors); // Perform overload resolution. OverloadCandidateSet::iterator Best; Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -3264,7 +3264,8 @@ } /// Look up the constructors for the given class. -DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { +void Sema::LookupConstructors(CXXRecordDecl *Class, + llvm::SmallVectorImpl &Constructors) { // If the implicit constructors have not yet been declared, do so now. if (CanDeclareSpecialMemberFunction(Class)) { runWithSufficientStackSpace(Class->getLocation(), [&] { @@ -3279,7 +3280,10 @@ CanQualType T = Context.getCanonicalType(Context.getTypeDeclType(Class)); DeclarationName Name = Context.DeclarationNames.getCXXConstructorName(T); - return Class->lookup(Name); + // Working directly on R might trigger a deserialization, invalidating R if + // the underlying data structure needs to reallocate the storage. + DeclContext::lookup_result R = Class->lookup(Name); + Constructors.append(R.begin(), R.end()); } /// Look up the copying assignment operator for the given class. @@ -3543,7 +3547,10 @@ // namespaces even if they are not visible during an ordinary // lookup (11.4). DeclContext::lookup_result R = NS->lookup(Name); - for (auto *D : R) { + // The loop might trigger a deserialization, invalidating R if the + // underlying data structure needs to reallocate the storage. + llvm::SmallVector RCopy(R.begin(), R.end()); + for (auto *D : RCopy) { auto *Underlying = D; if (auto *USD = dyn_cast(D)) Underlying = USD->getTargetDecl(); Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -3337,7 +3337,9 @@ OverloadCandidateSet &CandidateSet, bool AllowExplicit) { CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); - for (auto *D : S.LookupConstructors(To)) { + llvm::SmallVector Ctors; + S.LookupConstructors(To, Ctors); + for (auto *D : Ctors) { auto Info = getConstructorInfo(D); if (!Info) continue; @@ -3461,7 +3463,9 @@ ListInitializing = true; } - for (auto *D : S.LookupConstructors(ToRecordDecl)) { + llvm::SmallVector Ctors; + S.LookupConstructors(ToRecordDecl, Ctors); + for (auto *D : Ctors) { auto Info = getConstructorInfo(D); if (!Info) continue; Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -2480,7 +2480,9 @@ // for which some class template parameter without a default argument never // appears in a deduced context). bool AddedAny = false; - for (NamedDecl *D : LookupConstructors(Transform.Primary)) { + llvm::SmallVector Ctors; + LookupConstructors(Transform.Primary, Ctors); + for (NamedDecl *D : Ctors) { D = D->getUnderlyingDecl(); if (D->isInvalidDecl() || D->isImplicit()) continue;