xref: /freebsd/contrib/llvm-project/clang/lib/AST/ODRDiagsEmitter.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- ODRDiagsEmitter.cpp - Diagnostics for ODR mismatches ----*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
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"
15 
16 using namespace clang;
17 
computeODRHash(QualType Ty)18 static unsigned computeODRHash(QualType Ty) {
19   ODRHash Hasher;
20   Hasher.AddQualType(Ty);
21   return Hasher.CalculateHash();
22 }
23 
computeODRHash(const Stmt * S)24 static unsigned computeODRHash(const Stmt *S) {
25   ODRHash Hasher;
26   Hasher.AddStmt(S);
27   return Hasher.CalculateHash();
28 }
29 
computeODRHash(const Decl * D)30 static unsigned computeODRHash(const Decl *D) {
31   assert(D);
32   ODRHash Hasher;
33   Hasher.AddSubDecl(D);
34   return Hasher.CalculateHash();
35 }
36 
computeODRHash(const TemplateArgument & TA)37 static unsigned computeODRHash(const TemplateArgument &TA) {
38   ODRHash Hasher;
39   Hasher.AddTemplateArgument(TA);
40   return Hasher.CalculateHash();
41 }
42 
getOwningModuleNameForDiagnostic(const Decl * D)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();
47 
48   // Not from a module.
49   return {};
50 }
51 
52 template <typename MethodT>
diagnoseSubMismatchMethodParameters(DiagnosticsEngine & Diags,const NamedDecl * FirstContainer,StringRef FirstModule,StringRef SecondModule,const MethodT * FirstMethod,const MethodT * SecondMethod)53 static bool diagnoseSubMismatchMethodParameters(DiagnosticsEngine &Diags,
54                                                 const NamedDecl *FirstContainer,
55                                                 StringRef FirstModule,
56                                                 StringRef SecondModule,
57                                                 const MethodT *FirstMethod,
58                                                 const MethodT *SecondMethod) {
59   enum DiagMethodType {
60     DiagMethod,
61     DiagConstructor,
62     DiagDestructor,
63   };
64   auto GetDiagMethodType = [](const NamedDecl *D) {
65     if (isa<CXXConstructorDecl>(D))
66       return DiagConstructor;
67     if (isa<CXXDestructorDecl>(D))
68       return DiagDestructor;
69     return DiagMethod;
70   };
71 
72   enum ODRMethodParametersDifference {
73     NumberParameters,
74     ParameterType,
75     ParameterName,
76   };
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
85            << FirstName;
86   };
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
95            << SecondName;
96   };
97 
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;
103     return true;
104   }
105 
106   for (unsigned I = 0; I < FirstNumParameters; ++I) {
107     const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
108     const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
109 
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();
118       } else {
119         DiagError(ParameterType) << (I + 1) << FirstParamType << false;
120       }
121 
122       if (const DecayedType *ParamDecayedType =
123               SecondParamType->getAs<DecayedType>()) {
124         DiagNote(ParameterType) << (I + 1) << SecondParamType << true
125                                 << ParamDecayedType->getOriginalType();
126       } else {
127         DiagNote(ParameterType) << (I + 1) << SecondParamType << false;
128       }
129       return true;
130     }
131 
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;
137       return true;
138     }
139   }
140 
141   return false;
142 }
143 
diagnoseSubMismatchField(const NamedDecl * FirstRecord,StringRef FirstModule,StringRef SecondModule,const FieldDecl * FirstField,const FieldDecl * SecondField) const144 bool ODRDiagsEmitter::diagnoseSubMismatchField(
145     const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
146     const FieldDecl *FirstField, const FieldDecl *SecondField) const {
147   enum ODRFieldDifference {
148     FieldName,
149     FieldTypeName,
150     FieldSingleBitField,
151     FieldDifferentWidthBitField,
152     FieldSingleMutable,
153     FieldSingleInitializer,
154     FieldDifferentInitializers,
155   };
156 
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;
162   };
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;
168   };
169 
170   IdentifierInfo *FirstII = FirstField->getIdentifier();
171   IdentifierInfo *SecondII = SecondField->getIdentifier();
172   if (FirstII->getName() != SecondII->getName()) {
173     DiagError(FieldName) << FirstII;
174     DiagNote(FieldName) << SecondII;
175     return true;
176   }
177 
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;
183     return true;
184   }
185 
186   assert(Context.hasSameType(FirstField->getType(), SecondField->getType()));
187   (void)Context;
188 
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;
194     return true;
195   }
196 
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();
205       return true;
206     }
207   }
208 
209   if (!LangOpts.CPlusPlus)
210     return false;
211 
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;
217     return true;
218   }
219 
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);
228     return true;
229   }
230 
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();
239       return true;
240     }
241   }
242 
243   return false;
244 }
245 
diagnoseSubMismatchTypedef(const NamedDecl * FirstRecord,StringRef FirstModule,StringRef SecondModule,const TypedefNameDecl * FirstTD,const TypedefNameDecl * SecondTD,bool IsTypeAlias) const246 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 {
251     TypedefName,
252     TypedefType,
253   };
254 
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;
260   };
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;
266   };
267 
268   DeclarationName FirstName = FirstTD->getDeclName();
269   DeclarationName SecondName = SecondTD->getDeclName();
270   if (FirstName != SecondName) {
271     DiagError(TypedefName) << IsTypeAlias << FirstName;
272     DiagNote(TypedefName) << IsTypeAlias << SecondName;
273     return true;
274   }
275 
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;
281     return true;
282   }
283   return false;
284 }
285 
diagnoseSubMismatchVar(const NamedDecl * FirstRecord,StringRef FirstModule,StringRef SecondModule,const VarDecl * FirstVD,const VarDecl * SecondVD) const286 bool ODRDiagsEmitter::diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
287                                              StringRef FirstModule,
288                                              StringRef SecondModule,
289                                              const VarDecl *FirstVD,
290                                              const VarDecl *SecondVD) const {
291   enum ODRVarDifference {
292     VarName,
293     VarType,
294     VarSingleInitializer,
295     VarDifferentInitializer,
296     VarConstexpr,
297   };
298 
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;
304   };
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;
309   };
310 
311   DeclarationName FirstName = FirstVD->getDeclName();
312   DeclarationName SecondName = SecondVD->getDeclName();
313   if (FirstName != SecondName) {
314     DiagError(VarName) << FirstName;
315     DiagNote(VarName) << SecondName;
316     return true;
317   }
318 
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;
324     return true;
325   }
326 
327   if (!LangOpts.CPlusPlus)
328     return false;
329 
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());
339     return true;
340   }
341 
342   if (FirstInit && SecondInit &&
343       computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
344     DiagError(VarDifferentInitializer)
345         << FirstName << FirstInit->getSourceRange();
346     DiagNote(VarDifferentInitializer)
347         << SecondName << SecondInit->getSourceRange();
348     return true;
349   }
350 
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;
356     return true;
357   }
358   return false;
359 }
360 
diagnoseSubMismatchProtocols(const ObjCProtocolList & FirstProtocols,const ObjCContainerDecl * FirstContainer,StringRef FirstModule,const ObjCProtocolList & SecondProtocols,const ObjCContainerDecl * SecondContainer,StringRef SecondModule) const361 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 {
368     NumProtocols,
369     ProtocolType,
370   };
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
376            << DiffType;
377   };
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;
383   };
384   auto GetProtoListSourceRange = [](const ObjCProtocolList &PL) {
385     if (PL.empty())
386       return SourceRange();
387     return SourceRange(*PL.loc_begin(), *std::prev(PL.loc_end()));
388   };
389 
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();
397     return true;
398   }
399 
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;
413       return true;
414     }
415   }
416 
417   return false;
418 }
419 
diagnoseSubMismatchObjCMethod(const NamedDecl * FirstObjCContainer,StringRef FirstModule,StringRef SecondModule,const ObjCMethodDecl * FirstMethod,const ObjCMethodDecl * SecondMethod) const420 bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod(
421     const NamedDecl *FirstObjCContainer, StringRef FirstModule,
422     StringRef SecondModule, const ObjCMethodDecl *FirstMethod,
423     const ObjCMethodDecl *SecondMethod) const {
424   enum ODRMethodDifference {
425     ReturnType,
426     InstanceOrClass,
427     ControlLevel, // optional/required
428     DesignatedInitializer,
429     Directness,
430     Name,
431   };
432 
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;
439   };
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;
446   };
447 
448   if (computeODRHash(FirstMethod->getReturnType()) !=
449       computeODRHash(SecondMethod->getReturnType())) {
450     DiagError(ReturnType) << FirstMethod << FirstMethod->getReturnType();
451     DiagNote(ReturnType) << SecondMethod << SecondMethod->getReturnType();
452     return true;
453   }
454 
455   if (FirstMethod->isInstanceMethod() != SecondMethod->isInstanceMethod()) {
456     DiagError(InstanceOrClass)
457         << FirstMethod << FirstMethod->isInstanceMethod();
458     DiagNote(InstanceOrClass)
459         << SecondMethod << SecondMethod->isInstanceMethod();
460     return true;
461   }
462   if (FirstMethod->getImplementationControl() !=
463       SecondMethod->getImplementationControl()) {
464     DiagError(ControlLevel) << FirstMethod->getImplementationControl();
465     DiagNote(ControlLevel) << SecondMethod->getImplementationControl();
466     return true;
467   }
468   if (FirstMethod->isThisDeclarationADesignatedInitializer() !=
469       SecondMethod->isThisDeclarationADesignatedInitializer()) {
470     DiagError(DesignatedInitializer)
471         << FirstMethod
472         << FirstMethod->isThisDeclarationADesignatedInitializer();
473     DiagNote(DesignatedInitializer)
474         << SecondMethod
475         << SecondMethod->isThisDeclarationADesignatedInitializer();
476     return true;
477   }
478   if (FirstMethod->isDirectMethod() != SecondMethod->isDirectMethod()) {
479     DiagError(Directness) << FirstMethod << FirstMethod->isDirectMethod();
480     DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();
481     return true;
482   }
483   if (diagnoseSubMismatchMethodParameters(Diags, FirstObjCContainer,
484                                           FirstModule, SecondModule,
485                                           FirstMethod, SecondMethod))
486     return true;
487 
488   // Check method name *after* looking at the parameters otherwise we get a
489   // less ideal diagnostics: a ObjCMethodName mismatch given that selectors
490   // for different parameters are likely to be different.
491   DeclarationName FirstName = FirstMethod->getDeclName();
492   DeclarationName SecondName = SecondMethod->getDeclName();
493   if (FirstName != SecondName) {
494     DiagError(Name) << FirstName;
495     DiagNote(Name) << SecondName;
496     return true;
497   }
498 
499   return false;
500 }
501 
diagnoseSubMismatchObjCProperty(const NamedDecl * FirstObjCContainer,StringRef FirstModule,StringRef SecondModule,const ObjCPropertyDecl * FirstProp,const ObjCPropertyDecl * SecondProp) const502 bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
503     const NamedDecl *FirstObjCContainer, StringRef FirstModule,
504     StringRef SecondModule, const ObjCPropertyDecl *FirstProp,
505     const ObjCPropertyDecl *SecondProp) const {
506   enum ODRPropertyDifference {
507     Name,
508     Type,
509     ControlLevel, // optional/required
510     Attribute,
511   };
512 
513   auto DiagError = [FirstObjCContainer, FirstModule, FirstProp,
514                     this](SourceLocation Loc, ODRPropertyDifference DiffType) {
515     return Diag(Loc, diag::err_module_odr_violation_objc_property)
516            << FirstObjCContainer << FirstModule.empty() << FirstModule
517            << FirstProp->getSourceRange() << DiffType;
518   };
519   auto DiagNote = [SecondModule, SecondProp,
520                    this](SourceLocation Loc, ODRPropertyDifference DiffType) {
521     return Diag(Loc, diag::note_module_odr_violation_objc_property)
522            << SecondModule.empty() << SecondModule
523            << SecondProp->getSourceRange() << DiffType;
524   };
525 
526   IdentifierInfo *FirstII = FirstProp->getIdentifier();
527   IdentifierInfo *SecondII = SecondProp->getIdentifier();
528   if (FirstII->getName() != SecondII->getName()) {
529     DiagError(FirstProp->getLocation(), Name) << FirstII;
530     DiagNote(SecondProp->getLocation(), Name) << SecondII;
531     return true;
532   }
533   if (computeODRHash(FirstProp->getType()) !=
534       computeODRHash(SecondProp->getType())) {
535     DiagError(FirstProp->getLocation(), Type)
536         << FirstII << FirstProp->getType();
537     DiagNote(SecondProp->getLocation(), Type)
538         << SecondII << SecondProp->getType();
539     return true;
540   }
541   if (FirstProp->getPropertyImplementation() !=
542       SecondProp->getPropertyImplementation()) {
543     DiagError(FirstProp->getLocation(), ControlLevel)
544         << FirstProp->getPropertyImplementation();
545     DiagNote(SecondProp->getLocation(), ControlLevel)
546         << SecondProp->getPropertyImplementation();
547     return true;
548   }
549 
550   // Go over the property attributes and stop at the first mismatch.
551   unsigned FirstAttrs = (unsigned)FirstProp->getPropertyAttributes();
552   unsigned SecondAttrs = (unsigned)SecondProp->getPropertyAttributes();
553   if (FirstAttrs != SecondAttrs) {
554     for (unsigned I = 0; I < NumObjCPropertyAttrsBits; ++I) {
555       unsigned CheckedAttr = (1 << I);
556       if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))
557         continue;
558 
559       bool IsFirstWritten =
560           (unsigned)FirstProp->getPropertyAttributesAsWritten() & CheckedAttr;
561       bool IsSecondWritten =
562           (unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;
563       DiagError(IsFirstWritten ? FirstProp->getLParenLoc()
564                                : FirstProp->getLocation(),
565                 Attribute)
566           << FirstII << (I + 1) << IsFirstWritten;
567       DiagNote(IsSecondWritten ? SecondProp->getLParenLoc()
568                                : SecondProp->getLocation(),
569                Attribute)
570           << SecondII << (I + 1);
571       return true;
572     }
573   }
574 
575   return false;
576 }
577 
578 ODRDiagsEmitter::DiffResult
FindTypeDiffs(DeclHashes & FirstHashes,DeclHashes & SecondHashes)579 ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,
580                                DeclHashes &SecondHashes) {
581   auto DifferenceSelector = [](const Decl *D) {
582     assert(D && "valid Decl required");
583     switch (D->getKind()) {
584     default:
585       return Other;
586     case Decl::AccessSpec:
587       switch (D->getAccess()) {
588       case AS_public:
589         return PublicSpecifer;
590       case AS_private:
591         return PrivateSpecifer;
592       case AS_protected:
593         return ProtectedSpecifer;
594       case AS_none:
595         break;
596       }
597       llvm_unreachable("Invalid access specifier");
598     case Decl::StaticAssert:
599       return StaticAssert;
600     case Decl::Field:
601       return Field;
602     case Decl::CXXMethod:
603     case Decl::CXXConstructor:
604     case Decl::CXXDestructor:
605       return CXXMethod;
606     case Decl::TypeAlias:
607       return TypeAlias;
608     case Decl::Typedef:
609       return TypeDef;
610     case Decl::Var:
611       return Var;
612     case Decl::Friend:
613       return Friend;
614     case Decl::FunctionTemplate:
615       return FunctionTemplate;
616     case Decl::ObjCMethod:
617       return ObjCMethod;
618     case Decl::ObjCIvar:
619       return ObjCIvar;
620     case Decl::ObjCProperty:
621       return ObjCProperty;
622     }
623   };
624 
625   DiffResult DR;
626   auto FirstIt = FirstHashes.begin();
627   auto SecondIt = SecondHashes.begin();
628   while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
629     if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
630         FirstIt->second == SecondIt->second) {
631       ++FirstIt;
632       ++SecondIt;
633       continue;
634     }
635 
636     DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
637     DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
638 
639     DR.FirstDiffType =
640         DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;
641     DR.SecondDiffType =
642         DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;
643     return DR;
644   }
645   return DR;
646 }
647 
diagnoseSubMismatchUnexpected(DiffResult & DR,const NamedDecl * FirstRecord,StringRef FirstModule,const NamedDecl * SecondRecord,StringRef SecondModule) const648 void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(
649     DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
650     const NamedDecl *SecondRecord, StringRef SecondModule) const {
651   Diag(FirstRecord->getLocation(),
652        diag::err_module_odr_violation_different_definitions)
653       << FirstRecord << FirstModule.empty() << FirstModule;
654 
655   if (DR.FirstDecl) {
656     Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
657         << FirstRecord << DR.FirstDecl->getSourceRange();
658   }
659 
660   Diag(SecondRecord->getLocation(),
661        diag::note_module_odr_violation_different_definitions)
662       << SecondModule;
663 
664   if (DR.SecondDecl) {
665     Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
666         << DR.SecondDecl->getSourceRange();
667   }
668 }
669 
diagnoseSubMismatchDifferentDeclKinds(DiffResult & DR,const NamedDecl * FirstRecord,StringRef FirstModule,const NamedDecl * SecondRecord,StringRef SecondModule) const670 void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
671     DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
672     const NamedDecl *SecondRecord, StringRef SecondModule) const {
673   auto GetMismatchedDeclLoc = [](const NamedDecl *Container,
674                                  ODRMismatchDecl DiffType, const Decl *D) {
675     SourceLocation Loc;
676     SourceRange Range;
677     if (DiffType == EndOfClass) {
678       if (auto *Tag = dyn_cast<TagDecl>(Container))
679         Loc = Tag->getBraceRange().getEnd();
680       else if (auto *IF = dyn_cast<ObjCInterfaceDecl>(Container))
681         Loc = IF->getAtEndRange().getBegin();
682       else
683         Loc = Container->getEndLoc();
684     } else {
685       Loc = D->getLocation();
686       Range = D->getSourceRange();
687     }
688     return std::make_pair(Loc, Range);
689   };
690 
691   auto FirstDiagInfo =
692       GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
693   Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
694       << FirstRecord << FirstModule.empty() << FirstModule
695       << FirstDiagInfo.second << DR.FirstDiffType;
696 
697   auto SecondDiagInfo =
698       GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
699   Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
700       << SecondModule.empty() << SecondModule << SecondDiagInfo.second
701       << DR.SecondDiffType;
702 }
703 
diagnoseMismatch(const CXXRecordDecl * FirstRecord,const CXXRecordDecl * SecondRecord,const struct CXXRecordDecl::DefinitionData * SecondDD) const704 bool ODRDiagsEmitter::diagnoseMismatch(
705     const CXXRecordDecl *FirstRecord, const CXXRecordDecl *SecondRecord,
706     const struct CXXRecordDecl::DefinitionData *SecondDD) const {
707   // Multiple different declarations got merged together; tell the user
708   // where they came from.
709   if (FirstRecord == SecondRecord)
710     return false;
711 
712   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
713   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
714 
715   const struct CXXRecordDecl::DefinitionData *FirstDD =
716       FirstRecord->DefinitionData;
717   assert(FirstDD && SecondDD && "Definitions without DefinitionData");
718 
719   // Diagnostics from DefinitionData are emitted here.
720   if (FirstDD != SecondDD) {
721     // Keep in sync with err_module_odr_violation_definition_data.
722     enum ODRDefinitionDataDifference {
723       NumBases,
724       NumVBases,
725       BaseType,
726       BaseVirtual,
727       BaseAccess,
728     };
729     auto DiagBaseError = [FirstRecord, &FirstModule,
730                           this](SourceLocation Loc, SourceRange Range,
731                                 ODRDefinitionDataDifference DiffType) {
732       return Diag(Loc, diag::err_module_odr_violation_definition_data)
733              << FirstRecord << FirstModule.empty() << FirstModule << Range
734              << DiffType;
735     };
736     auto DiagBaseNote = [&SecondModule,
737                          this](SourceLocation Loc, SourceRange Range,
738                                ODRDefinitionDataDifference DiffType) {
739       return Diag(Loc, diag::note_module_odr_violation_definition_data)
740              << SecondModule << Range << DiffType;
741     };
742     auto GetSourceRange = [](const struct CXXRecordDecl::DefinitionData *DD) {
743       unsigned NumBases = DD->NumBases;
744       if (NumBases == 0)
745         return SourceRange();
746       ArrayRef<CXXBaseSpecifier> bases = DD->bases();
747       return SourceRange(bases[0].getBeginLoc(),
748                          bases[NumBases - 1].getEndLoc());
749     };
750 
751     unsigned FirstNumBases = FirstDD->NumBases;
752     unsigned FirstNumVBases = FirstDD->NumVBases;
753     unsigned SecondNumBases = SecondDD->NumBases;
754     unsigned SecondNumVBases = SecondDD->NumVBases;
755     if (FirstNumBases != SecondNumBases) {
756       DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
757                     NumBases)
758           << FirstNumBases;
759       DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
760                    NumBases)
761           << SecondNumBases;
762       return true;
763     }
764 
765     if (FirstNumVBases != SecondNumVBases) {
766       DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
767                     NumVBases)
768           << FirstNumVBases;
769       DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
770                    NumVBases)
771           << SecondNumVBases;
772       return true;
773     }
774 
775     ArrayRef<CXXBaseSpecifier> FirstBases = FirstDD->bases();
776     ArrayRef<CXXBaseSpecifier> SecondBases = SecondDD->bases();
777     for (unsigned I = 0; I < FirstNumBases; ++I) {
778       const CXXBaseSpecifier FirstBase = FirstBases[I];
779       const CXXBaseSpecifier SecondBase = SecondBases[I];
780       if (computeODRHash(FirstBase.getType()) !=
781           computeODRHash(SecondBase.getType())) {
782         DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
783                       BaseType)
784             << (I + 1) << FirstBase.getType();
785         DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
786                      BaseType)
787             << (I + 1) << SecondBase.getType();
788         return true;
789       }
790 
791       if (FirstBase.isVirtual() != SecondBase.isVirtual()) {
792         DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
793                       BaseVirtual)
794             << (I + 1) << FirstBase.isVirtual() << FirstBase.getType();
795         DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
796                      BaseVirtual)
797             << (I + 1) << SecondBase.isVirtual() << SecondBase.getType();
798         return true;
799       }
800 
801       if (FirstBase.getAccessSpecifierAsWritten() !=
802           SecondBase.getAccessSpecifierAsWritten()) {
803         DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
804                       BaseAccess)
805             << (I + 1) << FirstBase.getType()
806             << (int)FirstBase.getAccessSpecifierAsWritten();
807         DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
808                      BaseAccess)
809             << (I + 1) << SecondBase.getType()
810             << (int)SecondBase.getAccessSpecifierAsWritten();
811         return true;
812       }
813     }
814   }
815 
816   const ClassTemplateDecl *FirstTemplate =
817       FirstRecord->getDescribedClassTemplate();
818   const ClassTemplateDecl *SecondTemplate =
819       SecondRecord->getDescribedClassTemplate();
820 
821   assert(!FirstTemplate == !SecondTemplate &&
822          "Both pointers should be null or non-null");
823 
824   if (FirstTemplate && SecondTemplate) {
825     ArrayRef<const NamedDecl *> FirstTemplateParams =
826         FirstTemplate->getTemplateParameters()->asArray();
827     ArrayRef<const NamedDecl *> SecondTemplateParams =
828         SecondTemplate->getTemplateParameters()->asArray();
829     assert(FirstTemplateParams.size() == SecondTemplateParams.size() &&
830            "Number of template parameters should be equal.");
831     for (auto Pair : llvm::zip(FirstTemplateParams, SecondTemplateParams)) {
832       const NamedDecl *FirstDecl = std::get<0>(Pair);
833       const NamedDecl *SecondDecl = std::get<1>(Pair);
834       if (computeODRHash(FirstDecl) == computeODRHash(SecondDecl))
835         continue;
836 
837       assert(FirstDecl->getKind() == SecondDecl->getKind() &&
838              "Parameter Decl's should be the same kind.");
839 
840       enum ODRTemplateDifference {
841         ParamEmptyName,
842         ParamName,
843         ParamSingleDefaultArgument,
844         ParamDifferentDefaultArgument,
845       };
846 
847       auto hasDefaultArg = [](const NamedDecl *D) {
848         if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
849           return TTP->hasDefaultArgument() &&
850                  !TTP->defaultArgumentWasInherited();
851         if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
852           return NTTP->hasDefaultArgument() &&
853                  !NTTP->defaultArgumentWasInherited();
854         auto *TTP = cast<TemplateTemplateParmDecl>(D);
855         return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();
856       };
857       bool hasFirstArg = hasDefaultArg(FirstDecl);
858       bool hasSecondArg = hasDefaultArg(SecondDecl);
859 
860       ODRTemplateDifference ErrDiffType;
861       ODRTemplateDifference NoteDiffType;
862 
863       DeclarationName FirstName = FirstDecl->getDeclName();
864       DeclarationName SecondName = SecondDecl->getDeclName();
865 
866       if (FirstName != SecondName) {
867         bool FirstNameEmpty =
868             FirstName.isIdentifier() && !FirstName.getAsIdentifierInfo();
869         bool SecondNameEmpty =
870             SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo();
871         ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;
872         NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;
873       } else if (hasFirstArg == hasSecondArg)
874         ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
875       else
876         ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
877 
878       Diag(FirstDecl->getLocation(),
879            diag::err_module_odr_violation_template_parameter)
880           << FirstRecord << FirstModule.empty() << FirstModule
881           << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg
882           << FirstName;
883       Diag(SecondDecl->getLocation(),
884            diag::note_module_odr_violation_template_parameter)
885           << SecondModule << SecondDecl->getSourceRange() << NoteDiffType
886           << hasSecondArg << SecondName;
887       return true;
888     }
889   }
890 
891   auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,
892                            const DeclContext *DC) {
893     for (const Decl *D : Record->decls()) {
894       if (!ODRHash::isSubDeclToBeProcessed(D, DC))
895         continue;
896       Hashes.emplace_back(D, computeODRHash(D));
897     }
898   };
899 
900   DeclHashes FirstHashes;
901   DeclHashes SecondHashes;
902   const DeclContext *DC = FirstRecord;
903   PopulateHashes(FirstHashes, FirstRecord, DC);
904   PopulateHashes(SecondHashes, SecondRecord, DC);
905 
906   DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
907   ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
908   ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
909   const Decl *FirstDecl = DR.FirstDecl;
910   const Decl *SecondDecl = DR.SecondDecl;
911 
912   if (FirstDiffType == Other || SecondDiffType == Other) {
913     diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
914                                   SecondModule);
915     return true;
916   }
917 
918   if (FirstDiffType != SecondDiffType) {
919     diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
920                                           SecondRecord, SecondModule);
921     return true;
922   }
923 
924   // Used with err_module_odr_violation_record and
925   // note_module_odr_violation_record
926   enum ODRCXXRecordDifference {
927     StaticAssertCondition,
928     StaticAssertMessage,
929     StaticAssertOnlyMessage,
930     MethodName,
931     MethodDeleted,
932     MethodDefaulted,
933     MethodVirtual,
934     MethodStatic,
935     MethodVolatile,
936     MethodConst,
937     MethodInline,
938     MethodParameterSingleDefaultArgument,
939     MethodParameterDifferentDefaultArgument,
940     MethodNoTemplateArguments,
941     MethodDifferentNumberTemplateArguments,
942     MethodDifferentTemplateArgument,
943     MethodSingleBody,
944     MethodDifferentBody,
945     FriendTypeFunction,
946     FriendType,
947     FriendFunction,
948     FunctionTemplateDifferentNumberParameters,
949     FunctionTemplateParameterDifferentKind,
950     FunctionTemplateParameterName,
951     FunctionTemplateParameterSingleDefaultArgument,
952     FunctionTemplateParameterDifferentDefaultArgument,
953     FunctionTemplateParameterDifferentType,
954     FunctionTemplatePackParameter,
955   };
956   auto DiagError = [FirstRecord, &FirstModule,
957                     this](SourceLocation Loc, SourceRange Range,
958                           ODRCXXRecordDifference DiffType) {
959     return Diag(Loc, diag::err_module_odr_violation_record)
960            << FirstRecord << FirstModule.empty() << FirstModule << Range
961            << DiffType;
962   };
963   auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
964                                         ODRCXXRecordDifference DiffType) {
965     return Diag(Loc, diag::note_module_odr_violation_record)
966            << SecondModule << Range << DiffType;
967   };
968 
969   assert(FirstDiffType == SecondDiffType);
970   switch (FirstDiffType) {
971   case Other:
972   case EndOfClass:
973   case PublicSpecifer:
974   case PrivateSpecifer:
975   case ProtectedSpecifer:
976   case ObjCMethod:
977   case ObjCIvar:
978   case ObjCProperty:
979     llvm_unreachable("Invalid diff type");
980 
981   case StaticAssert: {
982     const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
983     const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
984 
985     const Expr *FirstExpr = FirstSA->getAssertExpr();
986     const Expr *SecondExpr = SecondSA->getAssertExpr();
987     unsigned FirstODRHash = computeODRHash(FirstExpr);
988     unsigned SecondODRHash = computeODRHash(SecondExpr);
989     if (FirstODRHash != SecondODRHash) {
990       DiagError(FirstExpr->getBeginLoc(), FirstExpr->getSourceRange(),
991                 StaticAssertCondition);
992       DiagNote(SecondExpr->getBeginLoc(), SecondExpr->getSourceRange(),
993                StaticAssertCondition);
994       return true;
995     }
996 
997     const Expr *FirstMessage = FirstSA->getMessage();
998     const Expr *SecondMessage = SecondSA->getMessage();
999     assert((FirstMessage || SecondMessage) && "Both messages cannot be empty");
1000     if ((FirstMessage && !SecondMessage) || (!FirstMessage && SecondMessage)) {
1001       SourceLocation FirstLoc, SecondLoc;
1002       SourceRange FirstRange, SecondRange;
1003       if (FirstMessage) {
1004         FirstLoc = FirstMessage->getBeginLoc();
1005         FirstRange = FirstMessage->getSourceRange();
1006       } else {
1007         FirstLoc = FirstSA->getBeginLoc();
1008         FirstRange = FirstSA->getSourceRange();
1009       }
1010       if (SecondMessage) {
1011         SecondLoc = SecondMessage->getBeginLoc();
1012         SecondRange = SecondMessage->getSourceRange();
1013       } else {
1014         SecondLoc = SecondSA->getBeginLoc();
1015         SecondRange = SecondSA->getSourceRange();
1016       }
1017       DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
1018           << (FirstMessage == nullptr);
1019       DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
1020           << (SecondMessage == nullptr);
1021       return true;
1022     }
1023 
1024     if (FirstMessage && SecondMessage) {
1025       unsigned FirstMessageODRHash = computeODRHash(FirstMessage);
1026       unsigned SecondMessageODRHash = computeODRHash(SecondMessage);
1027       if (FirstMessageODRHash != SecondMessageODRHash) {
1028         DiagError(FirstMessage->getBeginLoc(), FirstMessage->getSourceRange(),
1029                   StaticAssertMessage);
1030         DiagNote(SecondMessage->getBeginLoc(), SecondMessage->getSourceRange(),
1031                  StaticAssertMessage);
1032         return true;
1033       }
1034     }
1035     break;
1036   }
1037 
1038   case Field: {
1039     if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1040                                  cast<FieldDecl>(FirstDecl),
1041                                  cast<FieldDecl>(SecondDecl)))
1042       return true;
1043     break;
1044   }
1045 
1046   case CXXMethod: {
1047     enum {
1048       DiagMethod,
1049       DiagConstructor,
1050       DiagDestructor,
1051     } FirstMethodType,
1052         SecondMethodType;
1053     auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl *D) {
1054       if (isa<CXXConstructorDecl>(D))
1055         return DiagConstructor;
1056       if (isa<CXXDestructorDecl>(D))
1057         return DiagDestructor;
1058       return DiagMethod;
1059     };
1060     const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
1061     const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
1062     FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
1063     SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
1064     DeclarationName FirstName = FirstMethod->getDeclName();
1065     DeclarationName SecondName = SecondMethod->getDeclName();
1066     auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType,
1067                             FirstName](ODRCXXRecordDifference DiffType) {
1068       return DiagError(FirstMethod->getLocation(),
1069                        FirstMethod->getSourceRange(), DiffType)
1070              << FirstMethodType << FirstName;
1071     };
1072     auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,
1073                            SecondName](ODRCXXRecordDifference DiffType) {
1074       return DiagNote(SecondMethod->getLocation(),
1075                       SecondMethod->getSourceRange(), DiffType)
1076              << SecondMethodType << SecondName;
1077     };
1078 
1079     if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
1080       DiagMethodError(MethodName);
1081       DiagMethodNote(MethodName);
1082       return true;
1083     }
1084 
1085     const bool FirstDeleted = FirstMethod->isDeletedAsWritten();
1086     const bool SecondDeleted = SecondMethod->isDeletedAsWritten();
1087     if (FirstDeleted != SecondDeleted) {
1088       DiagMethodError(MethodDeleted) << FirstDeleted;
1089       DiagMethodNote(MethodDeleted) << SecondDeleted;
1090       return true;
1091     }
1092 
1093     const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted();
1094     const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted();
1095     if (FirstDefaulted != SecondDefaulted) {
1096       DiagMethodError(MethodDefaulted) << FirstDefaulted;
1097       DiagMethodNote(MethodDefaulted) << SecondDefaulted;
1098       return true;
1099     }
1100 
1101     const bool FirstVirtual = FirstMethod->isVirtualAsWritten();
1102     const bool SecondVirtual = SecondMethod->isVirtualAsWritten();
1103     const bool FirstPure = FirstMethod->isPureVirtual();
1104     const bool SecondPure = SecondMethod->isPureVirtual();
1105     if ((FirstVirtual || SecondVirtual) &&
1106         (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
1107       DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
1108       DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
1109       return true;
1110     }
1111 
1112     // CXXMethodDecl::isStatic uses the canonical Decl.  With Decl merging,
1113     // FirstDecl is the canonical Decl of SecondDecl, so the storage
1114     // class needs to be checked instead.
1115     StorageClass FirstStorage = FirstMethod->getStorageClass();
1116     StorageClass SecondStorage = SecondMethod->getStorageClass();
1117     const bool FirstStatic = FirstStorage == SC_Static;
1118     const bool SecondStatic = SecondStorage == SC_Static;
1119     if (FirstStatic != SecondStatic) {
1120       DiagMethodError(MethodStatic) << FirstStatic;
1121       DiagMethodNote(MethodStatic) << SecondStatic;
1122       return true;
1123     }
1124 
1125     const bool FirstVolatile = FirstMethod->isVolatile();
1126     const bool SecondVolatile = SecondMethod->isVolatile();
1127     if (FirstVolatile != SecondVolatile) {
1128       DiagMethodError(MethodVolatile) << FirstVolatile;
1129       DiagMethodNote(MethodVolatile) << SecondVolatile;
1130       return true;
1131     }
1132 
1133     const bool FirstConst = FirstMethod->isConst();
1134     const bool SecondConst = SecondMethod->isConst();
1135     if (FirstConst != SecondConst) {
1136       DiagMethodError(MethodConst) << FirstConst;
1137       DiagMethodNote(MethodConst) << SecondConst;
1138       return true;
1139     }
1140 
1141     const bool FirstInline = FirstMethod->isInlineSpecified();
1142     const bool SecondInline = SecondMethod->isInlineSpecified();
1143     if (FirstInline != SecondInline) {
1144       DiagMethodError(MethodInline) << FirstInline;
1145       DiagMethodNote(MethodInline) << SecondInline;
1146       return true;
1147     }
1148 
1149     if (diagnoseSubMismatchMethodParameters(Diags, FirstRecord,
1150                                             FirstModule, SecondModule,
1151                                             FirstMethod, SecondMethod))
1152       return true;
1153 
1154     for (unsigned I = 0, N = FirstMethod->param_size(); I < N; ++I) {
1155       const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
1156       const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
1157 
1158       const Expr *FirstInit = FirstParam->getInit();
1159       const Expr *SecondInit = SecondParam->getInit();
1160       if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1161         DiagMethodError(MethodParameterSingleDefaultArgument)
1162             << (I + 1) << (FirstInit == nullptr)
1163             << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
1164         DiagMethodNote(MethodParameterSingleDefaultArgument)
1165             << (I + 1) << (SecondInit == nullptr)
1166             << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
1167         return true;
1168       }
1169 
1170       if (FirstInit && SecondInit &&
1171           computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1172         DiagMethodError(MethodParameterDifferentDefaultArgument)
1173             << (I + 1) << FirstInit->getSourceRange();
1174         DiagMethodNote(MethodParameterDifferentDefaultArgument)
1175             << (I + 1) << SecondInit->getSourceRange();
1176         return true;
1177       }
1178     }
1179 
1180     const TemplateArgumentList *FirstTemplateArgs =
1181         FirstMethod->getTemplateSpecializationArgs();
1182     const TemplateArgumentList *SecondTemplateArgs =
1183         SecondMethod->getTemplateSpecializationArgs();
1184 
1185     if ((FirstTemplateArgs && !SecondTemplateArgs) ||
1186         (!FirstTemplateArgs && SecondTemplateArgs)) {
1187       DiagMethodError(MethodNoTemplateArguments)
1188           << (FirstTemplateArgs != nullptr);
1189       DiagMethodNote(MethodNoTemplateArguments)
1190           << (SecondTemplateArgs != nullptr);
1191       return true;
1192     }
1193 
1194     if (FirstTemplateArgs && SecondTemplateArgs) {
1195       // Remove pack expansions from argument list.
1196       auto ExpandTemplateArgumentList = [](const TemplateArgumentList *TAL) {
1197         llvm::SmallVector<const TemplateArgument *, 8> ExpandedList;
1198         for (const TemplateArgument &TA : TAL->asArray()) {
1199           if (TA.getKind() != TemplateArgument::Pack) {
1200             ExpandedList.push_back(&TA);
1201             continue;
1202           }
1203           llvm::append_range(ExpandedList,
1204                              llvm::make_pointer_range(TA.getPackAsArray()));
1205         }
1206         return ExpandedList;
1207       };
1208       llvm::SmallVector<const TemplateArgument *, 8> FirstExpandedList =
1209           ExpandTemplateArgumentList(FirstTemplateArgs);
1210       llvm::SmallVector<const TemplateArgument *, 8> SecondExpandedList =
1211           ExpandTemplateArgumentList(SecondTemplateArgs);
1212 
1213       if (FirstExpandedList.size() != SecondExpandedList.size()) {
1214         DiagMethodError(MethodDifferentNumberTemplateArguments)
1215             << (unsigned)FirstExpandedList.size();
1216         DiagMethodNote(MethodDifferentNumberTemplateArguments)
1217             << (unsigned)SecondExpandedList.size();
1218         return true;
1219       }
1220 
1221       for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
1222         const TemplateArgument &FirstTA = *FirstExpandedList[i],
1223                                &SecondTA = *SecondExpandedList[i];
1224         if (computeODRHash(FirstTA) == computeODRHash(SecondTA))
1225           continue;
1226 
1227         DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;
1228         DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;
1229         return true;
1230       }
1231     }
1232 
1233     // Compute the hash of the method as if it has no body.
1234     auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) {
1235       ODRHash Hasher;
1236       Hasher.AddFunctionDecl(D, true /*SkipBody*/);
1237       return Hasher.CalculateHash();
1238     };
1239 
1240     // Compare the hash generated to the hash stored.  A difference means
1241     // that a body was present in the original source.  Due to merging,
1242     // the standard way of detecting a body will not work.
1243     const bool HasFirstBody =
1244         ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();
1245     const bool HasSecondBody =
1246         ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash();
1247 
1248     if (HasFirstBody != HasSecondBody) {
1249       DiagMethodError(MethodSingleBody) << HasFirstBody;
1250       DiagMethodNote(MethodSingleBody) << HasSecondBody;
1251       return true;
1252     }
1253 
1254     if (HasFirstBody && HasSecondBody) {
1255       DiagMethodError(MethodDifferentBody);
1256       DiagMethodNote(MethodDifferentBody);
1257       return true;
1258     }
1259 
1260     break;
1261   }
1262 
1263   case TypeAlias:
1264   case TypeDef: {
1265     if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1266                                    cast<TypedefNameDecl>(FirstDecl),
1267                                    cast<TypedefNameDecl>(SecondDecl),
1268                                    FirstDiffType == TypeAlias))
1269       return true;
1270     break;
1271   }
1272   case Var: {
1273     if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1274                                cast<VarDecl>(FirstDecl),
1275                                cast<VarDecl>(SecondDecl)))
1276       return true;
1277     break;
1278   }
1279   case Friend: {
1280     const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
1281     const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
1282 
1283     const NamedDecl *FirstND = FirstFriend->getFriendDecl();
1284     const NamedDecl *SecondND = SecondFriend->getFriendDecl();
1285 
1286     TypeSourceInfo *FirstTSI = FirstFriend->getFriendType();
1287     TypeSourceInfo *SecondTSI = SecondFriend->getFriendType();
1288 
1289     if (FirstND && SecondND) {
1290       DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1291                 FriendFunction)
1292           << FirstND;
1293       DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1294                FriendFunction)
1295           << SecondND;
1296       return true;
1297     }
1298 
1299     if (FirstTSI && SecondTSI) {
1300       QualType FirstFriendType = FirstTSI->getType();
1301       QualType SecondFriendType = SecondTSI->getType();
1302       assert(computeODRHash(FirstFriendType) !=
1303              computeODRHash(SecondFriendType));
1304       DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1305                 FriendType)
1306           << FirstFriendType;
1307       DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1308                FriendType)
1309           << SecondFriendType;
1310       return true;
1311     }
1312 
1313     DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1314               FriendTypeFunction)
1315         << (FirstTSI == nullptr);
1316     DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1317              FriendTypeFunction)
1318         << (SecondTSI == nullptr);
1319     return true;
1320   }
1321   case FunctionTemplate: {
1322     const FunctionTemplateDecl *FirstTemplate =
1323         cast<FunctionTemplateDecl>(FirstDecl);
1324     const FunctionTemplateDecl *SecondTemplate =
1325         cast<FunctionTemplateDecl>(SecondDecl);
1326 
1327     TemplateParameterList *FirstTPL = FirstTemplate->getTemplateParameters();
1328     TemplateParameterList *SecondTPL = SecondTemplate->getTemplateParameters();
1329 
1330     auto DiagTemplateError = [&DiagError,
1331                               FirstTemplate](ODRCXXRecordDifference DiffType) {
1332       return DiagError(FirstTemplate->getLocation(),
1333                        FirstTemplate->getSourceRange(), DiffType)
1334              << FirstTemplate;
1335     };
1336     auto DiagTemplateNote = [&DiagNote,
1337                              SecondTemplate](ODRCXXRecordDifference DiffType) {
1338       return DiagNote(SecondTemplate->getLocation(),
1339                       SecondTemplate->getSourceRange(), DiffType)
1340              << SecondTemplate;
1341     };
1342 
1343     if (FirstTPL->size() != SecondTPL->size()) {
1344       DiagTemplateError(FunctionTemplateDifferentNumberParameters)
1345           << FirstTPL->size();
1346       DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
1347           << SecondTPL->size();
1348       return true;
1349     }
1350 
1351     for (unsigned i = 0, e = FirstTPL->size(); i != e; ++i) {
1352       NamedDecl *FirstParam = FirstTPL->getParam(i);
1353       NamedDecl *SecondParam = SecondTPL->getParam(i);
1354 
1355       if (FirstParam->getKind() != SecondParam->getKind()) {
1356         enum {
1357           TemplateTypeParameter,
1358           NonTypeTemplateParameter,
1359           TemplateTemplateParameter,
1360         };
1361         auto GetParamType = [](NamedDecl *D) {
1362           switch (D->getKind()) {
1363           default:
1364             llvm_unreachable("Unexpected template parameter type");
1365           case Decl::TemplateTypeParm:
1366             return TemplateTypeParameter;
1367           case Decl::NonTypeTemplateParm:
1368             return NonTypeTemplateParameter;
1369           case Decl::TemplateTemplateParm:
1370             return TemplateTemplateParameter;
1371           }
1372         };
1373 
1374         DiagTemplateError(FunctionTemplateParameterDifferentKind)
1375             << (i + 1) << GetParamType(FirstParam);
1376         DiagTemplateNote(FunctionTemplateParameterDifferentKind)
1377             << (i + 1) << GetParamType(SecondParam);
1378         return true;
1379       }
1380 
1381       if (FirstParam->getName() != SecondParam->getName()) {
1382         DiagTemplateError(FunctionTemplateParameterName)
1383             << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam;
1384         DiagTemplateNote(FunctionTemplateParameterName)
1385             << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam;
1386         return true;
1387       }
1388 
1389       if (isa<TemplateTypeParmDecl>(FirstParam) &&
1390           isa<TemplateTypeParmDecl>(SecondParam)) {
1391         TemplateTypeParmDecl *FirstTTPD =
1392             cast<TemplateTypeParmDecl>(FirstParam);
1393         TemplateTypeParmDecl *SecondTTPD =
1394             cast<TemplateTypeParmDecl>(SecondParam);
1395         bool HasFirstDefaultArgument =
1396             FirstTTPD->hasDefaultArgument() &&
1397             !FirstTTPD->defaultArgumentWasInherited();
1398         bool HasSecondDefaultArgument =
1399             SecondTTPD->hasDefaultArgument() &&
1400             !SecondTTPD->defaultArgumentWasInherited();
1401         if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1402           DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1403               << (i + 1) << HasFirstDefaultArgument;
1404           DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1405               << (i + 1) << HasSecondDefaultArgument;
1406           return true;
1407         }
1408 
1409         if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1410           TemplateArgument FirstTA =
1411               FirstTTPD->getDefaultArgument().getArgument();
1412           TemplateArgument SecondTA =
1413               SecondTTPD->getDefaultArgument().getArgument();
1414           if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {
1415             DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1416                 << (i + 1) << FirstTA;
1417             DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1418                 << (i + 1) << SecondTA;
1419             return true;
1420           }
1421         }
1422 
1423         if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1424           DiagTemplateError(FunctionTemplatePackParameter)
1425               << (i + 1) << FirstTTPD->isParameterPack();
1426           DiagTemplateNote(FunctionTemplatePackParameter)
1427               << (i + 1) << SecondTTPD->isParameterPack();
1428           return true;
1429         }
1430       }
1431 
1432       if (isa<TemplateTemplateParmDecl>(FirstParam) &&
1433           isa<TemplateTemplateParmDecl>(SecondParam)) {
1434         TemplateTemplateParmDecl *FirstTTPD =
1435             cast<TemplateTemplateParmDecl>(FirstParam);
1436         TemplateTemplateParmDecl *SecondTTPD =
1437             cast<TemplateTemplateParmDecl>(SecondParam);
1438 
1439         TemplateParameterList *FirstTPL = FirstTTPD->getTemplateParameters();
1440         TemplateParameterList *SecondTPL = SecondTTPD->getTemplateParameters();
1441 
1442         auto ComputeTemplateParameterListODRHash =
1443             [](const TemplateParameterList *TPL) {
1444               assert(TPL);
1445               ODRHash Hasher;
1446               Hasher.AddTemplateParameterList(TPL);
1447               return Hasher.CalculateHash();
1448             };
1449 
1450         if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1451             ComputeTemplateParameterListODRHash(SecondTPL)) {
1452           DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1453           DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1454           return true;
1455         }
1456 
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;
1468           return true;
1469         }
1470 
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;
1481             return true;
1482           }
1483         }
1484 
1485         if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1486           DiagTemplateError(FunctionTemplatePackParameter)
1487               << (i + 1) << FirstTTPD->isParameterPack();
1488           DiagTemplateNote(FunctionTemplatePackParameter)
1489               << (i + 1) << SecondTTPD->isParameterPack();
1490           return true;
1491         }
1492       }
1493 
1494       if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
1495           isa<NonTypeTemplateParmDecl>(SecondParam)) {
1496         NonTypeTemplateParmDecl *FirstNTTPD =
1497             cast<NonTypeTemplateParmDecl>(FirstParam);
1498         NonTypeTemplateParmDecl *SecondNTTPD =
1499             cast<NonTypeTemplateParmDecl>(SecondParam);
1500 
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);
1506           return true;
1507         }
1508 
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;
1520           return true;
1521         }
1522 
1523         if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1524           TemplateArgument FirstDefaultArgument =
1525               FirstNTTPD->getDefaultArgument().getArgument();
1526           TemplateArgument SecondDefaultArgument =
1527               SecondNTTPD->getDefaultArgument().getArgument();
1528 
1529           if (computeODRHash(FirstDefaultArgument) !=
1530               computeODRHash(SecondDefaultArgument)) {
1531             DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1532                 << (i + 1) << FirstDefaultArgument;
1533             DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1534                 << (i + 1) << SecondDefaultArgument;
1535             return true;
1536           }
1537         }
1538 
1539         if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) {
1540           DiagTemplateError(FunctionTemplatePackParameter)
1541               << (i + 1) << FirstNTTPD->isParameterPack();
1542           DiagTemplateNote(FunctionTemplatePackParameter)
1543               << (i + 1) << SecondNTTPD->isParameterPack();
1544           return true;
1545         }
1546       }
1547     }
1548     break;
1549   }
1550   }
1551 
1552   Diag(FirstDecl->getLocation(),
1553        diag::err_module_odr_violation_mismatch_decl_unknown)
1554       << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1555       << FirstDecl->getSourceRange();
1556   Diag(SecondDecl->getLocation(),
1557        diag::note_module_odr_violation_mismatch_decl_unknown)
1558       << SecondModule.empty() << SecondModule << FirstDiffType
1559       << SecondDecl->getSourceRange();
1560   return true;
1561 }
1562 
diagnoseMismatch(const RecordDecl * FirstRecord,const RecordDecl * SecondRecord) const1563 bool ODRDiagsEmitter::diagnoseMismatch(const RecordDecl *FirstRecord,
1564                                        const RecordDecl *SecondRecord) const {
1565   if (FirstRecord == SecondRecord)
1566     return false;
1567 
1568   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
1569   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
1570 
1571   auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,
1572                            const DeclContext *DC) {
1573     for (const Decl *D : Record->decls()) {
1574       if (!ODRHash::isSubDeclToBeProcessed(D, DC))
1575         continue;
1576       Hashes.emplace_back(D, computeODRHash(D));
1577     }
1578   };
1579 
1580   DeclHashes FirstHashes;
1581   DeclHashes SecondHashes;
1582   const DeclContext *DC = FirstRecord;
1583   PopulateHashes(FirstHashes, FirstRecord, DC);
1584   PopulateHashes(SecondHashes, SecondRecord, DC);
1585 
1586   DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1587   ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1588   ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1589   const Decl *FirstDecl = DR.FirstDecl;
1590   const Decl *SecondDecl = DR.SecondDecl;
1591 
1592   if (FirstDiffType == Other || SecondDiffType == Other) {
1593     diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1594                                   SecondModule);
1595     return true;
1596   }
1597 
1598   if (FirstDiffType != SecondDiffType) {
1599     diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1600                                           SecondRecord, SecondModule);
1601     return true;
1602   }
1603 
1604   assert(FirstDiffType == SecondDiffType);
1605   switch (FirstDiffType) {
1606   // Already handled.
1607   case EndOfClass:
1608   case Other:
1609   // C++ only, invalid in this context.
1610   case PublicSpecifer:
1611   case PrivateSpecifer:
1612   case ProtectedSpecifer:
1613   case StaticAssert:
1614   case CXXMethod:
1615   case TypeAlias:
1616   case Friend:
1617   case FunctionTemplate:
1618   // Cannot be contained by RecordDecl, invalid in this context.
1619   case ObjCMethod:
1620   case ObjCIvar:
1621   case ObjCProperty:
1622     llvm_unreachable("Invalid diff type");
1623 
1624   case Field: {
1625     if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1626                                  cast<FieldDecl>(FirstDecl),
1627                                  cast<FieldDecl>(SecondDecl)))
1628       return true;
1629     break;
1630   }
1631   case TypeDef: {
1632     if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1633                                    cast<TypedefNameDecl>(FirstDecl),
1634                                    cast<TypedefNameDecl>(SecondDecl),
1635                                    /*IsTypeAlias=*/false))
1636       return true;
1637     break;
1638   }
1639   case Var: {
1640     if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1641                                cast<VarDecl>(FirstDecl),
1642                                cast<VarDecl>(SecondDecl)))
1643       return true;
1644     break;
1645   }
1646   }
1647 
1648   Diag(FirstDecl->getLocation(),
1649        diag::err_module_odr_violation_mismatch_decl_unknown)
1650       << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1651       << FirstDecl->getSourceRange();
1652   Diag(SecondDecl->getLocation(),
1653        diag::note_module_odr_violation_mismatch_decl_unknown)
1654       << SecondModule.empty() << SecondModule << FirstDiffType
1655       << SecondDecl->getSourceRange();
1656   return true;
1657 }
1658 
diagnoseMismatch(const FunctionDecl * FirstFunction,const FunctionDecl * SecondFunction) const1659 bool ODRDiagsEmitter::diagnoseMismatch(
1660     const FunctionDecl *FirstFunction,
1661     const FunctionDecl *SecondFunction) const {
1662   if (FirstFunction == SecondFunction)
1663     return false;
1664 
1665   // Keep in sync with select options in err_module_odr_violation_function.
1666   enum ODRFunctionDifference {
1667     ReturnType,
1668     ParameterName,
1669     ParameterType,
1670     ParameterSingleDefaultArgument,
1671     ParameterDifferentDefaultArgument,
1672     FunctionBody,
1673   };
1674 
1675   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);
1676   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondFunction);
1677 
1678   auto DiagError = [FirstFunction, &FirstModule,
1679                     this](SourceLocation Loc, SourceRange Range,
1680                           ODRFunctionDifference DiffType) {
1681     return Diag(Loc, diag::err_module_odr_violation_function)
1682            << FirstFunction << FirstModule.empty() << FirstModule << Range
1683            << DiffType;
1684   };
1685   auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1686                                         ODRFunctionDifference DiffType) {
1687     return Diag(Loc, diag::note_module_odr_violation_function)
1688            << SecondModule << Range << DiffType;
1689   };
1690 
1691   if (computeODRHash(FirstFunction->getReturnType()) !=
1692       computeODRHash(SecondFunction->getReturnType())) {
1693     DiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),
1694               FirstFunction->getReturnTypeSourceRange(), ReturnType)
1695         << FirstFunction->getReturnType();
1696     DiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),
1697              SecondFunction->getReturnTypeSourceRange(), ReturnType)
1698         << SecondFunction->getReturnType();
1699     return true;
1700   }
1701 
1702   assert(FirstFunction->param_size() == SecondFunction->param_size() &&
1703          "Merged functions with different number of parameters");
1704 
1705   size_t ParamSize = FirstFunction->param_size();
1706   for (unsigned I = 0; I < ParamSize; ++I) {
1707     const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I);
1708     const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I);
1709 
1710     assert(Context.hasSameType(FirstParam->getType(), SecondParam->getType()) &&
1711            "Merged function has different parameter types.");
1712 
1713     if (FirstParam->getDeclName() != SecondParam->getDeclName()) {
1714       DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1715                 ParameterName)
1716           << I + 1 << FirstParam->getDeclName();
1717       DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1718                ParameterName)
1719           << I + 1 << SecondParam->getDeclName();
1720       return true;
1721     };
1722 
1723     QualType FirstParamType = FirstParam->getType();
1724     QualType SecondParamType = SecondParam->getType();
1725     if (FirstParamType != SecondParamType &&
1726         computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) {
1727       if (const DecayedType *ParamDecayedType =
1728               FirstParamType->getAs<DecayedType>()) {
1729         DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1730                   ParameterType)
1731             << (I + 1) << FirstParamType << true
1732             << ParamDecayedType->getOriginalType();
1733       } else {
1734         DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1735                   ParameterType)
1736             << (I + 1) << FirstParamType << false;
1737       }
1738 
1739       if (const DecayedType *ParamDecayedType =
1740               SecondParamType->getAs<DecayedType>()) {
1741         DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1742                  ParameterType)
1743             << (I + 1) << SecondParamType << true
1744             << ParamDecayedType->getOriginalType();
1745       } else {
1746         DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1747                  ParameterType)
1748             << (I + 1) << SecondParamType << false;
1749       }
1750       return true;
1751     }
1752 
1753     // Note, these calls can trigger deserialization.
1754     const Expr *FirstInit = FirstParam->getInit();
1755     const Expr *SecondInit = SecondParam->getInit();
1756     if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1757       DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1758                 ParameterSingleDefaultArgument)
1759           << (I + 1) << (FirstInit == nullptr)
1760           << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
1761       DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1762                ParameterSingleDefaultArgument)
1763           << (I + 1) << (SecondInit == nullptr)
1764           << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
1765       return true;
1766     }
1767 
1768     if (FirstInit && SecondInit &&
1769         computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1770       DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1771                 ParameterDifferentDefaultArgument)
1772           << (I + 1) << FirstInit->getSourceRange();
1773       DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1774                ParameterDifferentDefaultArgument)
1775           << (I + 1) << SecondInit->getSourceRange();
1776       return true;
1777     }
1778 
1779     assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) &&
1780            "Undiagnosed parameter difference.");
1781   }
1782 
1783   // If no error has been generated before now, assume the problem is in
1784   // the body and generate a message.
1785   DiagError(FirstFunction->getLocation(), FirstFunction->getSourceRange(),
1786             FunctionBody);
1787   DiagNote(SecondFunction->getLocation(), SecondFunction->getSourceRange(),
1788            FunctionBody);
1789   return true;
1790 }
1791 
diagnoseMismatch(const EnumDecl * FirstEnum,const EnumDecl * SecondEnum) const1792 bool ODRDiagsEmitter::diagnoseMismatch(const EnumDecl *FirstEnum,
1793                                        const EnumDecl *SecondEnum) const {
1794   if (FirstEnum == SecondEnum)
1795     return false;
1796 
1797   // Keep in sync with select options in err_module_odr_violation_enum.
1798   enum ODREnumDifference {
1799     SingleScopedEnum,
1800     EnumTagKeywordMismatch,
1801     SingleSpecifiedType,
1802     DifferentSpecifiedTypes,
1803     DifferentNumberEnumConstants,
1804     EnumConstantName,
1805     EnumConstantSingleInitializer,
1806     EnumConstantDifferentInitializer,
1807   };
1808 
1809   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum);
1810   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondEnum);
1811 
1812   auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor,
1813                                                    ODREnumDifference DiffType) {
1814     return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1815            << FirstEnum << FirstModule.empty() << FirstModule
1816            << DiagAnchor->getSourceRange() << DiffType;
1817   };
1818   auto DiagNote = [&SecondModule, this](const auto *DiagAnchor,
1819                                         ODREnumDifference DiffType) {
1820     return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1821            << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1822   };
1823 
1824   if (FirstEnum->isScoped() != SecondEnum->isScoped()) {
1825     DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();
1826     DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();
1827     return true;
1828   }
1829 
1830   if (FirstEnum->isScoped() && SecondEnum->isScoped()) {
1831     if (FirstEnum->isScopedUsingClassTag() !=
1832         SecondEnum->isScopedUsingClassTag()) {
1833       DiagError(FirstEnum, EnumTagKeywordMismatch)
1834           << FirstEnum->isScopedUsingClassTag();
1835       DiagNote(SecondEnum, EnumTagKeywordMismatch)
1836           << SecondEnum->isScopedUsingClassTag();
1837       return true;
1838     }
1839   }
1840 
1841   QualType FirstUnderlyingType =
1842       FirstEnum->getIntegerTypeSourceInfo()
1843           ? FirstEnum->getIntegerTypeSourceInfo()->getType()
1844           : QualType();
1845   QualType SecondUnderlyingType =
1846       SecondEnum->getIntegerTypeSourceInfo()
1847           ? SecondEnum->getIntegerTypeSourceInfo()->getType()
1848           : QualType();
1849   if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {
1850     DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull();
1851     DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull();
1852     return true;
1853   }
1854 
1855   if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {
1856     if (computeODRHash(FirstUnderlyingType) !=
1857         computeODRHash(SecondUnderlyingType)) {
1858       DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1859       DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1860       return true;
1861     }
1862   }
1863 
1864   // Compare enum constants.
1865   using DeclHashes =
1866       llvm::SmallVector<std::pair<const EnumConstantDecl *, unsigned>, 4>;
1867   auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, const EnumDecl *Enum) {
1868     for (const Decl *D : Enum->decls()) {
1869       // Due to decl merging, the first EnumDecl is the parent of
1870       // Decls in both records.
1871       if (!ODRHash::isSubDeclToBeProcessed(D, FirstEnum))
1872         continue;
1873       assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");
1874       Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D));
1875     }
1876   };
1877   DeclHashes FirstHashes;
1878   PopulateHashes(FirstHashes, FirstEnum);
1879   DeclHashes SecondHashes;
1880   PopulateHashes(SecondHashes, SecondEnum);
1881 
1882   if (FirstHashes.size() != SecondHashes.size()) {
1883     DiagError(FirstEnum, DifferentNumberEnumConstants)
1884         << (int)FirstHashes.size();
1885     DiagNote(SecondEnum, DifferentNumberEnumConstants)
1886         << (int)SecondHashes.size();
1887     return true;
1888   }
1889 
1890   for (unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {
1891     if (FirstHashes[I].second == SecondHashes[I].second)
1892       continue;
1893     const EnumConstantDecl *FirstConstant = FirstHashes[I].first;
1894     const EnumConstantDecl *SecondConstant = SecondHashes[I].first;
1895 
1896     if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) {
1897       DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1898       DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1899       return true;
1900     }
1901 
1902     const Expr *FirstInit = FirstConstant->getInitExpr();
1903     const Expr *SecondInit = SecondConstant->getInitExpr();
1904     if (!FirstInit && !SecondInit)
1905       continue;
1906 
1907     if (!FirstInit || !SecondInit) {
1908       DiagError(FirstConstant, EnumConstantSingleInitializer)
1909           << I + 1 << FirstConstant << (FirstInit != nullptr);
1910       DiagNote(SecondConstant, EnumConstantSingleInitializer)
1911           << I + 1 << SecondConstant << (SecondInit != nullptr);
1912       return true;
1913     }
1914 
1915     if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1916       DiagError(FirstConstant, EnumConstantDifferentInitializer)
1917           << I + 1 << FirstConstant;
1918       DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1919           << I + 1 << SecondConstant;
1920       return true;
1921     }
1922   }
1923   return false;
1924 }
1925 
diagnoseMismatch(const ObjCInterfaceDecl * FirstID,const ObjCInterfaceDecl * SecondID,const struct ObjCInterfaceDecl::DefinitionData * SecondDD) const1926 bool ODRDiagsEmitter::diagnoseMismatch(
1927     const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
1928     const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const {
1929   // Multiple different declarations got merged together; tell the user
1930   // where they came from.
1931   if (FirstID == SecondID)
1932     return false;
1933 
1934   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstID);
1935   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondID);
1936 
1937   // Keep in sync with err_module_odr_violation_objc_interface.
1938   enum ODRInterfaceDifference {
1939     SuperClassType,
1940     IVarAccess,
1941   };
1942 
1943   auto DiagError = [FirstID, &FirstModule,
1944                     this](SourceLocation Loc, SourceRange Range,
1945                           ODRInterfaceDifference DiffType) {
1946     return Diag(Loc, diag::err_module_odr_violation_objc_interface)
1947            << FirstID << FirstModule.empty() << FirstModule << Range
1948            << DiffType;
1949   };
1950   auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1951                                         ODRInterfaceDifference DiffType) {
1952     return Diag(Loc, diag::note_module_odr_violation_objc_interface)
1953            << SecondModule.empty() << SecondModule << Range << DiffType;
1954   };
1955 
1956   const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1957   assert(FirstDD && SecondDD && "Definitions without DefinitionData");
1958   if (FirstDD != SecondDD) {
1959     // Check for matching super class.
1960     auto GetSuperClassSourceRange = [](const TypeSourceInfo *SuperInfo,
1961                                        const ObjCInterfaceDecl *ID) {
1962       if (!SuperInfo)
1963         return ID->getSourceRange();
1964       TypeLoc Loc = SuperInfo->getTypeLoc();
1965       return SourceRange(Loc.getBeginLoc(), Loc.getEndLoc());
1966     };
1967 
1968     ObjCInterfaceDecl *FirstSuperClass = FirstID->getSuperClass();
1969     ObjCInterfaceDecl *SecondSuperClass = nullptr;
1970     const TypeSourceInfo *FirstSuperInfo = FirstID->getSuperClassTInfo();
1971     const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;
1972     if (SecondSuperInfo)
1973       SecondSuperClass =
1974           SecondSuperInfo->getType()->castAs<ObjCObjectType>()->getInterface();
1975 
1976     if ((FirstSuperClass && SecondSuperClass &&
1977          FirstSuperClass->getODRHash() != SecondSuperClass->getODRHash()) ||
1978         (FirstSuperClass && !SecondSuperClass) ||
1979         (!FirstSuperClass && SecondSuperClass)) {
1980       QualType FirstType;
1981       if (FirstSuperInfo)
1982         FirstType = FirstSuperInfo->getType();
1983 
1984       DiagError(FirstID->getLocation(),
1985                 GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1986                 SuperClassType)
1987           << (bool)FirstSuperInfo << FirstType;
1988 
1989       QualType SecondType;
1990       if (SecondSuperInfo)
1991         SecondType = SecondSuperInfo->getType();
1992 
1993       DiagNote(SecondID->getLocation(),
1994                GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1995                SuperClassType)
1996           << (bool)SecondSuperInfo << SecondType;
1997       return true;
1998     }
1999 
2000     // Check both interfaces reference the same protocols.
2001     auto &FirstProtos = FirstID->getReferencedProtocols();
2002     auto &SecondProtos = SecondDD->ReferencedProtocols;
2003     if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
2004                                      SecondProtos, SecondID, SecondModule))
2005       return true;
2006   }
2007 
2008   auto PopulateHashes = [](DeclHashes &Hashes, const ObjCInterfaceDecl *ID,
2009                            const DeclContext *DC) {
2010     for (auto *D : ID->decls()) {
2011       if (!ODRHash::isSubDeclToBeProcessed(D, DC))
2012         continue;
2013       Hashes.emplace_back(D, computeODRHash(D));
2014     }
2015   };
2016 
2017   DeclHashes FirstHashes;
2018   DeclHashes SecondHashes;
2019   // Use definition as DeclContext because definitions are merged when
2020   // DeclContexts are merged and separate when DeclContexts are separate.
2021   PopulateHashes(FirstHashes, FirstID, FirstID->getDefinition());
2022   PopulateHashes(SecondHashes, SecondID, SecondID->getDefinition());
2023 
2024   DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2025   ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2026   ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2027   const Decl *FirstDecl = DR.FirstDecl;
2028   const Decl *SecondDecl = DR.SecondDecl;
2029 
2030   if (FirstDiffType == Other || SecondDiffType == Other) {
2031     diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2032                                   SecondModule);
2033     return true;
2034   }
2035 
2036   if (FirstDiffType != SecondDiffType) {
2037     diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2038                                           SecondModule);
2039     return true;
2040   }
2041 
2042   assert(FirstDiffType == SecondDiffType);
2043   switch (FirstDiffType) {
2044   // Already handled.
2045   case EndOfClass:
2046   case Other:
2047   // Cannot be contained by ObjCInterfaceDecl, invalid in this context.
2048   case Field:
2049   case TypeDef:
2050   case Var:
2051   // C++ only, invalid in this context.
2052   case PublicSpecifer:
2053   case PrivateSpecifer:
2054   case ProtectedSpecifer:
2055   case StaticAssert:
2056   case CXXMethod:
2057   case TypeAlias:
2058   case Friend:
2059   case FunctionTemplate:
2060     llvm_unreachable("Invalid diff type");
2061 
2062   case ObjCMethod: {
2063     if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2064                                       cast<ObjCMethodDecl>(FirstDecl),
2065                                       cast<ObjCMethodDecl>(SecondDecl)))
2066       return true;
2067     break;
2068   }
2069   case ObjCIvar: {
2070     if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2071                                  cast<FieldDecl>(FirstDecl),
2072                                  cast<FieldDecl>(SecondDecl)))
2073       return true;
2074 
2075     // Check if the access match.
2076     const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl);
2077     const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl);
2078     if (FirstIvar->getCanonicalAccessControl() !=
2079         SecondIvar->getCanonicalAccessControl()) {
2080       DiagError(FirstIvar->getLocation(), FirstIvar->getSourceRange(),
2081                 IVarAccess)
2082           << FirstIvar->getName()
2083           << (int)FirstIvar->getCanonicalAccessControl();
2084       DiagNote(SecondIvar->getLocation(), SecondIvar->getSourceRange(),
2085                IVarAccess)
2086           << SecondIvar->getName()
2087           << (int)SecondIvar->getCanonicalAccessControl();
2088       return true;
2089     }
2090     break;
2091   }
2092   case ObjCProperty: {
2093     if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2094                                         cast<ObjCPropertyDecl>(FirstDecl),
2095                                         cast<ObjCPropertyDecl>(SecondDecl)))
2096       return true;
2097     break;
2098   }
2099   }
2100 
2101   Diag(FirstDecl->getLocation(),
2102        diag::err_module_odr_violation_mismatch_decl_unknown)
2103       << FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2104       << FirstDecl->getSourceRange();
2105   Diag(SecondDecl->getLocation(),
2106        diag::note_module_odr_violation_mismatch_decl_unknown)
2107       << SecondModule.empty() << SecondModule << FirstDiffType
2108       << SecondDecl->getSourceRange();
2109   return true;
2110 }
2111 
diagnoseMismatch(const ObjCProtocolDecl * FirstProtocol,const ObjCProtocolDecl * SecondProtocol,const struct ObjCProtocolDecl::DefinitionData * SecondDD) const2112 bool ODRDiagsEmitter::diagnoseMismatch(
2113     const ObjCProtocolDecl *FirstProtocol,
2114     const ObjCProtocolDecl *SecondProtocol,
2115     const struct ObjCProtocolDecl::DefinitionData *SecondDD) const {
2116   if (FirstProtocol == SecondProtocol)
2117     return false;
2118 
2119   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstProtocol);
2120   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondProtocol);
2121 
2122   const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2123   assert(FirstDD && SecondDD && "Definitions without DefinitionData");
2124   // Diagnostics from ObjCProtocol DefinitionData are emitted here.
2125   if (FirstDD != SecondDD) {
2126     // Check both protocols reference the same protocols.
2127     const ObjCProtocolList &FirstProtocols =
2128         FirstProtocol->getReferencedProtocols();
2129     const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols;
2130     if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2131                                      SecondProtocols, SecondProtocol,
2132                                      SecondModule))
2133       return true;
2134   }
2135 
2136   auto PopulateHashes = [](DeclHashes &Hashes, const ObjCProtocolDecl *ID,
2137                            const DeclContext *DC) {
2138     for (const Decl *D : ID->decls()) {
2139       if (!ODRHash::isSubDeclToBeProcessed(D, DC))
2140         continue;
2141       Hashes.emplace_back(D, computeODRHash(D));
2142     }
2143   };
2144 
2145   DeclHashes FirstHashes;
2146   DeclHashes SecondHashes;
2147   // Use definition as DeclContext because definitions are merged when
2148   // DeclContexts are merged and separate when DeclContexts are separate.
2149   PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition());
2150   PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition());
2151 
2152   DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2153   ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2154   ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2155   const Decl *FirstDecl = DR.FirstDecl;
2156   const Decl *SecondDecl = DR.SecondDecl;
2157 
2158   if (FirstDiffType == Other || SecondDiffType == Other) {
2159     diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2160                                   SecondProtocol, SecondModule);
2161     return true;
2162   }
2163 
2164   if (FirstDiffType != SecondDiffType) {
2165     diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2166                                           SecondProtocol, SecondModule);
2167     return true;
2168   }
2169 
2170   assert(FirstDiffType == SecondDiffType);
2171   switch (FirstDiffType) {
2172   // Already handled.
2173   case EndOfClass:
2174   case Other:
2175   // Cannot be contained by ObjCProtocolDecl, invalid in this context.
2176   case Field:
2177   case TypeDef:
2178   case Var:
2179   case ObjCIvar:
2180   // C++ only, invalid in this context.
2181   case PublicSpecifer:
2182   case PrivateSpecifer:
2183   case ProtectedSpecifer:
2184   case StaticAssert:
2185   case CXXMethod:
2186   case TypeAlias:
2187   case Friend:
2188   case FunctionTemplate:
2189     llvm_unreachable("Invalid diff type");
2190   case ObjCMethod: {
2191     if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2192                                       cast<ObjCMethodDecl>(FirstDecl),
2193                                       cast<ObjCMethodDecl>(SecondDecl)))
2194       return true;
2195     break;
2196   }
2197   case ObjCProperty: {
2198     if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2199                                         SecondModule,
2200                                         cast<ObjCPropertyDecl>(FirstDecl),
2201                                         cast<ObjCPropertyDecl>(SecondDecl)))
2202       return true;
2203     break;
2204   }
2205   }
2206 
2207   Diag(FirstDecl->getLocation(),
2208        diag::err_module_odr_violation_mismatch_decl_unknown)
2209       << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2210       << FirstDecl->getSourceRange();
2211   Diag(SecondDecl->getLocation(),
2212        diag::note_module_odr_violation_mismatch_decl_unknown)
2213       << SecondModule.empty() << SecondModule << FirstDiffType
2214       << SecondDecl->getSourceRange();
2215   return true;
2216 }
2217