diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-11 01:44:51 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-11 01:44:51 +0000 |
commit | 8ce51084b803609393835403d20a40e4952b144f (patch) | |
tree | 0f2703b5dfab2ee927a82241d8743fc6abe735e3 | |
parent | 67375c3bbc878fe77f2cb1ee101c863f9fea188d (diff) | |
download | bcm5719-llvm-8ce51084b803609393835403d20a40e4952b144f.tar.gz bcm5719-llvm-8ce51084b803609393835403d20a40e4952b144f.zip |
[modules] Avoid accidentally completing the redeclaration chain when updating
all the existing declarations of a record-like entity with a pointer to its
definition.
llvm-svn: 231901
-rw-r--r-- | clang/include/clang/Serialization/ASTReader.h | 6 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 4 |
3 files changed, 29 insertions, 15 deletions
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 1037160ab25..951a21016f7 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1159,6 +1159,12 @@ private: void LoadedDecl(unsigned Index, Decl *D); Decl *ReadDeclRecord(serialization::DeclID ID); void markIncompleteDeclChain(Decl *Canon); + + /// \brief Returns the most recent declaration of a declaration (which must be + /// of a redeclarable kind) that is either local or has already been loaded + /// merged into its redecl chain. + Decl *getMostRecentExistingDecl(Decl *D); + RecordLocation DeclCursorForID(serialization::DeclID ID, unsigned &RawLocation); void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7e3a779b076..da5a0e68e93 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -8369,10 +8369,12 @@ void ASTReader::finishPendingActions() { // Make sure that the TagType points at the definition. const_cast<TagType*>(TagT)->decl = TD; } - + if (auto RD = dyn_cast<CXXRecordDecl>(D)) { - for (auto R : RD->redecls()) { - assert((R == D) == R->isThisDeclarationADefinition() && + for (auto *R = getMostRecentExistingDecl(RD); R; + R = R->getPreviousDecl()) { + assert((R == D) == + cast<CXXRecordDecl>(R)->isThisDeclarationADefinition() && "declaration thinks it's the definition but it isn't"); cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData; } @@ -8380,34 +8382,36 @@ void ASTReader::finishPendingActions() { continue; } - + if (auto ID = dyn_cast<ObjCInterfaceDecl>(D)) { // Make sure that the ObjCInterfaceType points at the definition. const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl)) ->Decl = ID; - - for (auto R : ID->redecls()) - R->Data = ID->Data; - + + for (auto *R = getMostRecentExistingDecl(ID); R; R = R->getPreviousDecl()) + cast<ObjCInterfaceDecl>(R)->Data = ID->Data; + continue; } - + if (auto PD = dyn_cast<ObjCProtocolDecl>(D)) { - for (auto R : PD->redecls()) - R->Data = PD->Data; - + for (auto *R = getMostRecentExistingDecl(PD); R; R = R->getPreviousDecl()) + cast<ObjCProtocolDecl>(R)->Data = PD->Data; + continue; } - + auto RTD = cast<RedeclarableTemplateDecl>(D)->getCanonicalDecl(); - for (auto R : RTD->redecls()) - R->Common = RTD->Common; + for (auto *R = getMostRecentExistingDecl(RTD); R; R = R->getPreviousDecl()) + cast<RedeclarableTemplateDecl>(R)->Common = RTD->Common; } PendingDefinitions.clear(); // Load the bodies of any functions or methods we've encountered. We do // this now (delayed) so that we can be sure that the declaration chains // have been fully wired up. + // FIXME: There seems to be no point in delaying this, it does not depend + // on the redecl chains having been wired up. for (PendingBodiesMap::iterator PB = PendingBodies.begin(), PBEnd = PendingBodies.end(); PB != PBEnd; ++PB) { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 0789ba5e3e7..565f33ecba7 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2799,6 +2799,10 @@ Decl *ASTDeclReader::getMostRecentDecl(Decl *D) { llvm_unreachable("unknown decl kind"); } +Decl *ASTReader::getMostRecentExistingDecl(Decl *D) { + return ASTDeclReader::getMostRecentDecl(D->getCanonicalDecl()); +} + template<typename DeclT> void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable<DeclT> *D, |