summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-03-11 01:44:51 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-03-11 01:44:51 +0000
commit8ce51084b803609393835403d20a40e4952b144f (patch)
tree0f2703b5dfab2ee927a82241d8743fc6abe735e3
parent67375c3bbc878fe77f2cb1ee101c863f9fea188d (diff)
downloadbcm5719-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.h6
-rw-r--r--clang/lib/Serialization/ASTReader.cpp34
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp4
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,
OpenPOWER on IntegriCloud