summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-08-30 04:46:40 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-08-30 04:46:40 +0000
commita4ba74c5f50a1f03fdf7ff23b6b1a2380fb58a8c (patch)
treef1811cdd67505f2fddaba0d9386044cd8d2b1f14 /clang/lib
parent8568e576b0e638e94993e437b9dc4b685ae295ae (diff)
downloadbcm5719-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.cpp66
-rw-r--r--clang/lib/Serialization/ASTReader.cpp6
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp4
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);
OpenPOWER on IntegriCloud