@@ -4079,22 +4079,34 @@ struct FriendCountAndPosition {
4079
4079
unsigned int IndexOfDecl;
4080
4080
};
4081
4081
4082
- template <class T >
4083
- static FriendCountAndPosition getFriendCountAndPosition (
4084
- const FriendDecl *FD,
4085
- llvm::function_ref<T(const FriendDecl *)> GetCanTypeOrDecl) {
4082
+ static bool IsEquivalentFriend (ASTImporter &Importer, FriendDecl *FD1,
4083
+ FriendDecl *FD2) {
4084
+ if ((!FD1->getFriendType ()) != (!FD2->getFriendType ()))
4085
+ return false ;
4086
+
4087
+ if (const TypeSourceInfo *TSI = FD1->getFriendType ())
4088
+ return Importer.IsStructurallyEquivalent (
4089
+ TSI->getType (), FD2->getFriendType ()->getType (), /* Complain=*/ false );
4090
+
4091
+ ASTImporter::NonEquivalentDeclSet NonEquivalentDecls;
4092
+ StructuralEquivalenceContext Ctx (
4093
+ FD1->getASTContext (), FD2->getASTContext (), NonEquivalentDecls,
4094
+ StructuralEquivalenceKind::Default,
4095
+ /* StrictTypeSpelling = */ false , /* Complain = */ false );
4096
+ return Ctx.IsEquivalent (FD1, FD2);
4097
+ }
4098
+
4099
+ static FriendCountAndPosition getFriendCountAndPosition (ASTImporter &Importer,
4100
+ FriendDecl *FD) {
4086
4101
unsigned int FriendCount = 0 ;
4087
4102
std::optional<unsigned int > FriendPosition;
4088
4103
const auto *RD = cast<CXXRecordDecl>(FD->getLexicalDeclContext ());
4089
4104
4090
- T TypeOrDecl = GetCanTypeOrDecl (FD);
4091
-
4092
- for (const FriendDecl *FoundFriend : RD->friends ()) {
4105
+ for (FriendDecl *FoundFriend : RD->friends ()) {
4093
4106
if (FoundFriend == FD) {
4094
4107
FriendPosition = FriendCount;
4095
4108
++FriendCount;
4096
- } else if (!FoundFriend->getFriendDecl () == !FD->getFriendDecl () &&
4097
- GetCanTypeOrDecl (FoundFriend) == TypeOrDecl) {
4109
+ } else if (IsEquivalentFriend (Importer, FD, FoundFriend)) {
4098
4110
++FriendCount;
4099
4111
}
4100
4112
}
@@ -4104,21 +4116,6 @@ static FriendCountAndPosition getFriendCountAndPosition(
4104
4116
return {FriendCount, *FriendPosition};
4105
4117
}
4106
4118
4107
- static FriendCountAndPosition getFriendCountAndPosition (const FriendDecl *FD) {
4108
- if (FD->getFriendType ())
4109
- return getFriendCountAndPosition<QualType>(FD, [](const FriendDecl *F) {
4110
- if (TypeSourceInfo *TSI = F->getFriendType ())
4111
- return TSI->getType ().getCanonicalType ();
4112
- llvm_unreachable (" Wrong friend object type." );
4113
- });
4114
- else
4115
- return getFriendCountAndPosition<Decl *>(FD, [](const FriendDecl *F) {
4116
- if (Decl *D = F->getFriendDecl ())
4117
- return D->getCanonicalDecl ();
4118
- llvm_unreachable (" Wrong friend object type." );
4119
- });
4120
- }
4121
-
4122
4119
ExpectedDecl ASTNodeImporter::VisitFriendDecl (FriendDecl *D) {
4123
4120
// Import the major distinguishing characteristics of a declaration.
4124
4121
DeclContext *DC, *LexicalDC;
@@ -4129,26 +4126,13 @@ ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
4129
4126
// FriendDecl is not a NamedDecl so we cannot use lookup.
4130
4127
// We try to maintain order and count of redundant friend declarations.
4131
4128
const auto *RD = cast<CXXRecordDecl>(DC);
4132
- FriendDecl *ImportedFriend = RD->getFirstFriend ();
4133
4129
SmallVector<FriendDecl *, 2 > ImportedEquivalentFriends;
4134
-
4135
- while (ImportedFriend) {
4136
- bool Match = false ;
4137
- if (D->getFriendDecl () && ImportedFriend->getFriendDecl ()) {
4138
- Match =
4139
- IsStructuralMatch (D->getFriendDecl (), ImportedFriend->getFriendDecl (),
4140
- /* Complain=*/ false );
4141
- } else if (D->getFriendType () && ImportedFriend->getFriendType ()) {
4142
- Match = Importer.IsStructurallyEquivalent (
4143
- D->getFriendType ()->getType (),
4144
- ImportedFriend->getFriendType ()->getType (), /* Complain=*/ false );
4145
- }
4146
- if (Match)
4130
+ for (FriendDecl *ImportedFriend : RD->friends ())
4131
+ if (IsEquivalentFriend (Importer, D, ImportedFriend))
4147
4132
ImportedEquivalentFriends.push_back (ImportedFriend);
4148
4133
4149
- ImportedFriend = ImportedFriend->getNextFriend ();
4150
- }
4151
- FriendCountAndPosition CountAndPosition = getFriendCountAndPosition (D);
4134
+ FriendCountAndPosition CountAndPosition =
4135
+ getFriendCountAndPosition (Importer, D);
4152
4136
4153
4137
assert (ImportedEquivalentFriends.size () <= CountAndPosition.TotalCount &&
4154
4138
" Class with non-matching friends is imported, ODR check wrong?" );
0 commit comments