diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-02-21 02:31:57 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-02-21 02:31:57 +0000 |
commit | 40c7806451f484436aa0bdfa53254cf41d3427fa (patch) | |
tree | ca4fdda9f83fafa01e86308384294d77a337eeaa /clang/lib | |
parent | 65500d4b29bdd03f6e3d14bd09550465bd9e16ed (diff) | |
download | bcm5719-llvm-40c7806451f484436aa0bdfa53254cf41d3427fa.tar.gz bcm5719-llvm-40c7806451f484436aa0bdfa53254cf41d3427fa.zip |
Revert r167816 and replace it with a proper fix for the issue: do not
invalidate lookup_iterators and lookup_results for some name within a
DeclContext if the lookup results for a *different* name change.
llvm-svn: 230121
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 30 | ||||
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 6 |
4 files changed, 25 insertions, 37 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index b4f1c98f712..30cca6f6b1b 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1297,12 +1297,14 @@ void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) { } } +NamedDecl *const DeclContextLookupResult::SingleElementDummyList = nullptr; + DeclContext::lookup_result -DeclContext::lookup(DeclarationName Name) { +DeclContext::lookup(DeclarationName Name) const { assert(DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"); - DeclContext *PrimaryContext = getPrimaryContext(); + const DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) return PrimaryContext->lookup(Name); @@ -1318,7 +1320,8 @@ DeclContext::lookup(DeclarationName Name) { StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) - Map = buildLookup(); + // FIXME: Make buildLookup const? + Map = const_cast<DeclContext*>(this)->buildLookup(); if (!Map) Map = CreateStoredDeclsMap(getParentASTContext()); @@ -1338,19 +1341,19 @@ DeclContext::lookup(DeclarationName Name) { } } - return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr)); + return lookup_result(); } StoredDeclsMap *Map = LookupPtr.getPointer(); if (LookupPtr.getInt()) - Map = buildLookup(); + Map = const_cast<DeclContext*>(this)->buildLookup(); if (!Map) - return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr)); + return lookup_result(); StoredDeclsMap::iterator I = Map->find(Name); if (I == Map->end()) - return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr)); + return lookup_result(); return I->second.getLookupResult(); } @@ -1387,12 +1390,11 @@ DeclContext::noload_lookup(DeclarationName Name) { } if (!Map) - return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr)); + return lookup_result(); StoredDeclsMap::iterator I = Map->find(Name); return I != Map->end() ? I->second.getLookupResult() - : lookup_result(lookup_iterator(nullptr), - lookup_iterator(nullptr)); + : lookup_result(); } void DeclContext::localUncachedLookup(DeclarationName Name, @@ -1574,15 +1576,17 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) { DeclNameEntries.AddSubsequentDecl(D); } +UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const { + return cast<UsingDirectiveDecl>(*I); +} + /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within /// this context. DeclContext::udir_range DeclContext::using_directives() const { // FIXME: Use something more efficient than normal lookup for using // directives. In C++, using directives are looked up more than anything else. lookup_const_result Result = lookup(UsingDirectiveDecl::getName()); - return udir_range( - reinterpret_cast<UsingDirectiveDecl *const *>(Result.begin()), - reinterpret_cast<UsingDirectiveDecl *const *>(Result.end())); + return udir_range(Result.begin(), Result.end()); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index a796e0b622f..536a1453aaa 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1418,9 +1418,8 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD, return nullptr; } - lookup_const_result Candidates = RD->lookup(getDeclName()); - for (NamedDecl * const * I = Candidates.begin(); I != Candidates.end(); ++I) { - CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*I); + for (auto *ND : RD->lookup(getDeclName())) { + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND); if (!MD) continue; if (recursivelyOverrides(MD, this)) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index c0cf8e0a63a..9eb7700e9ea 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3171,15 +3171,13 @@ static OverloadingResult ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, MultiExprArg Args, OverloadCandidateSet &CandidateSet, - ArrayRef<NamedDecl *> Ctors, + DeclContext::lookup_result Ctors, OverloadCandidateSet::iterator &Best, bool CopyInitializing, bool AllowExplicit, bool OnlyListConstructors, bool IsListInit) { CandidateSet.clear(); - for (ArrayRef<NamedDecl *>::iterator - Con = Ctors.begin(), ConEnd = Ctors.end(); Con != ConEnd; ++Con) { - NamedDecl *D = *Con; + for (NamedDecl *D : Ctors) { DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); bool SuppressUserConversions = false; @@ -3281,11 +3279,7 @@ static void TryConstructorInitialization(Sema &S, // - 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 R = S.LookupConstructors(DestRecordDecl); - // The container holding the constructors can under certain conditions - // be changed while iterating (e.g. because of deserialization). - // To be safe we copy the lookup results to a new container. - SmallVector<NamedDecl*, 16> Ctors(R.begin(), R.end()); + DeclContext::lookup_result Ctors = S.LookupConstructors(DestRecordDecl); OverloadingResult Result = OR_No_Viable_Function; OverloadCandidateSet::iterator Best; @@ -3663,14 +3657,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, // to see if there is a suitable conversion. CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl()); - DeclContext::lookup_result R = S.LookupConstructors(T1RecordDecl); - // The container holding the constructors can under certain conditions - // be changed while iterating (e.g. because of deserialization). - // To be safe we copy the lookup results to a new container. - SmallVector<NamedDecl*, 16> Ctors(R.begin(), R.end()); - for (SmallVectorImpl<NamedDecl *>::iterator - CI = Ctors.begin(), CE = Ctors.end(); CI != CE; ++CI) { - NamedDecl *D = *CI; + for (NamedDecl *D : S.LookupConstructors(T1RecordDecl)) { DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); // Find the constructor (which may be a template). diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 07d5d29e44b..5d508967f25 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3756,16 +3756,14 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *DC, // Add the constructors. if (!ConstructorDecls.empty()) { Generator.insert(ConstructorName, - DeclContext::lookup_result(ConstructorDecls.begin(), - ConstructorDecls.end()), + DeclContext::lookup_result(ConstructorDecls), Trait); } // Add the conversion functions. if (!ConversionDecls.empty()) { Generator.insert(ConversionName, - DeclContext::lookup_result(ConversionDecls.begin(), - ConversionDecls.end()), + DeclContext::lookup_result(ConversionDecls), Trait); } |