1 //===-- ODRDiagsEmitter.cpp - Diagnostics for ODR mismatches ----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang/AST/ODRDiagsEmitter.h"
10 #include "clang/AST/DeclFriend.h"
11 #include "clang/AST/DeclTemplate.h"
12 #include "clang/AST/ODRHash.h"
13 #include "clang/Basic/DiagnosticAST.h"
14 #include "clang/Basic/Module.h"
16 using namespace clang
;
18 static unsigned computeODRHash(QualType Ty
) {
20 Hasher
.AddQualType(Ty
);
21 return Hasher
.CalculateHash();
24 static unsigned computeODRHash(const Stmt
*S
) {
27 return Hasher
.CalculateHash();
30 static unsigned computeODRHash(const Decl
*D
) {
34 return Hasher
.CalculateHash();
37 static unsigned computeODRHash(const TemplateArgument
&TA
) {
39 Hasher
.AddTemplateArgument(TA
);
40 return Hasher
.CalculateHash();
43 std::string
ODRDiagsEmitter::getOwningModuleNameForDiagnostic(const Decl
*D
) {
44 // If we know the owning module, use it.
45 if (Module
*M
= D
->getImportedOwningModule())
46 return M
->getFullModuleName();
52 template <typename MethodT
>
53 static bool diagnoseSubMismatchMethodParameters(DiagnosticsEngine
&Diags
,
54 const NamedDecl
*FirstContainer
,
55 StringRef FirstModule
,
56 StringRef SecondModule
,
57 const MethodT
*FirstMethod
,
58 const MethodT
*SecondMethod
) {
64 auto GetDiagMethodType
= [](const NamedDecl
*D
) {
65 if (isa
<CXXConstructorDecl
>(D
))
66 return DiagConstructor
;
67 if (isa
<CXXDestructorDecl
>(D
))
68 return DiagDestructor
;
72 enum ODRMethodParametersDifference
{
77 auto DiagError
= [&Diags
, &GetDiagMethodType
, FirstContainer
, FirstModule
,
78 FirstMethod
](ODRMethodParametersDifference DiffType
) {
79 DeclarationName FirstName
= FirstMethod
->getDeclName();
80 DiagMethodType FirstMethodType
= GetDiagMethodType(FirstMethod
);
81 return Diags
.Report(FirstMethod
->getLocation(),
82 diag::err_module_odr_violation_method_params
)
83 << FirstContainer
<< FirstModule
.empty() << FirstModule
84 << FirstMethod
->getSourceRange() << DiffType
<< FirstMethodType
87 auto DiagNote
= [&Diags
, &GetDiagMethodType
, SecondModule
,
88 SecondMethod
](ODRMethodParametersDifference DiffType
) {
89 DeclarationName SecondName
= SecondMethod
->getDeclName();
90 DiagMethodType SecondMethodType
= GetDiagMethodType(SecondMethod
);
91 return Diags
.Report(SecondMethod
->getLocation(),
92 diag::note_module_odr_violation_method_params
)
93 << SecondModule
.empty() << SecondModule
94 << SecondMethod
->getSourceRange() << DiffType
<< SecondMethodType
98 const unsigned FirstNumParameters
= FirstMethod
->param_size();
99 const unsigned SecondNumParameters
= SecondMethod
->param_size();
100 if (FirstNumParameters
!= SecondNumParameters
) {
101 DiagError(NumberParameters
) << FirstNumParameters
;
102 DiagNote(NumberParameters
) << SecondNumParameters
;
106 for (unsigned I
= 0; I
< FirstNumParameters
; ++I
) {
107 const ParmVarDecl
*FirstParam
= FirstMethod
->getParamDecl(I
);
108 const ParmVarDecl
*SecondParam
= SecondMethod
->getParamDecl(I
);
110 QualType FirstParamType
= FirstParam
->getType();
111 QualType SecondParamType
= SecondParam
->getType();
112 if (FirstParamType
!= SecondParamType
&&
113 computeODRHash(FirstParamType
) != computeODRHash(SecondParamType
)) {
114 if (const DecayedType
*ParamDecayedType
=
115 FirstParamType
->getAs
<DecayedType
>()) {
116 DiagError(ParameterType
) << (I
+ 1) << FirstParamType
<< true
117 << ParamDecayedType
->getOriginalType();
119 DiagError(ParameterType
) << (I
+ 1) << FirstParamType
<< false;
122 if (const DecayedType
*ParamDecayedType
=
123 SecondParamType
->getAs
<DecayedType
>()) {
124 DiagNote(ParameterType
) << (I
+ 1) << SecondParamType
<< true
125 << ParamDecayedType
->getOriginalType();
127 DiagNote(ParameterType
) << (I
+ 1) << SecondParamType
<< false;
132 DeclarationName FirstParamName
= FirstParam
->getDeclName();
133 DeclarationName SecondParamName
= SecondParam
->getDeclName();
134 if (FirstParamName
!= SecondParamName
) {
135 DiagError(ParameterName
) << (I
+ 1) << FirstParamName
;
136 DiagNote(ParameterName
) << (I
+ 1) << SecondParamName
;
144 bool ODRDiagsEmitter::diagnoseSubMismatchField(
145 const NamedDecl
*FirstRecord
, StringRef FirstModule
, StringRef SecondModule
,
146 const FieldDecl
*FirstField
, const FieldDecl
*SecondField
) const {
147 enum ODRFieldDifference
{
151 FieldDifferentWidthBitField
,
153 FieldSingleInitializer
,
154 FieldDifferentInitializers
,
157 auto DiagError
= [FirstRecord
, FirstField
, FirstModule
,
158 this](ODRFieldDifference DiffType
) {
159 return Diag(FirstField
->getLocation(), diag::err_module_odr_violation_field
)
160 << FirstRecord
<< FirstModule
.empty() << FirstModule
161 << FirstField
->getSourceRange() << DiffType
;
163 auto DiagNote
= [SecondField
, SecondModule
,
164 this](ODRFieldDifference DiffType
) {
165 return Diag(SecondField
->getLocation(),
166 diag::note_module_odr_violation_field
)
167 << SecondModule
.empty() << SecondModule
<< SecondField
->getSourceRange() << DiffType
;
170 IdentifierInfo
*FirstII
= FirstField
->getIdentifier();
171 IdentifierInfo
*SecondII
= SecondField
->getIdentifier();
172 if (FirstII
->getName() != SecondII
->getName()) {
173 DiagError(FieldName
) << FirstII
;
174 DiagNote(FieldName
) << SecondII
;
178 QualType FirstType
= FirstField
->getType();
179 QualType SecondType
= SecondField
->getType();
180 if (computeODRHash(FirstType
) != computeODRHash(SecondType
)) {
181 DiagError(FieldTypeName
) << FirstII
<< FirstType
;
182 DiagNote(FieldTypeName
) << SecondII
<< SecondType
;
186 assert(Context
.hasSameType(FirstField
->getType(), SecondField
->getType()));
189 const bool IsFirstBitField
= FirstField
->isBitField();
190 const bool IsSecondBitField
= SecondField
->isBitField();
191 if (IsFirstBitField
!= IsSecondBitField
) {
192 DiagError(FieldSingleBitField
) << FirstII
<< IsFirstBitField
;
193 DiagNote(FieldSingleBitField
) << SecondII
<< IsSecondBitField
;
197 if (IsFirstBitField
&& IsSecondBitField
) {
198 unsigned FirstBitWidthHash
= computeODRHash(FirstField
->getBitWidth());
199 unsigned SecondBitWidthHash
= computeODRHash(SecondField
->getBitWidth());
200 if (FirstBitWidthHash
!= SecondBitWidthHash
) {
201 DiagError(FieldDifferentWidthBitField
)
202 << FirstII
<< FirstField
->getBitWidth()->getSourceRange();
203 DiagNote(FieldDifferentWidthBitField
)
204 << SecondII
<< SecondField
->getBitWidth()->getSourceRange();
209 if (!LangOpts
.CPlusPlus
)
212 const bool IsFirstMutable
= FirstField
->isMutable();
213 const bool IsSecondMutable
= SecondField
->isMutable();
214 if (IsFirstMutable
!= IsSecondMutable
) {
215 DiagError(FieldSingleMutable
) << FirstII
<< IsFirstMutable
;
216 DiagNote(FieldSingleMutable
) << SecondII
<< IsSecondMutable
;
220 const Expr
*FirstInitializer
= FirstField
->getInClassInitializer();
221 const Expr
*SecondInitializer
= SecondField
->getInClassInitializer();
222 if ((!FirstInitializer
&& SecondInitializer
) ||
223 (FirstInitializer
&& !SecondInitializer
)) {
224 DiagError(FieldSingleInitializer
)
225 << FirstII
<< (FirstInitializer
!= nullptr);
226 DiagNote(FieldSingleInitializer
)
227 << SecondII
<< (SecondInitializer
!= nullptr);
231 if (FirstInitializer
&& SecondInitializer
) {
232 unsigned FirstInitHash
= computeODRHash(FirstInitializer
);
233 unsigned SecondInitHash
= computeODRHash(SecondInitializer
);
234 if (FirstInitHash
!= SecondInitHash
) {
235 DiagError(FieldDifferentInitializers
)
236 << FirstII
<< FirstInitializer
->getSourceRange();
237 DiagNote(FieldDifferentInitializers
)
238 << SecondII
<< SecondInitializer
->getSourceRange();
246 bool ODRDiagsEmitter::diagnoseSubMismatchTypedef(
247 const NamedDecl
*FirstRecord
, StringRef FirstModule
, StringRef SecondModule
,
248 const TypedefNameDecl
*FirstTD
, const TypedefNameDecl
*SecondTD
,
249 bool IsTypeAlias
) const {
250 enum ODRTypedefDifference
{
255 auto DiagError
= [FirstRecord
, FirstTD
, FirstModule
,
256 this](ODRTypedefDifference DiffType
) {
257 return Diag(FirstTD
->getLocation(), diag::err_module_odr_violation_typedef
)
258 << FirstRecord
<< FirstModule
.empty() << FirstModule
259 << FirstTD
->getSourceRange() << DiffType
;
261 auto DiagNote
= [SecondTD
, SecondModule
,
262 this](ODRTypedefDifference DiffType
) {
263 return Diag(SecondTD
->getLocation(),
264 diag::note_module_odr_violation_typedef
)
265 << SecondModule
<< SecondTD
->getSourceRange() << DiffType
;
268 DeclarationName FirstName
= FirstTD
->getDeclName();
269 DeclarationName SecondName
= SecondTD
->getDeclName();
270 if (FirstName
!= SecondName
) {
271 DiagError(TypedefName
) << IsTypeAlias
<< FirstName
;
272 DiagNote(TypedefName
) << IsTypeAlias
<< SecondName
;
276 QualType FirstType
= FirstTD
->getUnderlyingType();
277 QualType SecondType
= SecondTD
->getUnderlyingType();
278 if (computeODRHash(FirstType
) != computeODRHash(SecondType
)) {
279 DiagError(TypedefType
) << IsTypeAlias
<< FirstName
<< FirstType
;
280 DiagNote(TypedefType
) << IsTypeAlias
<< SecondName
<< SecondType
;
286 bool ODRDiagsEmitter::diagnoseSubMismatchVar(const NamedDecl
*FirstRecord
,
287 StringRef FirstModule
,
288 StringRef SecondModule
,
289 const VarDecl
*FirstVD
,
290 const VarDecl
*SecondVD
) const {
291 enum ODRVarDifference
{
294 VarSingleInitializer
,
295 VarDifferentInitializer
,
299 auto DiagError
= [FirstRecord
, FirstVD
, FirstModule
,
300 this](ODRVarDifference DiffType
) {
301 return Diag(FirstVD
->getLocation(), diag::err_module_odr_violation_variable
)
302 << FirstRecord
<< FirstModule
.empty() << FirstModule
303 << FirstVD
->getSourceRange() << DiffType
;
305 auto DiagNote
= [SecondVD
, SecondModule
, this](ODRVarDifference DiffType
) {
306 return Diag(SecondVD
->getLocation(),
307 diag::note_module_odr_violation_variable
)
308 << SecondModule
<< SecondVD
->getSourceRange() << DiffType
;
311 DeclarationName FirstName
= FirstVD
->getDeclName();
312 DeclarationName SecondName
= SecondVD
->getDeclName();
313 if (FirstName
!= SecondName
) {
314 DiagError(VarName
) << FirstName
;
315 DiagNote(VarName
) << SecondName
;
319 QualType FirstType
= FirstVD
->getType();
320 QualType SecondType
= SecondVD
->getType();
321 if (computeODRHash(FirstType
) != computeODRHash(SecondType
)) {
322 DiagError(VarType
) << FirstName
<< FirstType
;
323 DiagNote(VarType
) << SecondName
<< SecondType
;
327 if (!LangOpts
.CPlusPlus
)
330 const Expr
*FirstInit
= FirstVD
->getInit();
331 const Expr
*SecondInit
= SecondVD
->getInit();
332 if ((FirstInit
== nullptr) != (SecondInit
== nullptr)) {
333 DiagError(VarSingleInitializer
)
334 << FirstName
<< (FirstInit
== nullptr)
335 << (FirstInit
? FirstInit
->getSourceRange() : SourceRange());
336 DiagNote(VarSingleInitializer
)
337 << SecondName
<< (SecondInit
== nullptr)
338 << (SecondInit
? SecondInit
->getSourceRange() : SourceRange());
342 if (FirstInit
&& SecondInit
&&
343 computeODRHash(FirstInit
) != computeODRHash(SecondInit
)) {
344 DiagError(VarDifferentInitializer
)
345 << FirstName
<< FirstInit
->getSourceRange();
346 DiagNote(VarDifferentInitializer
)
347 << SecondName
<< SecondInit
->getSourceRange();
351 const bool FirstIsConstexpr
= FirstVD
->isConstexpr();
352 const bool SecondIsConstexpr
= SecondVD
->isConstexpr();
353 if (FirstIsConstexpr
!= SecondIsConstexpr
) {
354 DiagError(VarConstexpr
) << FirstName
<< FirstIsConstexpr
;
355 DiagNote(VarConstexpr
) << SecondName
<< SecondIsConstexpr
;
361 bool ODRDiagsEmitter::diagnoseSubMismatchProtocols(
362 const ObjCProtocolList
&FirstProtocols
,
363 const ObjCContainerDecl
*FirstContainer
, StringRef FirstModule
,
364 const ObjCProtocolList
&SecondProtocols
,
365 const ObjCContainerDecl
*SecondContainer
, StringRef SecondModule
) const {
366 // Keep in sync with err_module_odr_violation_referenced_protocols.
367 enum ODRReferencedProtocolDifference
{
371 auto DiagRefProtocolError
= [FirstContainer
, FirstModule
,
372 this](SourceLocation Loc
, SourceRange Range
,
373 ODRReferencedProtocolDifference DiffType
) {
374 return Diag(Loc
, diag::err_module_odr_violation_referenced_protocols
)
375 << FirstContainer
<< FirstModule
.empty() << FirstModule
<< Range
378 auto DiagRefProtocolNote
= [SecondModule
,
379 this](SourceLocation Loc
, SourceRange Range
,
380 ODRReferencedProtocolDifference DiffType
) {
381 return Diag(Loc
, diag::note_module_odr_violation_referenced_protocols
)
382 << SecondModule
.empty() << SecondModule
<< Range
<< DiffType
;
384 auto GetProtoListSourceRange
= [](const ObjCProtocolList
&PL
) {
386 return SourceRange();
387 return SourceRange(*PL
.loc_begin(), *std::prev(PL
.loc_end()));
390 if (FirstProtocols
.size() != SecondProtocols
.size()) {
391 DiagRefProtocolError(FirstContainer
->getLocation(),
392 GetProtoListSourceRange(FirstProtocols
), NumProtocols
)
393 << FirstProtocols
.size();
394 DiagRefProtocolNote(SecondContainer
->getLocation(),
395 GetProtoListSourceRange(SecondProtocols
), NumProtocols
)
396 << SecondProtocols
.size();
400 for (unsigned I
= 0, E
= FirstProtocols
.size(); I
!= E
; ++I
) {
401 const ObjCProtocolDecl
*FirstProtocol
= FirstProtocols
[I
];
402 const ObjCProtocolDecl
*SecondProtocol
= SecondProtocols
[I
];
403 DeclarationName FirstProtocolName
= FirstProtocol
->getDeclName();
404 DeclarationName SecondProtocolName
= SecondProtocol
->getDeclName();
405 if (FirstProtocolName
!= SecondProtocolName
) {
406 SourceLocation FirstLoc
= *(FirstProtocols
.loc_begin() + I
);
407 SourceLocation SecondLoc
= *(SecondProtocols
.loc_begin() + I
);
408 SourceRange EmptyRange
;
409 DiagRefProtocolError(FirstLoc
, EmptyRange
, ProtocolType
)
410 << (I
+ 1) << FirstProtocolName
;
411 DiagRefProtocolNote(SecondLoc
, EmptyRange
, ProtocolType
)
412 << (I
+ 1) << SecondProtocolName
;
420 bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod(
421 const NamedDecl
*FirstObjCContainer
, StringRef FirstModule
,
422 StringRef SecondModule
, const ObjCMethodDecl
*FirstMethod
,
423 const ObjCMethodDecl
*SecondMethod
) const {
424 enum ODRMethodDifference
{
427 ControlLevel
, // optional/required
428 DesignatedInitializer
,
433 auto DiagError
= [FirstObjCContainer
, FirstModule
, FirstMethod
,
434 this](ODRMethodDifference DiffType
) {
435 return Diag(FirstMethod
->getLocation(),
436 diag::err_module_odr_violation_objc_method
)
437 << FirstObjCContainer
<< FirstModule
.empty() << FirstModule
438 << FirstMethod
->getSourceRange() << DiffType
;
440 auto DiagNote
= [SecondModule
, SecondMethod
,
441 this](ODRMethodDifference DiffType
) {
442 return Diag(SecondMethod
->getLocation(),
443 diag::note_module_odr_violation_objc_method
)
444 << SecondModule
.empty() << SecondModule
445 << SecondMethod
->getSourceRange() << DiffType
;
448 if (computeODRHash(FirstMethod
->getReturnType()) !=
449 computeODRHash(SecondMethod
->getReturnType())) {
450 DiagError(ReturnType
) << FirstMethod
<< FirstMethod
->getReturnType();
451 DiagNote(ReturnType
) << SecondMethod
<< SecondMethod
->getReturnType();
455 if (FirstMethod
->isInstanceMethod() != SecondMethod
->isInstanceMethod()) {
456 DiagError(InstanceOrClass
)
457 << FirstMethod
<< FirstMethod
->isInstanceMethod();
458 DiagNote(InstanceOrClass
)
459 << SecondMethod
<< SecondMethod
->isInstanceMethod();
462 if (FirstMethod
->getImplementationControl() !=
463 SecondMethod
->getImplementationControl()) {
464 DiagError(ControlLevel
)
465 << llvm::to_underlying(FirstMethod
->getImplementationControl());
466 DiagNote(ControlLevel
) << llvm::to_underlying(
467 SecondMethod
->getImplementationControl());
470 if (FirstMethod
->isThisDeclarationADesignatedInitializer() !=
471 SecondMethod
->isThisDeclarationADesignatedInitializer()) {
472 DiagError(DesignatedInitializer
)
474 << FirstMethod
->isThisDeclarationADesignatedInitializer();
475 DiagNote(DesignatedInitializer
)
477 << SecondMethod
->isThisDeclarationADesignatedInitializer();
480 if (FirstMethod
->isDirectMethod() != SecondMethod
->isDirectMethod()) {
481 DiagError(Directness
) << FirstMethod
<< FirstMethod
->isDirectMethod();
482 DiagNote(Directness
) << SecondMethod
<< SecondMethod
->isDirectMethod();
485 if (diagnoseSubMismatchMethodParameters(Diags
, FirstObjCContainer
,
486 FirstModule
, SecondModule
,
487 FirstMethod
, SecondMethod
))
490 // Check method name *after* looking at the parameters otherwise we get a
491 // less ideal diagnostics: a ObjCMethodName mismatch given that selectors
492 // for different parameters are likely to be different.
493 DeclarationName FirstName
= FirstMethod
->getDeclName();
494 DeclarationName SecondName
= SecondMethod
->getDeclName();
495 if (FirstName
!= SecondName
) {
496 DiagError(Name
) << FirstName
;
497 DiagNote(Name
) << SecondName
;
504 bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
505 const NamedDecl
*FirstObjCContainer
, StringRef FirstModule
,
506 StringRef SecondModule
, const ObjCPropertyDecl
*FirstProp
,
507 const ObjCPropertyDecl
*SecondProp
) const {
508 enum ODRPropertyDifference
{
511 ControlLevel
, // optional/required
515 auto DiagError
= [FirstObjCContainer
, FirstModule
, FirstProp
,
516 this](SourceLocation Loc
, ODRPropertyDifference DiffType
) {
517 return Diag(Loc
, diag::err_module_odr_violation_objc_property
)
518 << FirstObjCContainer
<< FirstModule
.empty() << FirstModule
519 << FirstProp
->getSourceRange() << DiffType
;
521 auto DiagNote
= [SecondModule
, SecondProp
,
522 this](SourceLocation Loc
, ODRPropertyDifference DiffType
) {
523 return Diag(Loc
, diag::note_module_odr_violation_objc_property
)
524 << SecondModule
.empty() << SecondModule
525 << SecondProp
->getSourceRange() << DiffType
;
528 IdentifierInfo
*FirstII
= FirstProp
->getIdentifier();
529 IdentifierInfo
*SecondII
= SecondProp
->getIdentifier();
530 if (FirstII
->getName() != SecondII
->getName()) {
531 DiagError(FirstProp
->getLocation(), Name
) << FirstII
;
532 DiagNote(SecondProp
->getLocation(), Name
) << SecondII
;
535 if (computeODRHash(FirstProp
->getType()) !=
536 computeODRHash(SecondProp
->getType())) {
537 DiagError(FirstProp
->getLocation(), Type
)
538 << FirstII
<< FirstProp
->getType();
539 DiagNote(SecondProp
->getLocation(), Type
)
540 << SecondII
<< SecondProp
->getType();
543 if (FirstProp
->getPropertyImplementation() !=
544 SecondProp
->getPropertyImplementation()) {
545 DiagError(FirstProp
->getLocation(), ControlLevel
)
546 << FirstProp
->getPropertyImplementation();
547 DiagNote(SecondProp
->getLocation(), ControlLevel
)
548 << SecondProp
->getPropertyImplementation();
552 // Go over the property attributes and stop at the first mismatch.
553 unsigned FirstAttrs
= (unsigned)FirstProp
->getPropertyAttributes();
554 unsigned SecondAttrs
= (unsigned)SecondProp
->getPropertyAttributes();
555 if (FirstAttrs
!= SecondAttrs
) {
556 for (unsigned I
= 0; I
< NumObjCPropertyAttrsBits
; ++I
) {
557 unsigned CheckedAttr
= (1 << I
);
558 if ((FirstAttrs
& CheckedAttr
) == (SecondAttrs
& CheckedAttr
))
561 bool IsFirstWritten
=
562 (unsigned)FirstProp
->getPropertyAttributesAsWritten() & CheckedAttr
;
563 bool IsSecondWritten
=
564 (unsigned)SecondProp
->getPropertyAttributesAsWritten() & CheckedAttr
;
565 DiagError(IsFirstWritten
? FirstProp
->getLParenLoc()
566 : FirstProp
->getLocation(),
568 << FirstII
<< (I
+ 1) << IsFirstWritten
;
569 DiagNote(IsSecondWritten
? SecondProp
->getLParenLoc()
570 : SecondProp
->getLocation(),
572 << SecondII
<< (I
+ 1);
580 ODRDiagsEmitter::DiffResult
581 ODRDiagsEmitter::FindTypeDiffs(DeclHashes
&FirstHashes
,
582 DeclHashes
&SecondHashes
) {
583 auto DifferenceSelector
= [](const Decl
*D
) {
584 assert(D
&& "valid Decl required");
585 switch (D
->getKind()) {
588 case Decl::AccessSpec
:
589 switch (D
->getAccess()) {
591 return PublicSpecifer
;
593 return PrivateSpecifer
;
595 return ProtectedSpecifer
;
599 llvm_unreachable("Invalid access specifier");
600 case Decl::StaticAssert
:
604 case Decl::CXXMethod
:
605 case Decl::CXXConstructor
:
606 case Decl::CXXDestructor
:
608 case Decl::TypeAlias
:
616 case Decl::FunctionTemplate
:
617 return FunctionTemplate
;
618 case Decl::ObjCMethod
:
622 case Decl::ObjCProperty
:
628 auto FirstIt
= FirstHashes
.begin();
629 auto SecondIt
= SecondHashes
.begin();
630 while (FirstIt
!= FirstHashes
.end() || SecondIt
!= SecondHashes
.end()) {
631 if (FirstIt
!= FirstHashes
.end() && SecondIt
!= SecondHashes
.end() &&
632 FirstIt
->second
== SecondIt
->second
) {
638 DR
.FirstDecl
= FirstIt
== FirstHashes
.end() ? nullptr : FirstIt
->first
;
639 DR
.SecondDecl
= SecondIt
== SecondHashes
.end() ? nullptr : SecondIt
->first
;
642 DR
.FirstDecl
? DifferenceSelector(DR
.FirstDecl
) : EndOfClass
;
644 DR
.SecondDecl
? DifferenceSelector(DR
.SecondDecl
) : EndOfClass
;
650 void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(
651 DiffResult
&DR
, const NamedDecl
*FirstRecord
, StringRef FirstModule
,
652 const NamedDecl
*SecondRecord
, StringRef SecondModule
) const {
653 Diag(FirstRecord
->getLocation(),
654 diag::err_module_odr_violation_different_definitions
)
655 << FirstRecord
<< FirstModule
.empty() << FirstModule
;
658 Diag(DR
.FirstDecl
->getLocation(), diag::note_first_module_difference
)
659 << FirstRecord
<< DR
.FirstDecl
->getSourceRange();
662 Diag(SecondRecord
->getLocation(),
663 diag::note_module_odr_violation_different_definitions
)
667 Diag(DR
.SecondDecl
->getLocation(), diag::note_second_module_difference
)
668 << DR
.SecondDecl
->getSourceRange();
672 void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
673 DiffResult
&DR
, const NamedDecl
*FirstRecord
, StringRef FirstModule
,
674 const NamedDecl
*SecondRecord
, StringRef SecondModule
) const {
675 auto GetMismatchedDeclLoc
= [](const NamedDecl
*Container
,
676 ODRMismatchDecl DiffType
, const Decl
*D
) {
679 if (DiffType
== EndOfClass
) {
680 if (auto *Tag
= dyn_cast
<TagDecl
>(Container
))
681 Loc
= Tag
->getBraceRange().getEnd();
682 else if (auto *IF
= dyn_cast
<ObjCInterfaceDecl
>(Container
))
683 Loc
= IF
->getAtEndRange().getBegin();
685 Loc
= Container
->getEndLoc();
687 Loc
= D
->getLocation();
688 Range
= D
->getSourceRange();
690 return std::make_pair(Loc
, Range
);
694 GetMismatchedDeclLoc(FirstRecord
, DR
.FirstDiffType
, DR
.FirstDecl
);
695 Diag(FirstDiagInfo
.first
, diag::err_module_odr_violation_mismatch_decl
)
696 << FirstRecord
<< FirstModule
.empty() << FirstModule
697 << FirstDiagInfo
.second
<< DR
.FirstDiffType
;
699 auto SecondDiagInfo
=
700 GetMismatchedDeclLoc(SecondRecord
, DR
.SecondDiffType
, DR
.SecondDecl
);
701 Diag(SecondDiagInfo
.first
, diag::note_module_odr_violation_mismatch_decl
)
702 << SecondModule
.empty() << SecondModule
<< SecondDiagInfo
.second
703 << DR
.SecondDiffType
;
706 bool ODRDiagsEmitter::diagnoseMismatch(
707 const CXXRecordDecl
*FirstRecord
, const CXXRecordDecl
*SecondRecord
,
708 const struct CXXRecordDecl::DefinitionData
*SecondDD
) const {
709 // Multiple different declarations got merged together; tell the user
710 // where they came from.
711 if (FirstRecord
== SecondRecord
)
714 std::string FirstModule
= getOwningModuleNameForDiagnostic(FirstRecord
);
715 std::string SecondModule
= getOwningModuleNameForDiagnostic(SecondRecord
);
717 const struct CXXRecordDecl::DefinitionData
*FirstDD
=
718 FirstRecord
->DefinitionData
;
719 assert(FirstDD
&& SecondDD
&& "Definitions without DefinitionData");
721 // Diagnostics from DefinitionData are emitted here.
722 if (FirstDD
!= SecondDD
) {
723 // Keep in sync with err_module_odr_violation_definition_data.
724 enum ODRDefinitionDataDifference
{
731 auto DiagBaseError
= [FirstRecord
, &FirstModule
,
732 this](SourceLocation Loc
, SourceRange Range
,
733 ODRDefinitionDataDifference DiffType
) {
734 return Diag(Loc
, diag::err_module_odr_violation_definition_data
)
735 << FirstRecord
<< FirstModule
.empty() << FirstModule
<< Range
738 auto DiagBaseNote
= [&SecondModule
,
739 this](SourceLocation Loc
, SourceRange Range
,
740 ODRDefinitionDataDifference DiffType
) {
741 return Diag(Loc
, diag::note_module_odr_violation_definition_data
)
742 << SecondModule
<< Range
<< DiffType
;
744 auto GetSourceRange
= [](const struct CXXRecordDecl::DefinitionData
*DD
) {
745 unsigned NumBases
= DD
->NumBases
;
747 return SourceRange();
748 ArrayRef
<CXXBaseSpecifier
> bases
= DD
->bases();
749 return SourceRange(bases
[0].getBeginLoc(),
750 bases
[NumBases
- 1].getEndLoc());
753 unsigned FirstNumBases
= FirstDD
->NumBases
;
754 unsigned FirstNumVBases
= FirstDD
->NumVBases
;
755 unsigned SecondNumBases
= SecondDD
->NumBases
;
756 unsigned SecondNumVBases
= SecondDD
->NumVBases
;
757 if (FirstNumBases
!= SecondNumBases
) {
758 DiagBaseError(FirstRecord
->getLocation(), GetSourceRange(FirstDD
),
761 DiagBaseNote(SecondRecord
->getLocation(), GetSourceRange(SecondDD
),
767 if (FirstNumVBases
!= SecondNumVBases
) {
768 DiagBaseError(FirstRecord
->getLocation(), GetSourceRange(FirstDD
),
771 DiagBaseNote(SecondRecord
->getLocation(), GetSourceRange(SecondDD
),
777 ArrayRef
<CXXBaseSpecifier
> FirstBases
= FirstDD
->bases();
778 ArrayRef
<CXXBaseSpecifier
> SecondBases
= SecondDD
->bases();
779 for (unsigned I
= 0; I
< FirstNumBases
; ++I
) {
780 const CXXBaseSpecifier FirstBase
= FirstBases
[I
];
781 const CXXBaseSpecifier SecondBase
= SecondBases
[I
];
782 if (computeODRHash(FirstBase
.getType()) !=
783 computeODRHash(SecondBase
.getType())) {
784 DiagBaseError(FirstRecord
->getLocation(), FirstBase
.getSourceRange(),
786 << (I
+ 1) << FirstBase
.getType();
787 DiagBaseNote(SecondRecord
->getLocation(), SecondBase
.getSourceRange(),
789 << (I
+ 1) << SecondBase
.getType();
793 if (FirstBase
.isVirtual() != SecondBase
.isVirtual()) {
794 DiagBaseError(FirstRecord
->getLocation(), FirstBase
.getSourceRange(),
796 << (I
+ 1) << FirstBase
.isVirtual() << FirstBase
.getType();
797 DiagBaseNote(SecondRecord
->getLocation(), SecondBase
.getSourceRange(),
799 << (I
+ 1) << SecondBase
.isVirtual() << SecondBase
.getType();
803 if (FirstBase
.getAccessSpecifierAsWritten() !=
804 SecondBase
.getAccessSpecifierAsWritten()) {
805 DiagBaseError(FirstRecord
->getLocation(), FirstBase
.getSourceRange(),
807 << (I
+ 1) << FirstBase
.getType()
808 << (int)FirstBase
.getAccessSpecifierAsWritten();
809 DiagBaseNote(SecondRecord
->getLocation(), SecondBase
.getSourceRange(),
811 << (I
+ 1) << SecondBase
.getType()
812 << (int)SecondBase
.getAccessSpecifierAsWritten();
818 const ClassTemplateDecl
*FirstTemplate
=
819 FirstRecord
->getDescribedClassTemplate();
820 const ClassTemplateDecl
*SecondTemplate
=
821 SecondRecord
->getDescribedClassTemplate();
823 assert(!FirstTemplate
== !SecondTemplate
&&
824 "Both pointers should be null or non-null");
826 if (FirstTemplate
&& SecondTemplate
) {
827 ArrayRef
<const NamedDecl
*> FirstTemplateParams
=
828 FirstTemplate
->getTemplateParameters()->asArray();
829 ArrayRef
<const NamedDecl
*> SecondTemplateParams
=
830 SecondTemplate
->getTemplateParameters()->asArray();
831 assert(FirstTemplateParams
.size() == SecondTemplateParams
.size() &&
832 "Number of template parameters should be equal.");
833 for (auto Pair
: llvm::zip(FirstTemplateParams
, SecondTemplateParams
)) {
834 const NamedDecl
*FirstDecl
= std::get
<0>(Pair
);
835 const NamedDecl
*SecondDecl
= std::get
<1>(Pair
);
836 if (computeODRHash(FirstDecl
) == computeODRHash(SecondDecl
))
839 assert(FirstDecl
->getKind() == SecondDecl
->getKind() &&
840 "Parameter Decl's should be the same kind.");
842 enum ODRTemplateDifference
{
845 ParamSingleDefaultArgument
,
846 ParamDifferentDefaultArgument
,
849 auto hasDefaultArg
= [](const NamedDecl
*D
) {
850 if (auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(D
))
851 return TTP
->hasDefaultArgument() &&
852 !TTP
->defaultArgumentWasInherited();
853 if (auto *NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(D
))
854 return NTTP
->hasDefaultArgument() &&
855 !NTTP
->defaultArgumentWasInherited();
856 auto *TTP
= cast
<TemplateTemplateParmDecl
>(D
);
857 return TTP
->hasDefaultArgument() && !TTP
->defaultArgumentWasInherited();
859 bool hasFirstArg
= hasDefaultArg(FirstDecl
);
860 bool hasSecondArg
= hasDefaultArg(SecondDecl
);
862 ODRTemplateDifference ErrDiffType
;
863 ODRTemplateDifference NoteDiffType
;
865 DeclarationName FirstName
= FirstDecl
->getDeclName();
866 DeclarationName SecondName
= SecondDecl
->getDeclName();
868 if (FirstName
!= SecondName
) {
869 bool FirstNameEmpty
=
870 FirstName
.isIdentifier() && !FirstName
.getAsIdentifierInfo();
871 bool SecondNameEmpty
=
872 SecondName
.isIdentifier() && !SecondName
.getAsIdentifierInfo();
873 ErrDiffType
= FirstNameEmpty
? ParamEmptyName
: ParamName
;
874 NoteDiffType
= SecondNameEmpty
? ParamEmptyName
: ParamName
;
875 } else if (hasFirstArg
== hasSecondArg
)
876 ErrDiffType
= NoteDiffType
= ParamDifferentDefaultArgument
;
878 ErrDiffType
= NoteDiffType
= ParamSingleDefaultArgument
;
880 Diag(FirstDecl
->getLocation(),
881 diag::err_module_odr_violation_template_parameter
)
882 << FirstRecord
<< FirstModule
.empty() << FirstModule
883 << FirstDecl
->getSourceRange() << ErrDiffType
<< hasFirstArg
885 Diag(SecondDecl
->getLocation(),
886 diag::note_module_odr_violation_template_parameter
)
887 << SecondModule
<< SecondDecl
->getSourceRange() << NoteDiffType
888 << hasSecondArg
<< SecondName
;
893 auto PopulateHashes
= [](DeclHashes
&Hashes
, const RecordDecl
*Record
,
894 const DeclContext
*DC
) {
895 for (const Decl
*D
: Record
->decls()) {
896 if (!ODRHash::isSubDeclToBeProcessed(D
, DC
))
898 Hashes
.emplace_back(D
, computeODRHash(D
));
902 DeclHashes FirstHashes
;
903 DeclHashes SecondHashes
;
904 const DeclContext
*DC
= FirstRecord
;
905 PopulateHashes(FirstHashes
, FirstRecord
, DC
);
906 PopulateHashes(SecondHashes
, SecondRecord
, DC
);
908 DiffResult DR
= FindTypeDiffs(FirstHashes
, SecondHashes
);
909 ODRMismatchDecl FirstDiffType
= DR
.FirstDiffType
;
910 ODRMismatchDecl SecondDiffType
= DR
.SecondDiffType
;
911 const Decl
*FirstDecl
= DR
.FirstDecl
;
912 const Decl
*SecondDecl
= DR
.SecondDecl
;
914 if (FirstDiffType
== Other
|| SecondDiffType
== Other
) {
915 diagnoseSubMismatchUnexpected(DR
, FirstRecord
, FirstModule
, SecondRecord
,
920 if (FirstDiffType
!= SecondDiffType
) {
921 diagnoseSubMismatchDifferentDeclKinds(DR
, FirstRecord
, FirstModule
,
922 SecondRecord
, SecondModule
);
926 // Used with err_module_odr_violation_record and
927 // note_module_odr_violation_record
928 enum ODRCXXRecordDifference
{
929 StaticAssertCondition
,
931 StaticAssertOnlyMessage
,
940 MethodParameterSingleDefaultArgument
,
941 MethodParameterDifferentDefaultArgument
,
942 MethodNoTemplateArguments
,
943 MethodDifferentNumberTemplateArguments
,
944 MethodDifferentTemplateArgument
,
950 FunctionTemplateDifferentNumberParameters
,
951 FunctionTemplateParameterDifferentKind
,
952 FunctionTemplateParameterName
,
953 FunctionTemplateParameterSingleDefaultArgument
,
954 FunctionTemplateParameterDifferentDefaultArgument
,
955 FunctionTemplateParameterDifferentType
,
956 FunctionTemplatePackParameter
,
958 auto DiagError
= [FirstRecord
, &FirstModule
,
959 this](SourceLocation Loc
, SourceRange Range
,
960 ODRCXXRecordDifference DiffType
) {
961 return Diag(Loc
, diag::err_module_odr_violation_record
)
962 << FirstRecord
<< FirstModule
.empty() << FirstModule
<< Range
965 auto DiagNote
= [&SecondModule
, this](SourceLocation Loc
, SourceRange Range
,
966 ODRCXXRecordDifference DiffType
) {
967 return Diag(Loc
, diag::note_module_odr_violation_record
)
968 << SecondModule
<< Range
<< DiffType
;
971 assert(FirstDiffType
== SecondDiffType
);
972 switch (FirstDiffType
) {
976 case PrivateSpecifer
:
977 case ProtectedSpecifer
:
981 llvm_unreachable("Invalid diff type");
984 const StaticAssertDecl
*FirstSA
= cast
<StaticAssertDecl
>(FirstDecl
);
985 const StaticAssertDecl
*SecondSA
= cast
<StaticAssertDecl
>(SecondDecl
);
987 const Expr
*FirstExpr
= FirstSA
->getAssertExpr();
988 const Expr
*SecondExpr
= SecondSA
->getAssertExpr();
989 unsigned FirstODRHash
= computeODRHash(FirstExpr
);
990 unsigned SecondODRHash
= computeODRHash(SecondExpr
);
991 if (FirstODRHash
!= SecondODRHash
) {
992 DiagError(FirstExpr
->getBeginLoc(), FirstExpr
->getSourceRange(),
993 StaticAssertCondition
);
994 DiagNote(SecondExpr
->getBeginLoc(), SecondExpr
->getSourceRange(),
995 StaticAssertCondition
);
999 const Expr
*FirstMessage
= FirstSA
->getMessage();
1000 const Expr
*SecondMessage
= SecondSA
->getMessage();
1001 assert((FirstMessage
|| SecondMessage
) && "Both messages cannot be empty");
1002 if ((FirstMessage
&& !SecondMessage
) || (!FirstMessage
&& SecondMessage
)) {
1003 SourceLocation FirstLoc
, SecondLoc
;
1004 SourceRange FirstRange
, SecondRange
;
1006 FirstLoc
= FirstMessage
->getBeginLoc();
1007 FirstRange
= FirstMessage
->getSourceRange();
1009 FirstLoc
= FirstSA
->getBeginLoc();
1010 FirstRange
= FirstSA
->getSourceRange();
1012 if (SecondMessage
) {
1013 SecondLoc
= SecondMessage
->getBeginLoc();
1014 SecondRange
= SecondMessage
->getSourceRange();
1016 SecondLoc
= SecondSA
->getBeginLoc();
1017 SecondRange
= SecondSA
->getSourceRange();
1019 DiagError(FirstLoc
, FirstRange
, StaticAssertOnlyMessage
)
1020 << (FirstMessage
== nullptr);
1021 DiagNote(SecondLoc
, SecondRange
, StaticAssertOnlyMessage
)
1022 << (SecondMessage
== nullptr);
1026 if (FirstMessage
&& SecondMessage
) {
1027 unsigned FirstMessageODRHash
= computeODRHash(FirstMessage
);
1028 unsigned SecondMessageODRHash
= computeODRHash(SecondMessage
);
1029 if (FirstMessageODRHash
!= SecondMessageODRHash
) {
1030 DiagError(FirstMessage
->getBeginLoc(), FirstMessage
->getSourceRange(),
1031 StaticAssertMessage
);
1032 DiagNote(SecondMessage
->getBeginLoc(), SecondMessage
->getSourceRange(),
1033 StaticAssertMessage
);
1041 if (diagnoseSubMismatchField(FirstRecord
, FirstModule
, SecondModule
,
1042 cast
<FieldDecl
>(FirstDecl
),
1043 cast
<FieldDecl
>(SecondDecl
)))
1055 auto GetMethodTypeForDiagnostics
= [](const CXXMethodDecl
*D
) {
1056 if (isa
<CXXConstructorDecl
>(D
))
1057 return DiagConstructor
;
1058 if (isa
<CXXDestructorDecl
>(D
))
1059 return DiagDestructor
;
1062 const CXXMethodDecl
*FirstMethod
= cast
<CXXMethodDecl
>(FirstDecl
);
1063 const CXXMethodDecl
*SecondMethod
= cast
<CXXMethodDecl
>(SecondDecl
);
1064 FirstMethodType
= GetMethodTypeForDiagnostics(FirstMethod
);
1065 SecondMethodType
= GetMethodTypeForDiagnostics(SecondMethod
);
1066 DeclarationName FirstName
= FirstMethod
->getDeclName();
1067 DeclarationName SecondName
= SecondMethod
->getDeclName();
1068 auto DiagMethodError
= [&DiagError
, FirstMethod
, FirstMethodType
,
1069 FirstName
](ODRCXXRecordDifference DiffType
) {
1070 return DiagError(FirstMethod
->getLocation(),
1071 FirstMethod
->getSourceRange(), DiffType
)
1072 << FirstMethodType
<< FirstName
;
1074 auto DiagMethodNote
= [&DiagNote
, SecondMethod
, SecondMethodType
,
1075 SecondName
](ODRCXXRecordDifference DiffType
) {
1076 return DiagNote(SecondMethod
->getLocation(),
1077 SecondMethod
->getSourceRange(), DiffType
)
1078 << SecondMethodType
<< SecondName
;
1081 if (FirstMethodType
!= SecondMethodType
|| FirstName
!= SecondName
) {
1082 DiagMethodError(MethodName
);
1083 DiagMethodNote(MethodName
);
1087 const bool FirstDeleted
= FirstMethod
->isDeletedAsWritten();
1088 const bool SecondDeleted
= SecondMethod
->isDeletedAsWritten();
1089 if (FirstDeleted
!= SecondDeleted
) {
1090 DiagMethodError(MethodDeleted
) << FirstDeleted
;
1091 DiagMethodNote(MethodDeleted
) << SecondDeleted
;
1095 const bool FirstDefaulted
= FirstMethod
->isExplicitlyDefaulted();
1096 const bool SecondDefaulted
= SecondMethod
->isExplicitlyDefaulted();
1097 if (FirstDefaulted
!= SecondDefaulted
) {
1098 DiagMethodError(MethodDefaulted
) << FirstDefaulted
;
1099 DiagMethodNote(MethodDefaulted
) << SecondDefaulted
;
1103 const bool FirstVirtual
= FirstMethod
->isVirtualAsWritten();
1104 const bool SecondVirtual
= SecondMethod
->isVirtualAsWritten();
1105 const bool FirstPure
= FirstMethod
->isPure();
1106 const bool SecondPure
= SecondMethod
->isPure();
1107 if ((FirstVirtual
|| SecondVirtual
) &&
1108 (FirstVirtual
!= SecondVirtual
|| FirstPure
!= SecondPure
)) {
1109 DiagMethodError(MethodVirtual
) << FirstPure
<< FirstVirtual
;
1110 DiagMethodNote(MethodVirtual
) << SecondPure
<< SecondVirtual
;
1114 // CXXMethodDecl::isStatic uses the canonical Decl. With Decl merging,
1115 // FirstDecl is the canonical Decl of SecondDecl, so the storage
1116 // class needs to be checked instead.
1117 StorageClass FirstStorage
= FirstMethod
->getStorageClass();
1118 StorageClass SecondStorage
= SecondMethod
->getStorageClass();
1119 const bool FirstStatic
= FirstStorage
== SC_Static
;
1120 const bool SecondStatic
= SecondStorage
== SC_Static
;
1121 if (FirstStatic
!= SecondStatic
) {
1122 DiagMethodError(MethodStatic
) << FirstStatic
;
1123 DiagMethodNote(MethodStatic
) << SecondStatic
;
1127 const bool FirstVolatile
= FirstMethod
->isVolatile();
1128 const bool SecondVolatile
= SecondMethod
->isVolatile();
1129 if (FirstVolatile
!= SecondVolatile
) {
1130 DiagMethodError(MethodVolatile
) << FirstVolatile
;
1131 DiagMethodNote(MethodVolatile
) << SecondVolatile
;
1135 const bool FirstConst
= FirstMethod
->isConst();
1136 const bool SecondConst
= SecondMethod
->isConst();
1137 if (FirstConst
!= SecondConst
) {
1138 DiagMethodError(MethodConst
) << FirstConst
;
1139 DiagMethodNote(MethodConst
) << SecondConst
;
1143 const bool FirstInline
= FirstMethod
->isInlineSpecified();
1144 const bool SecondInline
= SecondMethod
->isInlineSpecified();
1145 if (FirstInline
!= SecondInline
) {
1146 DiagMethodError(MethodInline
) << FirstInline
;
1147 DiagMethodNote(MethodInline
) << SecondInline
;
1151 if (diagnoseSubMismatchMethodParameters(Diags
, FirstRecord
,
1152 FirstModule
, SecondModule
,
1153 FirstMethod
, SecondMethod
))
1156 for (unsigned I
= 0, N
= FirstMethod
->param_size(); I
< N
; ++I
) {
1157 const ParmVarDecl
*FirstParam
= FirstMethod
->getParamDecl(I
);
1158 const ParmVarDecl
*SecondParam
= SecondMethod
->getParamDecl(I
);
1160 const Expr
*FirstInit
= FirstParam
->getInit();
1161 const Expr
*SecondInit
= SecondParam
->getInit();
1162 if ((FirstInit
== nullptr) != (SecondInit
== nullptr)) {
1163 DiagMethodError(MethodParameterSingleDefaultArgument
)
1164 << (I
+ 1) << (FirstInit
== nullptr)
1165 << (FirstInit
? FirstInit
->getSourceRange() : SourceRange());
1166 DiagMethodNote(MethodParameterSingleDefaultArgument
)
1167 << (I
+ 1) << (SecondInit
== nullptr)
1168 << (SecondInit
? SecondInit
->getSourceRange() : SourceRange());
1172 if (FirstInit
&& SecondInit
&&
1173 computeODRHash(FirstInit
) != computeODRHash(SecondInit
)) {
1174 DiagMethodError(MethodParameterDifferentDefaultArgument
)
1175 << (I
+ 1) << FirstInit
->getSourceRange();
1176 DiagMethodNote(MethodParameterDifferentDefaultArgument
)
1177 << (I
+ 1) << SecondInit
->getSourceRange();
1182 const TemplateArgumentList
*FirstTemplateArgs
=
1183 FirstMethod
->getTemplateSpecializationArgs();
1184 const TemplateArgumentList
*SecondTemplateArgs
=
1185 SecondMethod
->getTemplateSpecializationArgs();
1187 if ((FirstTemplateArgs
&& !SecondTemplateArgs
) ||
1188 (!FirstTemplateArgs
&& SecondTemplateArgs
)) {
1189 DiagMethodError(MethodNoTemplateArguments
)
1190 << (FirstTemplateArgs
!= nullptr);
1191 DiagMethodNote(MethodNoTemplateArguments
)
1192 << (SecondTemplateArgs
!= nullptr);
1196 if (FirstTemplateArgs
&& SecondTemplateArgs
) {
1197 // Remove pack expansions from argument list.
1198 auto ExpandTemplateArgumentList
= [](const TemplateArgumentList
*TAL
) {
1199 llvm::SmallVector
<const TemplateArgument
*, 8> ExpandedList
;
1200 for (const TemplateArgument
&TA
: TAL
->asArray()) {
1201 if (TA
.getKind() != TemplateArgument::Pack
) {
1202 ExpandedList
.push_back(&TA
);
1205 llvm::append_range(ExpandedList
,
1206 llvm::make_pointer_range(TA
.getPackAsArray()));
1208 return ExpandedList
;
1210 llvm::SmallVector
<const TemplateArgument
*, 8> FirstExpandedList
=
1211 ExpandTemplateArgumentList(FirstTemplateArgs
);
1212 llvm::SmallVector
<const TemplateArgument
*, 8> SecondExpandedList
=
1213 ExpandTemplateArgumentList(SecondTemplateArgs
);
1215 if (FirstExpandedList
.size() != SecondExpandedList
.size()) {
1216 DiagMethodError(MethodDifferentNumberTemplateArguments
)
1217 << (unsigned)FirstExpandedList
.size();
1218 DiagMethodNote(MethodDifferentNumberTemplateArguments
)
1219 << (unsigned)SecondExpandedList
.size();
1223 for (unsigned i
= 0, e
= FirstExpandedList
.size(); i
!= e
; ++i
) {
1224 const TemplateArgument
&FirstTA
= *FirstExpandedList
[i
],
1225 &SecondTA
= *SecondExpandedList
[i
];
1226 if (computeODRHash(FirstTA
) == computeODRHash(SecondTA
))
1229 DiagMethodError(MethodDifferentTemplateArgument
) << FirstTA
<< i
+ 1;
1230 DiagMethodNote(MethodDifferentTemplateArgument
) << SecondTA
<< i
+ 1;
1235 // Compute the hash of the method as if it has no body.
1236 auto ComputeCXXMethodODRHash
= [](const CXXMethodDecl
*D
) {
1238 Hasher
.AddFunctionDecl(D
, true /*SkipBody*/);
1239 return Hasher
.CalculateHash();
1242 // Compare the hash generated to the hash stored. A difference means
1243 // that a body was present in the original source. Due to merging,
1244 // the standard way of detecting a body will not work.
1245 const bool HasFirstBody
=
1246 ComputeCXXMethodODRHash(FirstMethod
) != FirstMethod
->getODRHash();
1247 const bool HasSecondBody
=
1248 ComputeCXXMethodODRHash(SecondMethod
) != SecondMethod
->getODRHash();
1250 if (HasFirstBody
!= HasSecondBody
) {
1251 DiagMethodError(MethodSingleBody
) << HasFirstBody
;
1252 DiagMethodNote(MethodSingleBody
) << HasSecondBody
;
1256 if (HasFirstBody
&& HasSecondBody
) {
1257 DiagMethodError(MethodDifferentBody
);
1258 DiagMethodNote(MethodDifferentBody
);
1267 if (diagnoseSubMismatchTypedef(FirstRecord
, FirstModule
, SecondModule
,
1268 cast
<TypedefNameDecl
>(FirstDecl
),
1269 cast
<TypedefNameDecl
>(SecondDecl
),
1270 FirstDiffType
== TypeAlias
))
1275 if (diagnoseSubMismatchVar(FirstRecord
, FirstModule
, SecondModule
,
1276 cast
<VarDecl
>(FirstDecl
),
1277 cast
<VarDecl
>(SecondDecl
)))
1282 const FriendDecl
*FirstFriend
= cast
<FriendDecl
>(FirstDecl
);
1283 const FriendDecl
*SecondFriend
= cast
<FriendDecl
>(SecondDecl
);
1285 const NamedDecl
*FirstND
= FirstFriend
->getFriendDecl();
1286 const NamedDecl
*SecondND
= SecondFriend
->getFriendDecl();
1288 TypeSourceInfo
*FirstTSI
= FirstFriend
->getFriendType();
1289 TypeSourceInfo
*SecondTSI
= SecondFriend
->getFriendType();
1291 if (FirstND
&& SecondND
) {
1292 DiagError(FirstFriend
->getFriendLoc(), FirstFriend
->getSourceRange(),
1295 DiagNote(SecondFriend
->getFriendLoc(), SecondFriend
->getSourceRange(),
1301 if (FirstTSI
&& SecondTSI
) {
1302 QualType FirstFriendType
= FirstTSI
->getType();
1303 QualType SecondFriendType
= SecondTSI
->getType();
1304 assert(computeODRHash(FirstFriendType
) !=
1305 computeODRHash(SecondFriendType
));
1306 DiagError(FirstFriend
->getFriendLoc(), FirstFriend
->getSourceRange(),
1309 DiagNote(SecondFriend
->getFriendLoc(), SecondFriend
->getSourceRange(),
1311 << SecondFriendType
;
1315 DiagError(FirstFriend
->getFriendLoc(), FirstFriend
->getSourceRange(),
1317 << (FirstTSI
== nullptr);
1318 DiagNote(SecondFriend
->getFriendLoc(), SecondFriend
->getSourceRange(),
1320 << (SecondTSI
== nullptr);
1323 case FunctionTemplate
: {
1324 const FunctionTemplateDecl
*FirstTemplate
=
1325 cast
<FunctionTemplateDecl
>(FirstDecl
);
1326 const FunctionTemplateDecl
*SecondTemplate
=
1327 cast
<FunctionTemplateDecl
>(SecondDecl
);
1329 TemplateParameterList
*FirstTPL
= FirstTemplate
->getTemplateParameters();
1330 TemplateParameterList
*SecondTPL
= SecondTemplate
->getTemplateParameters();
1332 auto DiagTemplateError
= [&DiagError
,
1333 FirstTemplate
](ODRCXXRecordDifference DiffType
) {
1334 return DiagError(FirstTemplate
->getLocation(),
1335 FirstTemplate
->getSourceRange(), DiffType
)
1338 auto DiagTemplateNote
= [&DiagNote
,
1339 SecondTemplate
](ODRCXXRecordDifference DiffType
) {
1340 return DiagNote(SecondTemplate
->getLocation(),
1341 SecondTemplate
->getSourceRange(), DiffType
)
1345 if (FirstTPL
->size() != SecondTPL
->size()) {
1346 DiagTemplateError(FunctionTemplateDifferentNumberParameters
)
1347 << FirstTPL
->size();
1348 DiagTemplateNote(FunctionTemplateDifferentNumberParameters
)
1349 << SecondTPL
->size();
1353 for (unsigned i
= 0, e
= FirstTPL
->size(); i
!= e
; ++i
) {
1354 NamedDecl
*FirstParam
= FirstTPL
->getParam(i
);
1355 NamedDecl
*SecondParam
= SecondTPL
->getParam(i
);
1357 if (FirstParam
->getKind() != SecondParam
->getKind()) {
1359 TemplateTypeParameter
,
1360 NonTypeTemplateParameter
,
1361 TemplateTemplateParameter
,
1363 auto GetParamType
= [](NamedDecl
*D
) {
1364 switch (D
->getKind()) {
1366 llvm_unreachable("Unexpected template parameter type");
1367 case Decl::TemplateTypeParm
:
1368 return TemplateTypeParameter
;
1369 case Decl::NonTypeTemplateParm
:
1370 return NonTypeTemplateParameter
;
1371 case Decl::TemplateTemplateParm
:
1372 return TemplateTemplateParameter
;
1376 DiagTemplateError(FunctionTemplateParameterDifferentKind
)
1377 << (i
+ 1) << GetParamType(FirstParam
);
1378 DiagTemplateNote(FunctionTemplateParameterDifferentKind
)
1379 << (i
+ 1) << GetParamType(SecondParam
);
1383 if (FirstParam
->getName() != SecondParam
->getName()) {
1384 DiagTemplateError(FunctionTemplateParameterName
)
1385 << (i
+ 1) << (bool)FirstParam
->getIdentifier() << FirstParam
;
1386 DiagTemplateNote(FunctionTemplateParameterName
)
1387 << (i
+ 1) << (bool)SecondParam
->getIdentifier() << SecondParam
;
1391 if (isa
<TemplateTypeParmDecl
>(FirstParam
) &&
1392 isa
<TemplateTypeParmDecl
>(SecondParam
)) {
1393 TemplateTypeParmDecl
*FirstTTPD
=
1394 cast
<TemplateTypeParmDecl
>(FirstParam
);
1395 TemplateTypeParmDecl
*SecondTTPD
=
1396 cast
<TemplateTypeParmDecl
>(SecondParam
);
1397 bool HasFirstDefaultArgument
=
1398 FirstTTPD
->hasDefaultArgument() &&
1399 !FirstTTPD
->defaultArgumentWasInherited();
1400 bool HasSecondDefaultArgument
=
1401 SecondTTPD
->hasDefaultArgument() &&
1402 !SecondTTPD
->defaultArgumentWasInherited();
1403 if (HasFirstDefaultArgument
!= HasSecondDefaultArgument
) {
1404 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument
)
1405 << (i
+ 1) << HasFirstDefaultArgument
;
1406 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument
)
1407 << (i
+ 1) << HasSecondDefaultArgument
;
1411 if (HasFirstDefaultArgument
&& HasSecondDefaultArgument
) {
1412 QualType FirstType
= FirstTTPD
->getDefaultArgument();
1413 QualType SecondType
= SecondTTPD
->getDefaultArgument();
1414 if (computeODRHash(FirstType
) != computeODRHash(SecondType
)) {
1415 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument
)
1416 << (i
+ 1) << FirstType
;
1417 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument
)
1418 << (i
+ 1) << SecondType
;
1423 if (FirstTTPD
->isParameterPack() != SecondTTPD
->isParameterPack()) {
1424 DiagTemplateError(FunctionTemplatePackParameter
)
1425 << (i
+ 1) << FirstTTPD
->isParameterPack();
1426 DiagTemplateNote(FunctionTemplatePackParameter
)
1427 << (i
+ 1) << SecondTTPD
->isParameterPack();
1432 if (isa
<TemplateTemplateParmDecl
>(FirstParam
) &&
1433 isa
<TemplateTemplateParmDecl
>(SecondParam
)) {
1434 TemplateTemplateParmDecl
*FirstTTPD
=
1435 cast
<TemplateTemplateParmDecl
>(FirstParam
);
1436 TemplateTemplateParmDecl
*SecondTTPD
=
1437 cast
<TemplateTemplateParmDecl
>(SecondParam
);
1439 TemplateParameterList
*FirstTPL
= FirstTTPD
->getTemplateParameters();
1440 TemplateParameterList
*SecondTPL
= SecondTTPD
->getTemplateParameters();
1442 auto ComputeTemplateParameterListODRHash
=
1443 [](const TemplateParameterList
*TPL
) {
1446 Hasher
.AddTemplateParameterList(TPL
);
1447 return Hasher
.CalculateHash();
1450 if (ComputeTemplateParameterListODRHash(FirstTPL
) !=
1451 ComputeTemplateParameterListODRHash(SecondTPL
)) {
1452 DiagTemplateError(FunctionTemplateParameterDifferentType
) << (i
+ 1);
1453 DiagTemplateNote(FunctionTemplateParameterDifferentType
) << (i
+ 1);
1457 bool HasFirstDefaultArgument
=
1458 FirstTTPD
->hasDefaultArgument() &&
1459 !FirstTTPD
->defaultArgumentWasInherited();
1460 bool HasSecondDefaultArgument
=
1461 SecondTTPD
->hasDefaultArgument() &&
1462 !SecondTTPD
->defaultArgumentWasInherited();
1463 if (HasFirstDefaultArgument
!= HasSecondDefaultArgument
) {
1464 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument
)
1465 << (i
+ 1) << HasFirstDefaultArgument
;
1466 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument
)
1467 << (i
+ 1) << HasSecondDefaultArgument
;
1471 if (HasFirstDefaultArgument
&& HasSecondDefaultArgument
) {
1472 TemplateArgument FirstTA
=
1473 FirstTTPD
->getDefaultArgument().getArgument();
1474 TemplateArgument SecondTA
=
1475 SecondTTPD
->getDefaultArgument().getArgument();
1476 if (computeODRHash(FirstTA
) != computeODRHash(SecondTA
)) {
1477 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument
)
1478 << (i
+ 1) << FirstTA
;
1479 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument
)
1480 << (i
+ 1) << SecondTA
;
1485 if (FirstTTPD
->isParameterPack() != SecondTTPD
->isParameterPack()) {
1486 DiagTemplateError(FunctionTemplatePackParameter
)
1487 << (i
+ 1) << FirstTTPD
->isParameterPack();
1488 DiagTemplateNote(FunctionTemplatePackParameter
)
1489 << (i
+ 1) << SecondTTPD
->isParameterPack();
1494 if (isa
<NonTypeTemplateParmDecl
>(FirstParam
) &&
1495 isa
<NonTypeTemplateParmDecl
>(SecondParam
)) {
1496 NonTypeTemplateParmDecl
*FirstNTTPD
=
1497 cast
<NonTypeTemplateParmDecl
>(FirstParam
);
1498 NonTypeTemplateParmDecl
*SecondNTTPD
=
1499 cast
<NonTypeTemplateParmDecl
>(SecondParam
);
1501 QualType FirstType
= FirstNTTPD
->getType();
1502 QualType SecondType
= SecondNTTPD
->getType();
1503 if (computeODRHash(FirstType
) != computeODRHash(SecondType
)) {
1504 DiagTemplateError(FunctionTemplateParameterDifferentType
) << (i
+ 1);
1505 DiagTemplateNote(FunctionTemplateParameterDifferentType
) << (i
+ 1);
1509 bool HasFirstDefaultArgument
=
1510 FirstNTTPD
->hasDefaultArgument() &&
1511 !FirstNTTPD
->defaultArgumentWasInherited();
1512 bool HasSecondDefaultArgument
=
1513 SecondNTTPD
->hasDefaultArgument() &&
1514 !SecondNTTPD
->defaultArgumentWasInherited();
1515 if (HasFirstDefaultArgument
!= HasSecondDefaultArgument
) {
1516 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument
)
1517 << (i
+ 1) << HasFirstDefaultArgument
;
1518 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument
)
1519 << (i
+ 1) << HasSecondDefaultArgument
;
1523 if (HasFirstDefaultArgument
&& HasSecondDefaultArgument
) {
1524 Expr
*FirstDefaultArgument
= FirstNTTPD
->getDefaultArgument();
1525 Expr
*SecondDefaultArgument
= SecondNTTPD
->getDefaultArgument();
1526 if (computeODRHash(FirstDefaultArgument
) !=
1527 computeODRHash(SecondDefaultArgument
)) {
1528 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument
)
1529 << (i
+ 1) << FirstDefaultArgument
;
1530 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument
)
1531 << (i
+ 1) << SecondDefaultArgument
;
1536 if (FirstNTTPD
->isParameterPack() != SecondNTTPD
->isParameterPack()) {
1537 DiagTemplateError(FunctionTemplatePackParameter
)
1538 << (i
+ 1) << FirstNTTPD
->isParameterPack();
1539 DiagTemplateNote(FunctionTemplatePackParameter
)
1540 << (i
+ 1) << SecondNTTPD
->isParameterPack();
1549 Diag(FirstDecl
->getLocation(),
1550 diag::err_module_odr_violation_mismatch_decl_unknown
)
1551 << FirstRecord
<< FirstModule
.empty() << FirstModule
<< FirstDiffType
1552 << FirstDecl
->getSourceRange();
1553 Diag(SecondDecl
->getLocation(),
1554 diag::note_module_odr_violation_mismatch_decl_unknown
)
1555 << SecondModule
.empty() << SecondModule
<< FirstDiffType
1556 << SecondDecl
->getSourceRange();
1560 bool ODRDiagsEmitter::diagnoseMismatch(const RecordDecl
*FirstRecord
,
1561 const RecordDecl
*SecondRecord
) const {
1562 if (FirstRecord
== SecondRecord
)
1565 std::string FirstModule
= getOwningModuleNameForDiagnostic(FirstRecord
);
1566 std::string SecondModule
= getOwningModuleNameForDiagnostic(SecondRecord
);
1568 auto PopulateHashes
= [](DeclHashes
&Hashes
, const RecordDecl
*Record
,
1569 const DeclContext
*DC
) {
1570 for (const Decl
*D
: Record
->decls()) {
1571 if (!ODRHash::isSubDeclToBeProcessed(D
, DC
))
1573 Hashes
.emplace_back(D
, computeODRHash(D
));
1577 DeclHashes FirstHashes
;
1578 DeclHashes SecondHashes
;
1579 const DeclContext
*DC
= FirstRecord
;
1580 PopulateHashes(FirstHashes
, FirstRecord
, DC
);
1581 PopulateHashes(SecondHashes
, SecondRecord
, DC
);
1583 DiffResult DR
= FindTypeDiffs(FirstHashes
, SecondHashes
);
1584 ODRMismatchDecl FirstDiffType
= DR
.FirstDiffType
;
1585 ODRMismatchDecl SecondDiffType
= DR
.SecondDiffType
;
1586 const Decl
*FirstDecl
= DR
.FirstDecl
;
1587 const Decl
*SecondDecl
= DR
.SecondDecl
;
1589 if (FirstDiffType
== Other
|| SecondDiffType
== Other
) {
1590 diagnoseSubMismatchUnexpected(DR
, FirstRecord
, FirstModule
, SecondRecord
,
1595 if (FirstDiffType
!= SecondDiffType
) {
1596 diagnoseSubMismatchDifferentDeclKinds(DR
, FirstRecord
, FirstModule
,
1597 SecondRecord
, SecondModule
);
1601 assert(FirstDiffType
== SecondDiffType
);
1602 switch (FirstDiffType
) {
1606 // C++ only, invalid in this context.
1607 case PublicSpecifer
:
1608 case PrivateSpecifer
:
1609 case ProtectedSpecifer
:
1614 case FunctionTemplate
:
1615 // Cannot be contained by RecordDecl, invalid in this context.
1619 llvm_unreachable("Invalid diff type");
1622 if (diagnoseSubMismatchField(FirstRecord
, FirstModule
, SecondModule
,
1623 cast
<FieldDecl
>(FirstDecl
),
1624 cast
<FieldDecl
>(SecondDecl
)))
1629 if (diagnoseSubMismatchTypedef(FirstRecord
, FirstModule
, SecondModule
,
1630 cast
<TypedefNameDecl
>(FirstDecl
),
1631 cast
<TypedefNameDecl
>(SecondDecl
),
1632 /*IsTypeAlias=*/false))
1637 if (diagnoseSubMismatchVar(FirstRecord
, FirstModule
, SecondModule
,
1638 cast
<VarDecl
>(FirstDecl
),
1639 cast
<VarDecl
>(SecondDecl
)))
1645 Diag(FirstDecl
->getLocation(),
1646 diag::err_module_odr_violation_mismatch_decl_unknown
)
1647 << FirstRecord
<< FirstModule
.empty() << FirstModule
<< FirstDiffType
1648 << FirstDecl
->getSourceRange();
1649 Diag(SecondDecl
->getLocation(),
1650 diag::note_module_odr_violation_mismatch_decl_unknown
)
1651 << SecondModule
.empty() << SecondModule
<< FirstDiffType
1652 << SecondDecl
->getSourceRange();
1656 bool ODRDiagsEmitter::diagnoseMismatch(
1657 const FunctionDecl
*FirstFunction
,
1658 const FunctionDecl
*SecondFunction
) const {
1659 if (FirstFunction
== SecondFunction
)
1662 // Keep in sync with select options in err_module_odr_violation_function.
1663 enum ODRFunctionDifference
{
1667 ParameterSingleDefaultArgument
,
1668 ParameterDifferentDefaultArgument
,
1672 std::string FirstModule
= getOwningModuleNameForDiagnostic(FirstFunction
);
1673 std::string SecondModule
= getOwningModuleNameForDiagnostic(SecondFunction
);
1675 auto DiagError
= [FirstFunction
, &FirstModule
,
1676 this](SourceLocation Loc
, SourceRange Range
,
1677 ODRFunctionDifference DiffType
) {
1678 return Diag(Loc
, diag::err_module_odr_violation_function
)
1679 << FirstFunction
<< FirstModule
.empty() << FirstModule
<< Range
1682 auto DiagNote
= [&SecondModule
, this](SourceLocation Loc
, SourceRange Range
,
1683 ODRFunctionDifference DiffType
) {
1684 return Diag(Loc
, diag::note_module_odr_violation_function
)
1685 << SecondModule
<< Range
<< DiffType
;
1688 if (computeODRHash(FirstFunction
->getReturnType()) !=
1689 computeODRHash(SecondFunction
->getReturnType())) {
1690 DiagError(FirstFunction
->getReturnTypeSourceRange().getBegin(),
1691 FirstFunction
->getReturnTypeSourceRange(), ReturnType
)
1692 << FirstFunction
->getReturnType();
1693 DiagNote(SecondFunction
->getReturnTypeSourceRange().getBegin(),
1694 SecondFunction
->getReturnTypeSourceRange(), ReturnType
)
1695 << SecondFunction
->getReturnType();
1699 assert(FirstFunction
->param_size() == SecondFunction
->param_size() &&
1700 "Merged functions with different number of parameters");
1702 size_t ParamSize
= FirstFunction
->param_size();
1703 for (unsigned I
= 0; I
< ParamSize
; ++I
) {
1704 const ParmVarDecl
*FirstParam
= FirstFunction
->getParamDecl(I
);
1705 const ParmVarDecl
*SecondParam
= SecondFunction
->getParamDecl(I
);
1707 assert(Context
.hasSameType(FirstParam
->getType(), SecondParam
->getType()) &&
1708 "Merged function has different parameter types.");
1710 if (FirstParam
->getDeclName() != SecondParam
->getDeclName()) {
1711 DiagError(FirstParam
->getLocation(), FirstParam
->getSourceRange(),
1713 << I
+ 1 << FirstParam
->getDeclName();
1714 DiagNote(SecondParam
->getLocation(), SecondParam
->getSourceRange(),
1716 << I
+ 1 << SecondParam
->getDeclName();
1720 QualType FirstParamType
= FirstParam
->getType();
1721 QualType SecondParamType
= SecondParam
->getType();
1722 if (FirstParamType
!= SecondParamType
&&
1723 computeODRHash(FirstParamType
) != computeODRHash(SecondParamType
)) {
1724 if (const DecayedType
*ParamDecayedType
=
1725 FirstParamType
->getAs
<DecayedType
>()) {
1726 DiagError(FirstParam
->getLocation(), FirstParam
->getSourceRange(),
1728 << (I
+ 1) << FirstParamType
<< true
1729 << ParamDecayedType
->getOriginalType();
1731 DiagError(FirstParam
->getLocation(), FirstParam
->getSourceRange(),
1733 << (I
+ 1) << FirstParamType
<< false;
1736 if (const DecayedType
*ParamDecayedType
=
1737 SecondParamType
->getAs
<DecayedType
>()) {
1738 DiagNote(SecondParam
->getLocation(), SecondParam
->getSourceRange(),
1740 << (I
+ 1) << SecondParamType
<< true
1741 << ParamDecayedType
->getOriginalType();
1743 DiagNote(SecondParam
->getLocation(), SecondParam
->getSourceRange(),
1745 << (I
+ 1) << SecondParamType
<< false;
1750 // Note, these calls can trigger deserialization.
1751 const Expr
*FirstInit
= FirstParam
->getInit();
1752 const Expr
*SecondInit
= SecondParam
->getInit();
1753 if ((FirstInit
== nullptr) != (SecondInit
== nullptr)) {
1754 DiagError(FirstParam
->getLocation(), FirstParam
->getSourceRange(),
1755 ParameterSingleDefaultArgument
)
1756 << (I
+ 1) << (FirstInit
== nullptr)
1757 << (FirstInit
? FirstInit
->getSourceRange() : SourceRange());
1758 DiagNote(SecondParam
->getLocation(), SecondParam
->getSourceRange(),
1759 ParameterSingleDefaultArgument
)
1760 << (I
+ 1) << (SecondInit
== nullptr)
1761 << (SecondInit
? SecondInit
->getSourceRange() : SourceRange());
1765 if (FirstInit
&& SecondInit
&&
1766 computeODRHash(FirstInit
) != computeODRHash(SecondInit
)) {
1767 DiagError(FirstParam
->getLocation(), FirstParam
->getSourceRange(),
1768 ParameterDifferentDefaultArgument
)
1769 << (I
+ 1) << FirstInit
->getSourceRange();
1770 DiagNote(SecondParam
->getLocation(), SecondParam
->getSourceRange(),
1771 ParameterDifferentDefaultArgument
)
1772 << (I
+ 1) << SecondInit
->getSourceRange();
1776 assert(computeODRHash(FirstParam
) == computeODRHash(SecondParam
) &&
1777 "Undiagnosed parameter difference.");
1780 // If no error has been generated before now, assume the problem is in
1781 // the body and generate a message.
1782 DiagError(FirstFunction
->getLocation(), FirstFunction
->getSourceRange(),
1784 DiagNote(SecondFunction
->getLocation(), SecondFunction
->getSourceRange(),
1789 bool ODRDiagsEmitter::diagnoseMismatch(const EnumDecl
*FirstEnum
,
1790 const EnumDecl
*SecondEnum
) const {
1791 if (FirstEnum
== SecondEnum
)
1794 // Keep in sync with select options in err_module_odr_violation_enum.
1795 enum ODREnumDifference
{
1797 EnumTagKeywordMismatch
,
1798 SingleSpecifiedType
,
1799 DifferentSpecifiedTypes
,
1800 DifferentNumberEnumConstants
,
1802 EnumConstantSingleInitializer
,
1803 EnumConstantDifferentInitializer
,
1806 std::string FirstModule
= getOwningModuleNameForDiagnostic(FirstEnum
);
1807 std::string SecondModule
= getOwningModuleNameForDiagnostic(SecondEnum
);
1809 auto DiagError
= [FirstEnum
, &FirstModule
, this](const auto *DiagAnchor
,
1810 ODREnumDifference DiffType
) {
1811 return Diag(DiagAnchor
->getLocation(), diag::err_module_odr_violation_enum
)
1812 << FirstEnum
<< FirstModule
.empty() << FirstModule
1813 << DiagAnchor
->getSourceRange() << DiffType
;
1815 auto DiagNote
= [&SecondModule
, this](const auto *DiagAnchor
,
1816 ODREnumDifference DiffType
) {
1817 return Diag(DiagAnchor
->getLocation(), diag::note_module_odr_violation_enum
)
1818 << SecondModule
<< DiagAnchor
->getSourceRange() << DiffType
;
1821 if (FirstEnum
->isScoped() != SecondEnum
->isScoped()) {
1822 DiagError(FirstEnum
, SingleScopedEnum
) << FirstEnum
->isScoped();
1823 DiagNote(SecondEnum
, SingleScopedEnum
) << SecondEnum
->isScoped();
1827 if (FirstEnum
->isScoped() && SecondEnum
->isScoped()) {
1828 if (FirstEnum
->isScopedUsingClassTag() !=
1829 SecondEnum
->isScopedUsingClassTag()) {
1830 DiagError(FirstEnum
, EnumTagKeywordMismatch
)
1831 << FirstEnum
->isScopedUsingClassTag();
1832 DiagNote(SecondEnum
, EnumTagKeywordMismatch
)
1833 << SecondEnum
->isScopedUsingClassTag();
1838 QualType FirstUnderlyingType
=
1839 FirstEnum
->getIntegerTypeSourceInfo()
1840 ? FirstEnum
->getIntegerTypeSourceInfo()->getType()
1842 QualType SecondUnderlyingType
=
1843 SecondEnum
->getIntegerTypeSourceInfo()
1844 ? SecondEnum
->getIntegerTypeSourceInfo()->getType()
1846 if (FirstUnderlyingType
.isNull() != SecondUnderlyingType
.isNull()) {
1847 DiagError(FirstEnum
, SingleSpecifiedType
) << !FirstUnderlyingType
.isNull();
1848 DiagNote(SecondEnum
, SingleSpecifiedType
) << !SecondUnderlyingType
.isNull();
1852 if (!FirstUnderlyingType
.isNull() && !SecondUnderlyingType
.isNull()) {
1853 if (computeODRHash(FirstUnderlyingType
) !=
1854 computeODRHash(SecondUnderlyingType
)) {
1855 DiagError(FirstEnum
, DifferentSpecifiedTypes
) << FirstUnderlyingType
;
1856 DiagNote(SecondEnum
, DifferentSpecifiedTypes
) << SecondUnderlyingType
;
1861 // Compare enum constants.
1863 llvm::SmallVector
<std::pair
<const EnumConstantDecl
*, unsigned>, 4>;
1864 auto PopulateHashes
= [FirstEnum
](DeclHashes
&Hashes
, const EnumDecl
*Enum
) {
1865 for (const Decl
*D
: Enum
->decls()) {
1866 // Due to decl merging, the first EnumDecl is the parent of
1867 // Decls in both records.
1868 if (!ODRHash::isSubDeclToBeProcessed(D
, FirstEnum
))
1870 assert(isa
<EnumConstantDecl
>(D
) && "Unexpected Decl kind");
1871 Hashes
.emplace_back(cast
<EnumConstantDecl
>(D
), computeODRHash(D
));
1874 DeclHashes FirstHashes
;
1875 PopulateHashes(FirstHashes
, FirstEnum
);
1876 DeclHashes SecondHashes
;
1877 PopulateHashes(SecondHashes
, SecondEnum
);
1879 if (FirstHashes
.size() != SecondHashes
.size()) {
1880 DiagError(FirstEnum
, DifferentNumberEnumConstants
)
1881 << (int)FirstHashes
.size();
1882 DiagNote(SecondEnum
, DifferentNumberEnumConstants
)
1883 << (int)SecondHashes
.size();
1887 for (unsigned I
= 0, N
= FirstHashes
.size(); I
< N
; ++I
) {
1888 if (FirstHashes
[I
].second
== SecondHashes
[I
].second
)
1890 const EnumConstantDecl
*FirstConstant
= FirstHashes
[I
].first
;
1891 const EnumConstantDecl
*SecondConstant
= SecondHashes
[I
].first
;
1893 if (FirstConstant
->getDeclName() != SecondConstant
->getDeclName()) {
1894 DiagError(FirstConstant
, EnumConstantName
) << I
+ 1 << FirstConstant
;
1895 DiagNote(SecondConstant
, EnumConstantName
) << I
+ 1 << SecondConstant
;
1899 const Expr
*FirstInit
= FirstConstant
->getInitExpr();
1900 const Expr
*SecondInit
= SecondConstant
->getInitExpr();
1901 if (!FirstInit
&& !SecondInit
)
1904 if (!FirstInit
|| !SecondInit
) {
1905 DiagError(FirstConstant
, EnumConstantSingleInitializer
)
1906 << I
+ 1 << FirstConstant
<< (FirstInit
!= nullptr);
1907 DiagNote(SecondConstant
, EnumConstantSingleInitializer
)
1908 << I
+ 1 << SecondConstant
<< (SecondInit
!= nullptr);
1912 if (computeODRHash(FirstInit
) != computeODRHash(SecondInit
)) {
1913 DiagError(FirstConstant
, EnumConstantDifferentInitializer
)
1914 << I
+ 1 << FirstConstant
;
1915 DiagNote(SecondConstant
, EnumConstantDifferentInitializer
)
1916 << I
+ 1 << SecondConstant
;
1923 bool ODRDiagsEmitter::diagnoseMismatch(
1924 const ObjCInterfaceDecl
*FirstID
, const ObjCInterfaceDecl
*SecondID
,
1925 const struct ObjCInterfaceDecl::DefinitionData
*SecondDD
) const {
1926 // Multiple different declarations got merged together; tell the user
1927 // where they came from.
1928 if (FirstID
== SecondID
)
1931 std::string FirstModule
= getOwningModuleNameForDiagnostic(FirstID
);
1932 std::string SecondModule
= getOwningModuleNameForDiagnostic(SecondID
);
1934 // Keep in sync with err_module_odr_violation_objc_interface.
1935 enum ODRInterfaceDifference
{
1940 auto DiagError
= [FirstID
, &FirstModule
,
1941 this](SourceLocation Loc
, SourceRange Range
,
1942 ODRInterfaceDifference DiffType
) {
1943 return Diag(Loc
, diag::err_module_odr_violation_objc_interface
)
1944 << FirstID
<< FirstModule
.empty() << FirstModule
<< Range
1947 auto DiagNote
= [&SecondModule
, this](SourceLocation Loc
, SourceRange Range
,
1948 ODRInterfaceDifference DiffType
) {
1949 return Diag(Loc
, diag::note_module_odr_violation_objc_interface
)
1950 << SecondModule
.empty() << SecondModule
<< Range
<< DiffType
;
1953 const struct ObjCInterfaceDecl::DefinitionData
*FirstDD
= &FirstID
->data();
1954 assert(FirstDD
&& SecondDD
&& "Definitions without DefinitionData");
1955 if (FirstDD
!= SecondDD
) {
1956 // Check for matching super class.
1957 auto GetSuperClassSourceRange
= [](const TypeSourceInfo
*SuperInfo
,
1958 const ObjCInterfaceDecl
*ID
) {
1960 return ID
->getSourceRange();
1961 TypeLoc Loc
= SuperInfo
->getTypeLoc();
1962 return SourceRange(Loc
.getBeginLoc(), Loc
.getEndLoc());
1965 ObjCInterfaceDecl
*FirstSuperClass
= FirstID
->getSuperClass();
1966 ObjCInterfaceDecl
*SecondSuperClass
= nullptr;
1967 const TypeSourceInfo
*FirstSuperInfo
= FirstID
->getSuperClassTInfo();
1968 const TypeSourceInfo
*SecondSuperInfo
= SecondDD
->SuperClassTInfo
;
1969 if (SecondSuperInfo
)
1971 SecondSuperInfo
->getType()->castAs
<ObjCObjectType
>()->getInterface();
1973 if ((FirstSuperClass
&& SecondSuperClass
&&
1974 FirstSuperClass
->getODRHash() != SecondSuperClass
->getODRHash()) ||
1975 (FirstSuperClass
&& !SecondSuperClass
) ||
1976 (!FirstSuperClass
&& SecondSuperClass
)) {
1979 FirstType
= FirstSuperInfo
->getType();
1981 DiagError(FirstID
->getLocation(),
1982 GetSuperClassSourceRange(FirstSuperInfo
, FirstID
),
1984 << (bool)FirstSuperInfo
<< FirstType
;
1986 QualType SecondType
;
1987 if (SecondSuperInfo
)
1988 SecondType
= SecondSuperInfo
->getType();
1990 DiagNote(SecondID
->getLocation(),
1991 GetSuperClassSourceRange(SecondSuperInfo
, SecondID
),
1993 << (bool)SecondSuperInfo
<< SecondType
;
1997 // Check both interfaces reference the same protocols.
1998 auto &FirstProtos
= FirstID
->getReferencedProtocols();
1999 auto &SecondProtos
= SecondDD
->ReferencedProtocols
;
2000 if (diagnoseSubMismatchProtocols(FirstProtos
, FirstID
, FirstModule
,
2001 SecondProtos
, SecondID
, SecondModule
))
2005 auto PopulateHashes
= [](DeclHashes
&Hashes
, const ObjCInterfaceDecl
*ID
,
2006 const DeclContext
*DC
) {
2007 for (auto *D
: ID
->decls()) {
2008 if (!ODRHash::isSubDeclToBeProcessed(D
, DC
))
2010 Hashes
.emplace_back(D
, computeODRHash(D
));
2014 DeclHashes FirstHashes
;
2015 DeclHashes SecondHashes
;
2016 // Use definition as DeclContext because definitions are merged when
2017 // DeclContexts are merged and separate when DeclContexts are separate.
2018 PopulateHashes(FirstHashes
, FirstID
, FirstID
->getDefinition());
2019 PopulateHashes(SecondHashes
, SecondID
, SecondID
->getDefinition());
2021 DiffResult DR
= FindTypeDiffs(FirstHashes
, SecondHashes
);
2022 ODRMismatchDecl FirstDiffType
= DR
.FirstDiffType
;
2023 ODRMismatchDecl SecondDiffType
= DR
.SecondDiffType
;
2024 const Decl
*FirstDecl
= DR
.FirstDecl
;
2025 const Decl
*SecondDecl
= DR
.SecondDecl
;
2027 if (FirstDiffType
== Other
|| SecondDiffType
== Other
) {
2028 diagnoseSubMismatchUnexpected(DR
, FirstID
, FirstModule
, SecondID
,
2033 if (FirstDiffType
!= SecondDiffType
) {
2034 diagnoseSubMismatchDifferentDeclKinds(DR
, FirstID
, FirstModule
, SecondID
,
2039 assert(FirstDiffType
== SecondDiffType
);
2040 switch (FirstDiffType
) {
2044 // Cannot be contained by ObjCInterfaceDecl, invalid in this context.
2048 // C++ only, invalid in this context.
2049 case PublicSpecifer
:
2050 case PrivateSpecifer
:
2051 case ProtectedSpecifer
:
2056 case FunctionTemplate
:
2057 llvm_unreachable("Invalid diff type");
2060 if (diagnoseSubMismatchObjCMethod(FirstID
, FirstModule
, SecondModule
,
2061 cast
<ObjCMethodDecl
>(FirstDecl
),
2062 cast
<ObjCMethodDecl
>(SecondDecl
)))
2067 if (diagnoseSubMismatchField(FirstID
, FirstModule
, SecondModule
,
2068 cast
<FieldDecl
>(FirstDecl
),
2069 cast
<FieldDecl
>(SecondDecl
)))
2072 // Check if the access match.
2073 const ObjCIvarDecl
*FirstIvar
= cast
<ObjCIvarDecl
>(FirstDecl
);
2074 const ObjCIvarDecl
*SecondIvar
= cast
<ObjCIvarDecl
>(SecondDecl
);
2075 if (FirstIvar
->getCanonicalAccessControl() !=
2076 SecondIvar
->getCanonicalAccessControl()) {
2077 DiagError(FirstIvar
->getLocation(), FirstIvar
->getSourceRange(),
2079 << FirstIvar
->getName()
2080 << (int)FirstIvar
->getCanonicalAccessControl();
2081 DiagNote(SecondIvar
->getLocation(), SecondIvar
->getSourceRange(),
2083 << SecondIvar
->getName()
2084 << (int)SecondIvar
->getCanonicalAccessControl();
2089 case ObjCProperty
: {
2090 if (diagnoseSubMismatchObjCProperty(FirstID
, FirstModule
, SecondModule
,
2091 cast
<ObjCPropertyDecl
>(FirstDecl
),
2092 cast
<ObjCPropertyDecl
>(SecondDecl
)))
2098 Diag(FirstDecl
->getLocation(),
2099 diag::err_module_odr_violation_mismatch_decl_unknown
)
2100 << FirstID
<< FirstModule
.empty() << FirstModule
<< FirstDiffType
2101 << FirstDecl
->getSourceRange();
2102 Diag(SecondDecl
->getLocation(),
2103 diag::note_module_odr_violation_mismatch_decl_unknown
)
2104 << SecondModule
.empty() << SecondModule
<< FirstDiffType
2105 << SecondDecl
->getSourceRange();
2109 bool ODRDiagsEmitter::diagnoseMismatch(
2110 const ObjCProtocolDecl
*FirstProtocol
,
2111 const ObjCProtocolDecl
*SecondProtocol
,
2112 const struct ObjCProtocolDecl::DefinitionData
*SecondDD
) const {
2113 if (FirstProtocol
== SecondProtocol
)
2116 std::string FirstModule
= getOwningModuleNameForDiagnostic(FirstProtocol
);
2117 std::string SecondModule
= getOwningModuleNameForDiagnostic(SecondProtocol
);
2119 const ObjCProtocolDecl::DefinitionData
*FirstDD
= &FirstProtocol
->data();
2120 assert(FirstDD
&& SecondDD
&& "Definitions without DefinitionData");
2121 // Diagnostics from ObjCProtocol DefinitionData are emitted here.
2122 if (FirstDD
!= SecondDD
) {
2123 // Check both protocols reference the same protocols.
2124 const ObjCProtocolList
&FirstProtocols
=
2125 FirstProtocol
->getReferencedProtocols();
2126 const ObjCProtocolList
&SecondProtocols
= SecondDD
->ReferencedProtocols
;
2127 if (diagnoseSubMismatchProtocols(FirstProtocols
, FirstProtocol
, FirstModule
,
2128 SecondProtocols
, SecondProtocol
,
2133 auto PopulateHashes
= [](DeclHashes
&Hashes
, const ObjCProtocolDecl
*ID
,
2134 const DeclContext
*DC
) {
2135 for (const Decl
*D
: ID
->decls()) {
2136 if (!ODRHash::isSubDeclToBeProcessed(D
, DC
))
2138 Hashes
.emplace_back(D
, computeODRHash(D
));
2142 DeclHashes FirstHashes
;
2143 DeclHashes SecondHashes
;
2144 // Use definition as DeclContext because definitions are merged when
2145 // DeclContexts are merged and separate when DeclContexts are separate.
2146 PopulateHashes(FirstHashes
, FirstProtocol
, FirstProtocol
->getDefinition());
2147 PopulateHashes(SecondHashes
, SecondProtocol
, SecondProtocol
->getDefinition());
2149 DiffResult DR
= FindTypeDiffs(FirstHashes
, SecondHashes
);
2150 ODRMismatchDecl FirstDiffType
= DR
.FirstDiffType
;
2151 ODRMismatchDecl SecondDiffType
= DR
.SecondDiffType
;
2152 const Decl
*FirstDecl
= DR
.FirstDecl
;
2153 const Decl
*SecondDecl
= DR
.SecondDecl
;
2155 if (FirstDiffType
== Other
|| SecondDiffType
== Other
) {
2156 diagnoseSubMismatchUnexpected(DR
, FirstProtocol
, FirstModule
,
2157 SecondProtocol
, SecondModule
);
2161 if (FirstDiffType
!= SecondDiffType
) {
2162 diagnoseSubMismatchDifferentDeclKinds(DR
, FirstProtocol
, FirstModule
,
2163 SecondProtocol
, SecondModule
);
2167 assert(FirstDiffType
== SecondDiffType
);
2168 switch (FirstDiffType
) {
2172 // Cannot be contained by ObjCProtocolDecl, invalid in this context.
2177 // C++ only, invalid in this context.
2178 case PublicSpecifer
:
2179 case PrivateSpecifer
:
2180 case ProtectedSpecifer
:
2185 case FunctionTemplate
:
2186 llvm_unreachable("Invalid diff type");
2188 if (diagnoseSubMismatchObjCMethod(FirstProtocol
, FirstModule
, SecondModule
,
2189 cast
<ObjCMethodDecl
>(FirstDecl
),
2190 cast
<ObjCMethodDecl
>(SecondDecl
)))
2194 case ObjCProperty
: {
2195 if (diagnoseSubMismatchObjCProperty(FirstProtocol
, FirstModule
,
2197 cast
<ObjCPropertyDecl
>(FirstDecl
),
2198 cast
<ObjCPropertyDecl
>(SecondDecl
)))
2204 Diag(FirstDecl
->getLocation(),
2205 diag::err_module_odr_violation_mismatch_decl_unknown
)
2206 << FirstProtocol
<< FirstModule
.empty() << FirstModule
<< FirstDiffType
2207 << FirstDecl
->getSourceRange();
2208 Diag(SecondDecl
->getLocation(),
2209 diag::note_module_odr_violation_mismatch_decl_unknown
)
2210 << SecondModule
.empty() << SecondModule
<< FirstDiffType
2211 << SecondDecl
->getSourceRange();