[cfe-commits] r113391 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclTemplate.h lib/AST/Decl.cpp lib/AST/DeclTemplate.cpp lib/AST/TemplateName.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Wed Sep 8 12:31:22 PDT 2010
Author: akirtzidis
Date: Wed Sep 8 14:31:22 2010
New Revision: 113391
URL: http://llvm.org/viewvc/llvm-project?rev=113391&view=rev
Log:
Fix C++ PCH issues.
PCH got a severe beating by the boost-using test case reported here: http://llvm.org/PR8099
Fix issues like:
-When PCH reading, make sure Decl's getASTContext() doesn't get called since a Decl in the parent hierarchy may be initializing.
-In ASTDeclReader::VisitFunctionDecl VisitRedeclarable should be called before using FunctionDecl's isCanonicalDecl()
-In ASTDeclReader::VisitRedeclarableTemplateDecl CommonOrPrev must be initialized before anything else.
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/AST/TemplateName.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Sep 8 14:31:22 2010
@@ -1136,6 +1136,42 @@
/// declaration name embedded in the DeclaratorDecl base class.
DeclarationNameLoc DNLoc;
+ /// \brief Specify that this function declaration is actually a function
+ /// template specialization.
+ ///
+ /// \param C the ASTContext.
+ ///
+ /// \param Template the function template that this function template
+ /// specialization specializes.
+ ///
+ /// \param TemplateArgs the template arguments that produced this
+ /// function template specialization from the template.
+ ///
+ /// \param InsertPos If non-NULL, the position in the function template
+ /// specialization set where the function template specialization data will
+ /// be inserted.
+ ///
+ /// \param TSK the kind of template specialization this is.
+ ///
+ /// \param TemplateArgsAsWritten location info of template arguments.
+ ///
+ /// \param PointOfInstantiation point at which the function template
+ /// specialization was first instantiated.
+ void setFunctionTemplateSpecialization(ASTContext &C,
+ FunctionTemplateDecl *Template,
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos,
+ TemplateSpecializationKind TSK,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten,
+ SourceLocation PointOfInstantiation);
+
+ /// \brief Specify that this record is an instantiation of the
+ /// member function FD.
+ void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
+ TemplateSpecializationKind TSK);
+
+ void setParams(ASTContext &C, ParmVarDecl **NewParamInfo, unsigned NumParams);
+
protected:
FunctionDecl(Kind DK, DeclContext *DC, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
@@ -1343,7 +1379,9 @@
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
- void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+ void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
+ setParams(getASTContext(), NewParamInfo, NumParams);
+ }
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
@@ -1432,7 +1470,9 @@
/// \brief Specify that this record is an instantiation of the
/// member function FD.
void setInstantiationOfMemberFunction(FunctionDecl *FD,
- TemplateSpecializationKind TSK);
+ TemplateSpecializationKind TSK) {
+ setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
+ }
/// \brief Retrieves the function template that is described by this
/// function declaration.
@@ -1526,43 +1566,11 @@
void *InsertPos,
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
const TemplateArgumentListInfo *TemplateArgsAsWritten = 0,
- SourceLocation PointOfInstantiation = SourceLocation());
-
- /// \brief Specify that this function declaration is actually a function
- /// template specialization.
- ///
- /// \param Template the function template that this function template
- /// specialization specializes.
- ///
- /// \param NumTemplateArgs number of template arguments that produced this
- /// function template specialization from the template.
- ///
- /// \param TemplateArgs array of template arguments that produced this
- /// function template specialization from the template.
- ///
- /// \param TSK the kind of template specialization this is.
- ///
- /// \param NumTemplateArgsAsWritten number of template arguments that produced
- /// this function template specialization from the template.
- ///
- /// \param TemplateArgsAsWritten array of location info for the template
- /// arguments.
- ///
- /// \param LAngleLoc location of left angle token.
- ///
- /// \param RAngleLoc location of right angle token.
- ///
- /// \param PointOfInstantiation point at which the function template
- /// specialization was first instantiated.
- void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
- unsigned NumTemplateArgs,
- const TemplateArgument *TemplateArgs,
- TemplateSpecializationKind TSK,
- unsigned NumTemplateArgsAsWritten,
- TemplateArgumentLoc *TemplateArgsAsWritten,
- SourceLocation LAngleLoc,
- SourceLocation RAngleLoc,
- SourceLocation PointOfInstantiation);
+ SourceLocation PointOfInstantiation = SourceLocation()) {
+ setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
+ InsertPos, TSK, TemplateArgsAsWritten,
+ PointOfInstantiation);
+ }
/// \brief Specifies that this function declaration is actually a
/// dependent function template specialization.
Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Wed Sep 8 14:31:22 2010
@@ -584,7 +584,7 @@
/// for the common pointer.
CommonBase *getCommonPtr();
- virtual CommonBase *newCommon() = 0;
+ virtual CommonBase *newCommon(ASTContext &C) = 0;
// Construct a template decl with name, parameters, and templated element.
RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -789,19 +789,13 @@
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
- CommonBase *newCommon();
+ CommonBase *newCommon(ASTContext &C);
Common *getCommonPtr() {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
- friend void FunctionDecl::setFunctionTemplateSpecialization(
- FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation PointOfInstantiation);
+ friend class FunctionDecl;
/// \brief Retrieve the set of function template specializations of this
/// function template.
@@ -1659,7 +1653,7 @@
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
- CommonBase *newCommon();
+ CommonBase *newCommon(ASTContext &C);
Common *getCommonPtr() {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Sep 8 14:31:22 2010
@@ -1093,13 +1093,14 @@
}
-void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
+void FunctionDecl::setParams(ASTContext &C,
+ ParmVarDecl **NewParamInfo, unsigned NumParams) {
assert(ParamInfo == 0 && "Already has param info!");
assert(NumParams == getNumParams() && "Parameter count mismatch!");
// Zero params -> null pointer.
if (NumParams) {
- void *Mem = getASTContext().Allocate(sizeof(ParmVarDecl*)*NumParams);
+ void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams);
ParamInfo = new (Mem) ParmVarDecl*[NumParams];
memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
@@ -1271,12 +1272,13 @@
}
void
-FunctionDecl::setInstantiationOfMemberFunction(FunctionDecl *FD,
+FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C,
+ FunctionDecl *FD,
TemplateSpecializationKind TSK) {
assert(TemplateOrSpecialization.isNull() &&
"Member function is already a specialization");
MemberSpecializationInfo *Info
- = new (getASTContext()) MemberSpecializationInfo(FD, TSK);
+ = new (C) MemberSpecializationInfo(FD, TSK);
TemplateOrSpecialization = Info;
}
@@ -1362,7 +1364,8 @@
}
void
-FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C,
+ FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
TemplateSpecializationKind TSK,
@@ -1373,7 +1376,7 @@
FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
if (!Info)
- Info = new (getASTContext()) FunctionTemplateSpecializationInfo;
+ Info = new (C) FunctionTemplateSpecializationInfo;
Info->Function = this;
Info->Template.setPointer(Template);
@@ -1401,28 +1404,6 @@
}
void
-FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
- unsigned NumTemplateArgs,
- const TemplateArgument *TemplateArgs,
- TemplateSpecializationKind TSK,
- unsigned NumTemplateArgsAsWritten,
- TemplateArgumentLoc *TemplateArgsAsWritten,
- SourceLocation LAngleLoc,
- SourceLocation RAngleLoc,
- SourceLocation PointOfInstantiation) {
- ASTContext &Ctx = getASTContext();
- TemplateArgumentList *TemplArgs
- = new (Ctx) TemplateArgumentList(Ctx, TemplateArgs, NumTemplateArgs);
- TemplateArgumentListInfo *TemplArgsInfo
- = new (Ctx) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
- for (unsigned i=0; i != NumTemplateArgsAsWritten; ++i)
- TemplArgsInfo->addArgument(TemplateArgsAsWritten[i]);
-
- setFunctionTemplateSpecialization(Template, TemplArgs, /*InsertPos=*/0, TSK,
- TemplArgsInfo, PointOfInstantiation);
-}
-
-void
FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context,
const UnresolvedSetImpl &Templates,
const TemplateArgumentListInfo &TemplateArgs) {
Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Wed Sep 8 14:31:22 2010
@@ -92,7 +92,7 @@
RedeclarableTemplateDecl *First = getCanonicalDecl();
if (First->CommonOrPrev.isNull()) {
- CommonBase *CommonPtr = First->newCommon();
+ CommonBase *CommonPtr = First->newCommon(getASTContext());
First->CommonOrPrev = CommonPtr;
CommonPtr->Latest = First;
}
@@ -156,9 +156,10 @@
return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
}
-RedeclarableTemplateDecl::CommonBase *FunctionTemplateDecl::newCommon() {
- Common *CommonPtr = new (getASTContext()) Common;
- getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+RedeclarableTemplateDecl::CommonBase *
+FunctionTemplateDecl::newCommon(ASTContext &C) {
+ Common *CommonPtr = new (C) Common;
+ C.AddDeallocation(DeallocateCommon, CommonPtr);
return CommonPtr;
}
@@ -188,9 +189,10 @@
return New;
}
-RedeclarableTemplateDecl::CommonBase *ClassTemplateDecl::newCommon() {
- Common *CommonPtr = new (getASTContext()) Common;
- getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+RedeclarableTemplateDecl::CommonBase *
+ClassTemplateDecl::newCommon(ASTContext &C) {
+ Common *CommonPtr = new (C) Common;
+ C.AddDeallocation(DeallocateCommon, CommonPtr);
return CommonPtr;
}
Modified: cfe/trunk/lib/AST/TemplateName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateName.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateName.cpp (original)
+++ cfe/trunk/lib/AST/TemplateName.cpp Wed Sep 8 14:31:22 2010
@@ -44,8 +44,14 @@
bool TemplateName::isDependent() const {
if (TemplateDecl *Template = getAsTemplateDecl()) {
- return isa<TemplateTemplateParmDecl>(Template) ||
- Template->getDeclContext()->isDependentContext();
+ if (isa<TemplateTemplateParmDecl>(Template))
+ return true;
+ // FIXME: Hack, getDeclContext() can be null if Template is still
+ // initializing due to PCH reading, so we check it before using it.
+ // Should probably modify TemplateSpecializationType to allow constructing
+ // it without the isDependent() checking.
+ return Template->getDeclContext() &&
+ Template->getDeclContext()->isDependentContext();
}
assert(!getAsOverloadedTemplate() &&
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Sep 8 14:31:22 2010
@@ -183,8 +183,8 @@
void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
VisitTypeDecl(TD);
- TD->IdentifierNamespace = Record[Idx++];
VisitRedeclarable(TD);
+ TD->IdentifierNamespace = Record[Idx++];
TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
TD->setDefinition(Record[Idx++]);
TD->setEmbeddedInDeclarator(Record[Idx++]);
@@ -234,6 +234,7 @@
void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
VisitDeclaratorDecl(FD);
+ VisitRedeclarable(FD);
// FIXME: read DeclarationNameLoc.
FD->IdentifierNamespace = Record[Idx++];
@@ -250,7 +251,7 @@
FunctionDecl *InstFD = cast<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
- FD->setInstantiationOfMemberFunction(InstFD, TSK);
+ FD->setInstantiationOfMemberFunction(*Reader.getContext(), InstFD, TSK);
FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
break;
}
@@ -279,12 +280,26 @@
SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
- if (FD->isCanonicalDecl()) // if canonical add to template's set.
- FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(),
- TemplArgs.data(), TSK,
- TemplArgLocs.size(),
- TemplArgLocs.data(),
- LAngleLoc, RAngleLoc, POI);
+ if (FD->isCanonicalDecl()) { // if canonical add to template's set.
+ ASTContext &C = *Reader.getContext();
+ TemplateArgumentList *TemplArgList
+ = new (C) TemplateArgumentList(C, TemplArgs.data(), TemplArgs.size());
+ TemplateArgumentListInfo *TemplArgsInfo
+ = new (C) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
+ for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i)
+ TemplArgsInfo->addArgument(TemplArgLocs[i]);
+
+ llvm::FoldingSetNodeID ID;
+ FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(),
+ TemplArgs.size(), C);
+ void *InsertPos = 0;
+ FunctionTemplateSpecializationInfo *PrevFTInfo =
+ Template->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+ (void)PrevFTInfo;
+ assert(!PrevFTInfo && "Another specialization already inserted!");
+ FD->setFunctionTemplateSpecialization(C, Template, TemplArgList, InsertPos,
+ TSK, TemplArgsInfo, POI);
+ }
break;
}
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
@@ -311,7 +326,6 @@
// FunctionDecl's body is handled last at ASTDeclReader::Visit,
// after everything else is read.
- VisitRedeclarable(FD);
FD->setStorageClass((StorageClass)Record[Idx++]);
FD->setStorageClassAsWritten((StorageClass)Record[Idx++]);
FD->setInlineSpecified(Record[Idx++]);
@@ -331,7 +345,7 @@
Params.reserve(NumParams);
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- FD->setParams(Params.data(), NumParams);
+ FD->setParams(*Reader.getContext(), Params.data(), NumParams);
}
void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
@@ -567,13 +581,13 @@
void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
VisitDeclaratorDecl(VD);
+ VisitRedeclarable(VD);
VD->setStorageClass((StorageClass)Record[Idx++]);
VD->setStorageClassAsWritten((StorageClass)Record[Idx++]);
VD->setThreadSpecified(Record[Idx++]);
VD->setCXXDirectInitializer(Record[Idx++]);
VD->setExceptionVariable(Record[Idx++]);
VD->setNRVOVariable(Record[Idx++]);
- VisitRedeclarable(VD);
if (Record[Idx++])
VD->setInit(Reader.ReadExpr(Cursor));
@@ -864,9 +878,10 @@
}
void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
- VisitTemplateDecl(D);
+ // Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr()
+ // can be used while this is still initializing.
- D->IdentifierNamespace = Record[Idx++];
+ assert(D->CommonOrPrev.isNull() && "getCommonPtr was called earlier on this");
RedeclarableTemplateDecl *PrevDecl =
cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]));
assert((PrevDecl == 0 || PrevDecl->getKind() == D->getKind()) &&
@@ -874,6 +889,7 @@
if (PrevDecl)
D->CommonOrPrev = PrevDecl;
if (PrevDecl == 0) {
+ D->CommonOrPrev = D->newCommon(*Reader.getContext());
if (RedeclarableTemplateDecl *RTD
= cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
assert(RTD->getKind() == D->getKind() &&
@@ -907,6 +923,9 @@
assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch");
D->getCommonPtr()->Latest = LatestDecl;
}
+
+ VisitTemplateDecl(D);
+ D->IdentifierNamespace = Record[Idx++];
}
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Sep 8 14:31:22 2010
@@ -163,8 +163,8 @@
void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
VisitTypeDecl(D);
- Record.push_back(D->getIdentifierNamespace());
VisitRedeclarable(D);
+ Record.push_back(D->getIdentifierNamespace());
Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
Record.push_back(D->isDefinition());
Record.push_back(D->isEmbeddedInDeclarator());
@@ -214,6 +214,7 @@
void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
VisitDeclaratorDecl(D);
+ VisitRedeclarable(D);
// FIXME: write DeclarationNameLoc.
Record.push_back(D->getIdentifierNamespace());
@@ -281,7 +282,6 @@
// FunctionDecl's body is handled last at ASTWriterDecl::Visit,
// after everything else is written.
- VisitRedeclarable(D);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Record.push_back(D->getStorageClassAsWritten());
Record.push_back(D->isInlineSpecified());
@@ -513,13 +513,13 @@
void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
VisitDeclaratorDecl(D);
+ VisitRedeclarable(D);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Record.push_back(D->getStorageClassAsWritten());
Record.push_back(D->isThreadSpecified());
Record.push_back(D->hasCXXDirectInitializer());
Record.push_back(D->isExceptionVariable());
Record.push_back(D->isNRVOVariable());
- VisitRedeclarable(D);
Record.push_back(D->getInit() ? 1 : 0);
if (D->getInit())
Writer.AddStmt(D->getInit());
@@ -840,9 +840,9 @@
}
void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
- VisitTemplateDecl(D);
+ // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
+ // getCommonPtr() can be used while this is still initializing.
- Record.push_back(D->getIdentifierNamespace());
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
if (D->getPreviousDeclaration() == 0) {
// This TemplateDecl owns the CommonPtr; write it.
@@ -866,6 +866,9 @@
Writer.FirstLatestDecls[First] = D;
}
}
+
+ VisitTemplateDecl(D);
+ Record.push_back(D->getIdentifierNamespace());
}
void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
More information about the cfe-commits
mailing list