@@ -10671,6 +10671,70 @@ void ASTReader::finishPendingActions() {
1067110671
1067210672 // Inform any classes that had members added that they now have more members.
1067310673 for (auto [RD, MD] : PendingAddedClassMembers) {
10674+ // The module we just imported added MD to RD so we should do the same, but
10675+ // only RD doesn't already contain the same member. This can happen when two
10676+ // modules independent add and serialize the same implicit member.
10677+
10678+ // Fast path: we can check for the presence of implicit special members
10679+ // (default/copy/move constructors + copy/move assignments + destructors)
10680+ // with RD's needsImplicit*() methods (which are constant time).
10681+ if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
10682+ if (!Ctor->isInheritingConstructor ()) {
10683+ if (Ctor->isDefaultConstructor ()) {
10684+ if (RD->needsImplicitDefaultConstructor ())
10685+ RD->addHiddenDecl (MD);
10686+ continue ;
10687+ }
10688+ if (Ctor->isCopyConstructor ()) {
10689+ if (RD->needsImplicitCopyConstructor ())
10690+ RD->addHiddenDecl (MD);
10691+ continue ;
10692+ }
10693+ if (Ctor->isMoveConstructor ()) {
10694+ if (RD->needsImplicitMoveConstructor ())
10695+ RD->addHiddenDecl (MD);
10696+ continue ;
10697+ }
10698+ }
10699+ } else if (const auto *Mthd = dyn_cast<CXXMethodDecl>(MD)) {
10700+ if (isa<CXXDestructorDecl>(Mthd)) {
10701+ if (RD->needsImplicitDestructor ())
10702+ RD->addHiddenDecl (MD);
10703+ continue ;
10704+ }
10705+ if (Mthd->isCopyAssignmentOperator ()) {
10706+ if (RD->needsImplicitCopyAssignment ())
10707+ RD->addHiddenDecl (MD);
10708+ continue ;
10709+ }
10710+ if (Mthd->isMoveAssignmentOperator ()) {
10711+ if (RD->needsImplicitMoveAssignment ())
10712+ RD->addHiddenDecl (MD);
10713+ continue ;
10714+ }
10715+ }
10716+
10717+ if (auto *FD = dyn_cast<FunctionDecl>(MD)) {
10718+ // Slow path: this is some other implicit added member (e.g., inherited
10719+ // constructor). We need iterate through all of RD's members and compare
10720+ // their ODR hash against MD's.
10721+ auto needToAddMD = true ;
10722+ for (auto *RDD : RD->noload_decls ()) {
10723+ if (auto *RDFD = dyn_cast<FunctionDecl>(RDD)) {
10724+ if (FD->getODRHash () == RDFD->getODRHash ()) {
10725+ needToAddMD = false ;
10726+ break ;
10727+ }
10728+ }
10729+ }
10730+ if (needToAddMD)
10731+ RD->addHiddenDecl (MD);
10732+ continue ;
10733+ }
10734+
10735+ // This branch is only reachable if MD is not a function decl (which means
10736+ // it doesn't have an ODR hash to compare). Call addedMember() to preserve
10737+ // historical behavior.
1067410738 RD->addedMember (MD);
1067510739 }
1067610740 PendingAddedClassMembers.clear ();
0 commit comments