r185132 - Lazily deserialize function template specializations. This fixes a cycle in
Richard Smith
richard-llvm at metafoo.co.uk
Thu Jun 27 21:37:54 PDT 2013
Author: rsmith
Date: Thu Jun 27 23:37:53 2013
New Revision: 185132
URL: http://llvm.org/viewvc/llvm-project?rev=185132&view=rev
Log:
Lazily deserialize function template specializations. This fixes a cycle in
module deserialization / merging, and more laziness here is general goodness.
Modified:
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/test/PCH/cxx-templates.cpp
Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=185132&r1=185131&r2=185132&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Thu Jun 27 23:37:53 2013
@@ -743,7 +743,7 @@ protected:
/// \brief Data that is common to all of the declarations of a given
/// function template.
struct Common : CommonBase {
- Common() : InjectedArgs(0) { }
+ Common() : InjectedArgs(), LazySpecializations() { }
/// \brief The function template specializations for this function
/// template, including explicit specializations and instantiations.
@@ -757,6 +757,13 @@ protected:
/// template, and is allocated lazily, since most function templates do not
/// require the use of this information.
TemplateArgument *InjectedArgs;
+
+ /// \brief If non-null, points to an array of specializations known only
+ /// by their external declaration IDs.
+ ///
+ /// The first value in the array is the number of of specializations
+ /// that follow.
+ uint32_t *LazySpecializations;
};
FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
@@ -771,12 +778,13 @@ protected:
friend class FunctionDecl;
+ /// \brief Load any lazily-loaded specializations from the external source.
+ void LoadLazySpecializations() const;
+
/// \brief Retrieve the set of function template specializations of this
/// function template.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
- getSpecializations() const {
- return getCommonPtr()->Specializations;
- }
+ getSpecializations() const;
/// \brief Add a specialization of this function template.
///
@@ -1822,7 +1830,7 @@ protected:
QualType InjectedClassNameType;
/// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known ownly by their external declaration IDs.
+ /// partial specializations) known only by their external declaration IDs.
///
/// The first value in the array is the number of of specializations/
/// partial specializations that follow.
Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=185132&r1=185131&r2=185132&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Thu Jun 27 23:37:53 2013
@@ -245,6 +245,23 @@ FunctionTemplateDecl::newCommon(ASTConte
return CommonPtr;
}
+void FunctionTemplateDecl::LoadLazySpecializations() const {
+ Common *CommonPtr = getCommonPtr();
+ if (CommonPtr->LazySpecializations) {
+ ASTContext &Context = getASTContext();
+ uint32_t *Specs = CommonPtr->LazySpecializations;
+ CommonPtr->LazySpecializations = 0;
+ for (uint32_t I = 0, N = *Specs++; I != N; ++I)
+ (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
+ }
+}
+
+llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
+FunctionTemplateDecl::getSpecializations() const {
+ LoadLazySpecializations();
+ return getCommonPtr()->Specializations;
+}
+
FunctionDecl *
FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
unsigned NumArgs, void *&InsertPos) {
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=185132&r1=185131&r2=185132&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Jun 27 23:37:53 2013
@@ -606,11 +606,16 @@ void ASTDeclReader::VisitFunctionDecl(Fu
FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(),
TemplArgs.size(), C);
void *InsertPos = 0;
- CanonTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+ FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr();
+ CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos);
if (InsertPos)
- CanonTemplate->getSpecializations().InsertNode(FTInfo, InsertPos);
- else
- assert(0 && "Another specialization already inserted!");
+ CommonPtr->Specializations.InsertNode(FTInfo, InsertPos);
+ else {
+ assert(Reader.getContext().getLangOpts().Modules &&
+ "already deserialized this template specialization");
+ // FIXME: This specialization is a redeclaration of one from another
+ // module. Merge it.
+ }
}
break;
}
@@ -1508,12 +1513,17 @@ void ASTDeclReader::VisitFunctionTemplat
if (ThisDeclID == Redecl.getFirstID()) {
// This FunctionTemplateDecl owns a CommonPtr; read it.
- // Read the function specialization declarations.
- // FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled
- // when reading the specialized FunctionDecl.
- unsigned NumSpecs = Record[Idx++];
- while (NumSpecs--)
- (void)ReadDecl(Record, Idx);
+ // Read the function specialization declaration IDs. The specializations
+ // themselves will be loaded if they're needed.
+ if (unsigned NumSpecs = Record[Idx++]) {
+ // FIXME: Append specializations!
+ FunctionTemplateDecl::Common *CommonPtr = D->getCommonPtr();
+ CommonPtr->LazySpecializations = new (Reader.getContext())
+ serialization::DeclID[NumSpecs + 1];
+ CommonPtr->LazySpecializations[0] = NumSpecs;
+ for (unsigned I = 0; I != NumSpecs; ++I)
+ CommonPtr->LazySpecializations[I + 1] = ReadDeclID(Record, Idx);
+ }
}
}
Modified: cfe/trunk/test/PCH/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.cpp?rev=185132&r1=185131&r2=185132&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.cpp (original)
+++ cfe/trunk/test/PCH/cxx-templates.cpp Thu Jun 27 23:37:53 2013
@@ -7,6 +7,11 @@
// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump -o -
// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize | FileCheck %s
+// Test with modules.
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fmodules -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fmodules -include-pch %t -verify %s -ast-dump -o -
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize | FileCheck %s
+
// expected-no-diagnostics
// CHECK: define weak_odr void @_ZN2S4IiE1mEv
More information about the cfe-commits
mailing list