diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-08-30 04:46:40 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-08-30 04:46:40 +0000 |
commit | a4ba74c5f50a1f03fdf7ff23b6b1a2380fb58a8c (patch) | |
tree | f1811cdd67505f2fddaba0d9386044cd8d2b1f14 /clang/lib | |
parent | 8568e576b0e638e94993e437b9dc4b685ae295ae (diff) | |
download | bcm5719-llvm-a4ba74c5f50a1f03fdf7ff23b6b1a2380fb58a8c.tar.gz bcm5719-llvm-a4ba74c5f50a1f03fdf7ff23b6b1a2380fb58a8c.zip |
Don't eagerly load all conversion operators when loading a class declaration
from a PCH/module.
llvm-svn: 189646
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 66 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 4 |
3 files changed, 46 insertions, 30 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index ccd8220a684..4d963cf4b3c 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -35,6 +35,17 @@ AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (Mem) AccessSpecDecl(EmptyShell()); } +void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { + ExternalASTSource *Source = C.getExternalSource(); + assert(Impl.Decls.isLazy() && "getFromExternalSource for non-lazy set"); + assert(Source && "getFromExternalSource with no external source"); + + for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I) + I.setDecl(cast<NamedDecl>(Source->GetExternalDecl( + reinterpret_cast<uintptr_t>(I.getDecl()) >> 2))); + Impl.Decls.setLazy(false); +} + CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0), Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), @@ -552,18 +563,16 @@ void CXXRecordDecl::addedMember(Decl *D) { if (Conversion->getPrimaryTemplate()) { // We don't record specializations. - } else if (FunTmpl) { - if (FunTmpl->getPreviousDecl()) - data().Conversions.replace(FunTmpl->getPreviousDecl(), - FunTmpl, AS); - else - data().Conversions.addDecl(getASTContext(), FunTmpl, AS); } else { - if (Conversion->getPreviousDecl()) - data().Conversions.replace(Conversion->getPreviousDecl(), - Conversion, AS); + ASTContext &Ctx = getASTContext(); + ASTUnresolvedSet &Conversions = data().Conversions.get(Ctx); + NamedDecl *Primary = + FunTmpl ? cast<NamedDecl>(FunTmpl) : cast<NamedDecl>(Conversion); + if (Primary->getPreviousDecl()) + Conversions.replace(cast<NamedDecl>(Primary->getPreviousDecl()), + Primary, AS); else - data().Conversions.addDecl(getASTContext(), Conversion, AS); + Conversions.addDecl(Ctx, Primary, AS); } } @@ -880,10 +889,13 @@ void CXXRecordDecl::addedMember(Decl *D) { } // Handle using declarations of conversion functions. - if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D)) + if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D)) { if (Shadow->getDeclName().getNameKind() - == DeclarationName::CXXConversionFunctionName) - data().Conversions.addDecl(getASTContext(), Shadow, Shadow->getAccess()); + == DeclarationName::CXXConversionFunctionName) { + ASTContext &Ctx = getASTContext(); + data().Conversions.get(Ctx).addDecl(Ctx, Shadow, Shadow->getAccess()); + } + } } void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) { @@ -1083,16 +1095,21 @@ static void CollectVisibleConversions(ASTContext &Context, /// in current class; including conversion function templates. std::pair<CXXRecordDecl::conversion_iterator,CXXRecordDecl::conversion_iterator> CXXRecordDecl::getVisibleConversionFunctions() { - // If root class, all conversions are visible. - if (bases_begin() == bases_end()) - return std::make_pair(data().Conversions.begin(), data().Conversions.end()); - // If visible conversion list is already evaluated, return it. - if (!data().ComputedVisibleConversions) { - CollectVisibleConversions(getASTContext(), this, data().VisibleConversions); - data().ComputedVisibleConversions = true; + ASTContext &Ctx = getASTContext(); + + ASTUnresolvedSet *Set; + if (bases_begin() == bases_end()) { + // If root class, all conversions are visible. + Set = &data().Conversions.get(Ctx); + } else { + Set = &data().VisibleConversions.get(Ctx); + // If visible conversion list is not evaluated, evaluate it. + if (!data().ComputedVisibleConversions) { + CollectVisibleConversions(Ctx, this, *Set); + data().ComputedVisibleConversions = true; + } } - return std::make_pair(data().VisibleConversions.begin(), - data().VisibleConversions.end()); + return std::make_pair(Set->begin(), Set->end()); } void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { @@ -1107,7 +1124,7 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { // with sufficiently large numbers of directly-declared conversions // that asymptotic behavior matters. - ASTUnresolvedSet &Convs = data().Conversions; + ASTUnresolvedSet &Convs = data().Conversions.get(getASTContext()); for (unsigned I = 0, E = Convs.size(); I != E; ++I) { if (Convs[I].getDecl() == ConvDecl) { Convs.erase(I); @@ -1233,8 +1250,7 @@ void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) { } // Set access bits correctly on the directly-declared conversions. - for (UnresolvedSetIterator I = data().Conversions.begin(), - E = data().Conversions.end(); + for (conversion_iterator I = conversion_begin(), E = conversion_end(); I != E; ++I) I.setAccess((*I)->getAccess()); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 6a2db82c436..5b55390730d 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6972,14 +6972,14 @@ ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, } /// \brief Read a UnresolvedSet structure. -void ASTReader::ReadUnresolvedSet(ModuleFile &F, ASTUnresolvedSet &Set, +void ASTReader::ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set, const RecordData &Record, unsigned &Idx) { unsigned NumDecls = Record[Idx++]; Set.reserve(Context, NumDecls); while (NumDecls--) { - NamedDecl *D = ReadDeclAs<NamedDecl>(F, Record, Idx); + DeclID ID = ReadDeclID(F, Record, Idx); AccessSpecifier AS = (AccessSpecifier)Record[Idx++]; - Set.addDecl(Context, D, AS); + Set.addLazyDecl(Context, ID, AS); } } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 7f1bd9b882e..f8e8b5d7ada 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5117,8 +5117,8 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec AddCXXBaseSpecifiersRef(Data.getVBases(), Data.getVBases() + Data.NumVBases, Record); - AddUnresolvedSet(Data.Conversions, Record); - AddUnresolvedSet(Data.VisibleConversions, Record); + AddUnresolvedSet(Data.Conversions.get(*Context), Record); + AddUnresolvedSet(Data.VisibleConversions.get(*Context), Record); // Data.Definition is the owning decl, no need to write it. AddDeclRef(D->getFirstFriend(), Record); |