summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ODRHash.cpp18
-rw-r--r--clang/lib/Serialization/ASTReader.cpp53
2 files changed, 71 insertions, 0 deletions
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 3f66e58eb86..66b9940b8b0 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -228,6 +228,13 @@ public:
Hash.AddQualType(T);
}
+ void AddDecl(const Decl *D) {
+ Hash.AddBoolean(D);
+ if (D) {
+ Hash.AddDecl(D);
+ }
+ }
+
void Visit(const Decl *D) {
ID.AddInteger(D->getKind());
Inherited::Visit(D);
@@ -321,6 +328,16 @@ public:
void VisitTypeAliasDecl(const TypeAliasDecl *D) {
Inherited::VisitTypeAliasDecl(D);
}
+
+ void VisitFriendDecl(const FriendDecl *D) {
+ TypeSourceInfo *TSI = D->getFriendType();
+ Hash.AddBoolean(TSI);
+ if (TSI) {
+ AddQualType(TSI->getType());
+ } else {
+ AddDecl(D->getFriendDecl());
+ }
+ }
};
// Only allow a small portion of Decl's to be processed. Remove this once
@@ -335,6 +352,7 @@ bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) {
case Decl::AccessSpec:
case Decl::CXXMethod:
case Decl::Field:
+ case Decl::Friend:
case Decl::StaticAssert:
case Decl::TypeAlias:
case Decl::Typedef:
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 3aee3c04001..678ecfc9a3d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9314,6 +9314,7 @@ void ASTReader::diagnoseOdrViolations() {
TypeAlias,
TypeDef,
Var,
+ Friend,
Other
} FirstDiffType = Other,
SecondDiffType = Other;
@@ -9347,6 +9348,8 @@ void ASTReader::diagnoseOdrViolations() {
return TypeDef;
case Decl::Var:
return Var;
+ case Decl::Friend:
+ return Friend;
}
};
@@ -9463,6 +9466,9 @@ void ASTReader::diagnoseOdrViolations() {
VarSingleInitializer,
VarDifferentInitializer,
VarConstexpr,
+ FriendTypeFunction,
+ FriendType,
+ FriendFunction,
};
// These lambdas have the common portions of the ODR diagnostics. This
@@ -9973,6 +9979,53 @@ void ASTReader::diagnoseOdrViolations() {
}
break;
}
+ case Friend: {
+ FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
+ FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
+
+ NamedDecl *FirstND = FirstFriend->getFriendDecl();
+ NamedDecl *SecondND = SecondFriend->getFriendDecl();
+
+ TypeSourceInfo *FirstTSI = FirstFriend->getFriendType();
+ TypeSourceInfo *SecondTSI = SecondFriend->getFriendType();
+
+ if (FirstND && SecondND) {
+ ODRDiagError(FirstFriend->getFriendLoc(),
+ FirstFriend->getSourceRange(), FriendFunction)
+ << FirstND;
+ ODRDiagNote(SecondFriend->getFriendLoc(),
+ SecondFriend->getSourceRange(), FriendFunction)
+ << SecondND;
+
+ Diagnosed = true;
+ break;
+ }
+
+ if (FirstTSI && SecondTSI) {
+ QualType FirstFriendType = FirstTSI->getType();
+ QualType SecondFriendType = SecondTSI->getType();
+ assert(ComputeQualTypeODRHash(FirstFriendType) !=
+ ComputeQualTypeODRHash(SecondFriendType));
+ ODRDiagError(FirstFriend->getFriendLoc(),
+ FirstFriend->getSourceRange(), FriendType)
+ << FirstFriendType;
+ ODRDiagNote(SecondFriend->getFriendLoc(),
+ SecondFriend->getSourceRange(), FriendType)
+ << SecondFriendType;
+ Diagnosed = true;
+ break;
+ }
+
+ ODRDiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
+ FriendTypeFunction)
+ << (FirstTSI == nullptr);
+ ODRDiagNote(SecondFriend->getFriendLoc(),
+ SecondFriend->getSourceRange(), FriendTypeFunction)
+ << (SecondTSI == nullptr);
+
+ Diagnosed = true;
+ break;
+ }
}
if (Diagnosed == true)
OpenPOWER on IntegriCloud