diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-09-08 19:31:22 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-09-08 19:31:22 +0000 |
commit | f4bc0d87ee733daf490defee742a07feef295234 (patch) | |
tree | 4180d712815b49cea7da00f2e6c5a70dee5b14b1 /clang/lib | |
parent | d79bb127ddd8fd988e3bdfb9fc20d58f663779b6 (diff) | |
download | bcm5719-llvm-f4bc0d87ee733daf490defee742a07feef295234.tar.gz bcm5719-llvm-f4bc0d87ee733daf490defee742a07feef295234.zip |
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.
llvm-svn: 113391
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 37 | ||||
-rw-r--r-- | clang/lib/AST/DeclTemplate.cpp | 16 | ||||
-rw-r--r-- | clang/lib/AST/TemplateName.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 45 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 13 |
5 files changed, 66 insertions, 55 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index b7be02d7453..b2beb131c55 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1093,13 +1093,14 @@ unsigned FunctionDecl::getNumParams() const { } -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 @@ MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const { } 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 @@ FunctionDecl::getTemplateSpecializationArgsAsWritten() const { } void -FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, +FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C, + FunctionTemplateDecl *Template, const TemplateArgumentList *TemplateArgs, void *InsertPos, TemplateSpecializationKind TSK, @@ -1373,7 +1376,7 @@ FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, 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 @@ FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, } 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) { diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index e69338a7730..66321d3ec24 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -92,7 +92,7 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() { 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 @@ FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 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 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 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; } diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index ef7b315314d..439f4e81ade 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -44,8 +44,14 @@ TemplateDecl *TemplateName::getAsTemplateDecl() const { 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() && diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7adbe1220ff..653878209fc 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -183,8 +183,8 @@ void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) { 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::VisitDeclaratorDecl(DeclaratorDecl *DD) { void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { VisitDeclaratorDecl(FD); + VisitRedeclarable(FD); // FIXME: read DeclarationNameLoc. FD->IdentifierNamespace = Record[Idx++]; @@ -250,7 +251,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { 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 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { 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 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { // 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 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { 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::VisitFieldDecl(FieldDecl *FD) { 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::VisitTemplateDecl(TemplateDecl *D) { } 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 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { 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 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch"); D->getCommonPtr()->Latest = LatestDecl; } + + VisitTemplateDecl(D); + D->IdentifierNamespace = Record[Idx++]; } void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index ce39a1076b8..a615c0f9c22 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -163,8 +163,8 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { 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::VisitDeclaratorDecl(DeclaratorDecl *D) { void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { VisitDeclaratorDecl(D); + VisitRedeclarable(D); // FIXME: write DeclarationNameLoc. Record.push_back(D->getIdentifierNamespace()); @@ -281,7 +282,6 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { // 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::VisitFieldDecl(FieldDecl *D) { 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::VisitTemplateDecl(TemplateDecl *D) { } 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 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { Writer.FirstLatestDecls[First] = D; } } + + VisitTemplateDecl(D); + Record.push_back(D->getIdentifierNamespace()); } void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { |