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