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           QualType FirstType = FirstTTPD->getDefaultArgument();
1413           QualType SecondType = SecondTTPD->getDefaultArgument();
1414           if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
1415             DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1416                 << (i + 1) << FirstType;
1417             DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1418                 << (i + 1) << SecondType;
1419             return true;
1420           }
1421         }
1422 
1423         if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1424           DiagTemplateError(FunctionTemplatePackParameter)
1425               << (i + 1) << FirstTTPD->isParameterPack();
1426           DiagTemplateNote(FunctionTemplatePackParameter)
1427               << (i + 1) << SecondTTPD->isParameterPack();
1428           return true;
1429         }
1430       }
1431 
1432       if (isa<TemplateTemplateParmDecl>(FirstParam) &&
1433           isa<TemplateTemplateParmDecl>(SecondParam)) {
1434         TemplateTemplateParmDecl *FirstTTPD =
1435             cast<TemplateTemplateParmDecl>(FirstParam);
1436         TemplateTemplateParmDecl *SecondTTPD =
1437             cast<TemplateTemplateParmDecl>(SecondParam);
1438 
1439         TemplateParameterList *FirstTPL = FirstTTPD->getTemplateParameters();
1440         TemplateParameterList *SecondTPL = SecondTTPD->getTemplateParameters();
1441 
1442         auto ComputeTemplateParameterListODRHash =
1443             [](const TemplateParameterList *TPL) {
1444               assert(TPL);
1445               ODRHash Hasher;
1446               Hasher.AddTemplateParameterList(TPL);
1447               return Hasher.CalculateHash();
1448             };
1449 
1450         if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1451             ComputeTemplateParameterListODRHash(SecondTPL)) {
1452           DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1453           DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1454           return true;
1455         }
1456 
1457         bool HasFirstDefaultArgument =
1458             FirstTTPD->hasDefaultArgument() &&
1459             !FirstTTPD->defaultArgumentWasInherited();
1460         bool HasSecondDefaultArgument =
1461             SecondTTPD->hasDefaultArgument() &&
1462             !SecondTTPD->defaultArgumentWasInherited();
1463         if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1464           DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1465               << (i + 1) << HasFirstDefaultArgument;
1466           DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1467               << (i + 1) << HasSecondDefaultArgument;
1468           return true;
1469         }
1470 
1471         if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1472           TemplateArgument FirstTA =
1473               FirstTTPD->getDefaultArgument().getArgument();
1474           TemplateArgument SecondTA =
1475               SecondTTPD->getDefaultArgument().getArgument();
1476           if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {
1477             DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1478                 << (i + 1) << FirstTA;
1479             DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1480                 << (i + 1) << SecondTA;
1481             return true;
1482           }
1483         }
1484 
1485         if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1486           DiagTemplateError(FunctionTemplatePackParameter)
1487               << (i + 1) << FirstTTPD->isParameterPack();
1488           DiagTemplateNote(FunctionTemplatePackParameter)
1489               << (i + 1) << SecondTTPD->isParameterPack();
1490           return true;
1491         }
1492       }
1493 
1494       if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
1495           isa<NonTypeTemplateParmDecl>(SecondParam)) {
1496         NonTypeTemplateParmDecl *FirstNTTPD =
1497             cast<NonTypeTemplateParmDecl>(FirstParam);
1498         NonTypeTemplateParmDecl *SecondNTTPD =
1499             cast<NonTypeTemplateParmDecl>(SecondParam);
1500 
1501         QualType FirstType = FirstNTTPD->getType();
1502         QualType SecondType = SecondNTTPD->getType();
1503         if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
1504           DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1505           DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1506           return true;
1507         }
1508 
1509         bool HasFirstDefaultArgument =
1510             FirstNTTPD->hasDefaultArgument() &&
1511             !FirstNTTPD->defaultArgumentWasInherited();
1512         bool HasSecondDefaultArgument =
1513             SecondNTTPD->hasDefaultArgument() &&
1514             !SecondNTTPD->defaultArgumentWasInherited();
1515         if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1516           DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1517               << (i + 1) << HasFirstDefaultArgument;
1518           DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1519               << (i + 1) << HasSecondDefaultArgument;
1520           return true;
1521         }
1522 
1523         if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1524           Expr *FirstDefaultArgument = FirstNTTPD->getDefaultArgument();
1525           Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument();
1526           if (computeODRHash(FirstDefaultArgument) !=
1527               computeODRHash(SecondDefaultArgument)) {
1528             DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1529                 << (i + 1) << FirstDefaultArgument;
1530             DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1531                 << (i + 1) << SecondDefaultArgument;
1532             return true;
1533           }
1534         }
1535 
1536         if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) {
1537           DiagTemplateError(FunctionTemplatePackParameter)
1538               << (i + 1) << FirstNTTPD->isParameterPack();
1539           DiagTemplateNote(FunctionTemplatePackParameter)
1540               << (i + 1) << SecondNTTPD->isParameterPack();
1541           return true;
1542         }
1543       }
1544     }
1545     break;
1546   }
1547   }
1548 
1549   Diag(FirstDecl->getLocation(),
1550        diag::err_module_odr_violation_mismatch_decl_unknown)
1551       << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1552       << FirstDecl->getSourceRange();
1553   Diag(SecondDecl->getLocation(),
1554        diag::note_module_odr_violation_mismatch_decl_unknown)
1555       << SecondModule.empty() << SecondModule << FirstDiffType
1556       << SecondDecl->getSourceRange();
1557   return true;
1558 }
1559 
diagnoseMismatch(const RecordDecl * FirstRecord,const RecordDecl * SecondRecord) const1560 bool ODRDiagsEmitter::diagnoseMismatch(const RecordDecl *FirstRecord,
1561                                        const RecordDecl *SecondRecord) const {
1562   if (FirstRecord == SecondRecord)
1563     return false;
1564 
1565   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
1566   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
1567 
1568   auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,
1569                            const DeclContext *DC) {
1570     for (const Decl *D : Record->decls()) {
1571       if (!ODRHash::isSubDeclToBeProcessed(D, DC))
1572         continue;
1573       Hashes.emplace_back(D, computeODRHash(D));
1574     }
1575   };
1576 
1577   DeclHashes FirstHashes;
1578   DeclHashes SecondHashes;
1579   const DeclContext *DC = FirstRecord;
1580   PopulateHashes(FirstHashes, FirstRecord, DC);
1581   PopulateHashes(SecondHashes, SecondRecord, DC);
1582 
1583   DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1584   ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1585   ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1586   const Decl *FirstDecl = DR.FirstDecl;
1587   const Decl *SecondDecl = DR.SecondDecl;
1588 
1589   if (FirstDiffType == Other || SecondDiffType == Other) {
1590     diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1591                                   SecondModule);
1592     return true;
1593   }
1594 
1595   if (FirstDiffType != SecondDiffType) {
1596     diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1597                                           SecondRecord, SecondModule);
1598     return true;
1599   }
1600 
1601   assert(FirstDiffType == SecondDiffType);
1602   switch (FirstDiffType) {
1603   // Already handled.
1604   case EndOfClass:
1605   case Other:
1606   // C++ only, invalid in this context.
1607   case PublicSpecifer:
1608   case PrivateSpecifer:
1609   case ProtectedSpecifer:
1610   case StaticAssert:
1611   case CXXMethod:
1612   case TypeAlias:
1613   case Friend:
1614   case FunctionTemplate:
1615   // Cannot be contained by RecordDecl, invalid in this context.
1616   case ObjCMethod:
1617   case ObjCIvar:
1618   case ObjCProperty:
1619     llvm_unreachable("Invalid diff type");
1620 
1621   case Field: {
1622     if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1623                                  cast<FieldDecl>(FirstDecl),
1624                                  cast<FieldDecl>(SecondDecl)))
1625       return true;
1626     break;
1627   }
1628   case TypeDef: {
1629     if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1630                                    cast<TypedefNameDecl>(FirstDecl),
1631                                    cast<TypedefNameDecl>(SecondDecl),
1632                                    /*IsTypeAlias=*/false))
1633       return true;
1634     break;
1635   }
1636   case Var: {
1637     if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1638                                cast<VarDecl>(FirstDecl),
1639                                cast<VarDecl>(SecondDecl)))
1640       return true;
1641     break;
1642   }
1643   }
1644 
1645   Diag(FirstDecl->getLocation(),
1646        diag::err_module_odr_violation_mismatch_decl_unknown)
1647       << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1648       << FirstDecl->getSourceRange();
1649   Diag(SecondDecl->getLocation(),
1650        diag::note_module_odr_violation_mismatch_decl_unknown)
1651       << SecondModule.empty() << SecondModule << FirstDiffType
1652       << SecondDecl->getSourceRange();
1653   return true;
1654 }
1655 
diagnoseMismatch(const FunctionDecl * FirstFunction,const FunctionDecl * SecondFunction) const1656 bool ODRDiagsEmitter::diagnoseMismatch(
1657     const FunctionDecl *FirstFunction,
1658     const FunctionDecl *SecondFunction) const {
1659   if (FirstFunction == SecondFunction)
1660     return false;
1661 
1662   // Keep in sync with select options in err_module_odr_violation_function.
1663   enum ODRFunctionDifference {
1664     ReturnType,
1665     ParameterName,
1666     ParameterType,
1667     ParameterSingleDefaultArgument,
1668     ParameterDifferentDefaultArgument,
1669     FunctionBody,
1670   };
1671 
1672   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);
1673   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondFunction);
1674 
1675   auto DiagError = [FirstFunction, &FirstModule,
1676                     this](SourceLocation Loc, SourceRange Range,
1677                           ODRFunctionDifference DiffType) {
1678     return Diag(Loc, diag::err_module_odr_violation_function)
1679            << FirstFunction << FirstModule.empty() << FirstModule << Range
1680            << DiffType;
1681   };
1682   auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1683                                         ODRFunctionDifference DiffType) {
1684     return Diag(Loc, diag::note_module_odr_violation_function)
1685            << SecondModule << Range << DiffType;
1686   };
1687 
1688   if (computeODRHash(FirstFunction->getReturnType()) !=
1689       computeODRHash(SecondFunction->getReturnType())) {
1690     DiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),
1691               FirstFunction->getReturnTypeSourceRange(), ReturnType)
1692         << FirstFunction->getReturnType();
1693     DiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),
1694              SecondFunction->getReturnTypeSourceRange(), ReturnType)
1695         << SecondFunction->getReturnType();
1696     return true;
1697   }
1698 
1699   assert(FirstFunction->param_size() == SecondFunction->param_size() &&
1700          "Merged functions with different number of parameters");
1701 
1702   size_t ParamSize = FirstFunction->param_size();
1703   for (unsigned I = 0; I < ParamSize; ++I) {
1704     const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I);
1705     const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I);
1706 
1707     assert(Context.hasSameType(FirstParam->getType(), SecondParam->getType()) &&
1708            "Merged function has different parameter types.");
1709 
1710     if (FirstParam->getDeclName() != SecondParam->getDeclName()) {
1711       DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1712                 ParameterName)
1713           << I + 1 << FirstParam->getDeclName();
1714       DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1715                ParameterName)
1716           << I + 1 << SecondParam->getDeclName();
1717       return true;
1718     };
1719 
1720     QualType FirstParamType = FirstParam->getType();
1721     QualType SecondParamType = SecondParam->getType();
1722     if (FirstParamType != SecondParamType &&
1723         computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) {
1724       if (const DecayedType *ParamDecayedType =
1725               FirstParamType->getAs<DecayedType>()) {
1726         DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1727                   ParameterType)
1728             << (I + 1) << FirstParamType << true
1729             << ParamDecayedType->getOriginalType();
1730       } else {
1731         DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1732                   ParameterType)
1733             << (I + 1) << FirstParamType << false;
1734       }
1735 
1736       if (const DecayedType *ParamDecayedType =
1737               SecondParamType->getAs<DecayedType>()) {
1738         DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1739                  ParameterType)
1740             << (I + 1) << SecondParamType << true
1741             << ParamDecayedType->getOriginalType();
1742       } else {
1743         DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1744                  ParameterType)
1745             << (I + 1) << SecondParamType << false;
1746       }
1747       return true;
1748     }
1749 
1750     // Note, these calls can trigger deserialization.
1751     const Expr *FirstInit = FirstParam->getInit();
1752     const Expr *SecondInit = SecondParam->getInit();
1753     if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1754       DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1755                 ParameterSingleDefaultArgument)
1756           << (I + 1) << (FirstInit == nullptr)
1757           << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
1758       DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1759                ParameterSingleDefaultArgument)
1760           << (I + 1) << (SecondInit == nullptr)
1761           << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
1762       return true;
1763     }
1764 
1765     if (FirstInit && SecondInit &&
1766         computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1767       DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1768                 ParameterDifferentDefaultArgument)
1769           << (I + 1) << FirstInit->getSourceRange();
1770       DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1771                ParameterDifferentDefaultArgument)
1772           << (I + 1) << SecondInit->getSourceRange();
1773       return true;
1774     }
1775 
1776     assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) &&
1777            "Undiagnosed parameter difference.");
1778   }
1779 
1780   // If no error has been generated before now, assume the problem is in
1781   // the body and generate a message.
1782   DiagError(FirstFunction->getLocation(), FirstFunction->getSourceRange(),
1783             FunctionBody);
1784   DiagNote(SecondFunction->getLocation(), SecondFunction->getSourceRange(),
1785            FunctionBody);
1786   return true;
1787 }
1788 
diagnoseMismatch(const EnumDecl * FirstEnum,const EnumDecl * SecondEnum) const1789 bool ODRDiagsEmitter::diagnoseMismatch(const EnumDecl *FirstEnum,
1790                                        const EnumDecl *SecondEnum) const {
1791   if (FirstEnum == SecondEnum)
1792     return false;
1793 
1794   // Keep in sync with select options in err_module_odr_violation_enum.
1795   enum ODREnumDifference {
1796     SingleScopedEnum,
1797     EnumTagKeywordMismatch,
1798     SingleSpecifiedType,
1799     DifferentSpecifiedTypes,
1800     DifferentNumberEnumConstants,
1801     EnumConstantName,
1802     EnumConstantSingleInitializer,
1803     EnumConstantDifferentInitializer,
1804   };
1805 
1806   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum);
1807   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondEnum);
1808 
1809   auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor,
1810                                                    ODREnumDifference DiffType) {
1811     return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1812            << FirstEnum << FirstModule.empty() << FirstModule
1813            << DiagAnchor->getSourceRange() << DiffType;
1814   };
1815   auto DiagNote = [&SecondModule, this](const auto *DiagAnchor,
1816                                         ODREnumDifference DiffType) {
1817     return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1818            << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1819   };
1820 
1821   if (FirstEnum->isScoped() != SecondEnum->isScoped()) {
1822     DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();
1823     DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();
1824     return true;
1825   }
1826 
1827   if (FirstEnum->isScoped() && SecondEnum->isScoped()) {
1828     if (FirstEnum->isScopedUsingClassTag() !=
1829         SecondEnum->isScopedUsingClassTag()) {
1830       DiagError(FirstEnum, EnumTagKeywordMismatch)
1831           << FirstEnum->isScopedUsingClassTag();
1832       DiagNote(SecondEnum, EnumTagKeywordMismatch)
1833           << SecondEnum->isScopedUsingClassTag();
1834       return true;
1835     }
1836   }
1837 
1838   QualType FirstUnderlyingType =
1839       FirstEnum->getIntegerTypeSourceInfo()
1840           ? FirstEnum->getIntegerTypeSourceInfo()->getType()
1841           : QualType();
1842   QualType SecondUnderlyingType =
1843       SecondEnum->getIntegerTypeSourceInfo()
1844           ? SecondEnum->getIntegerTypeSourceInfo()->getType()
1845           : QualType();
1846   if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {
1847     DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull();
1848     DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull();
1849     return true;
1850   }
1851 
1852   if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {
1853     if (computeODRHash(FirstUnderlyingType) !=
1854         computeODRHash(SecondUnderlyingType)) {
1855       DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1856       DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1857       return true;
1858     }
1859   }
1860 
1861   // Compare enum constants.
1862   using DeclHashes =
1863       llvm::SmallVector<std::pair<const EnumConstantDecl *, unsigned>, 4>;
1864   auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, const EnumDecl *Enum) {
1865     for (const Decl *D : Enum->decls()) {
1866       // Due to decl merging, the first EnumDecl is the parent of
1867       // Decls in both records.
1868       if (!ODRHash::isSubDeclToBeProcessed(D, FirstEnum))
1869         continue;
1870       assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");
1871       Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D));
1872     }
1873   };
1874   DeclHashes FirstHashes;
1875   PopulateHashes(FirstHashes, FirstEnum);
1876   DeclHashes SecondHashes;
1877   PopulateHashes(SecondHashes, SecondEnum);
1878 
1879   if (FirstHashes.size() != SecondHashes.size()) {
1880     DiagError(FirstEnum, DifferentNumberEnumConstants)
1881         << (int)FirstHashes.size();
1882     DiagNote(SecondEnum, DifferentNumberEnumConstants)
1883         << (int)SecondHashes.size();
1884     return true;
1885   }
1886 
1887   for (unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {
1888     if (FirstHashes[I].second == SecondHashes[I].second)
1889       continue;
1890     const EnumConstantDecl *FirstConstant = FirstHashes[I].first;
1891     const EnumConstantDecl *SecondConstant = SecondHashes[I].first;
1892 
1893     if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) {
1894       DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1895       DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1896       return true;
1897     }
1898 
1899     const Expr *FirstInit = FirstConstant->getInitExpr();
1900     const Expr *SecondInit = SecondConstant->getInitExpr();
1901     if (!FirstInit && !SecondInit)
1902       continue;
1903 
1904     if (!FirstInit || !SecondInit) {
1905       DiagError(FirstConstant, EnumConstantSingleInitializer)
1906           << I + 1 << FirstConstant << (FirstInit != nullptr);
1907       DiagNote(SecondConstant, EnumConstantSingleInitializer)
1908           << I + 1 << SecondConstant << (SecondInit != nullptr);
1909       return true;
1910     }
1911 
1912     if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1913       DiagError(FirstConstant, EnumConstantDifferentInitializer)
1914           << I + 1 << FirstConstant;
1915       DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1916           << I + 1 << SecondConstant;
1917       return true;
1918     }
1919   }
1920   return false;
1921 }
1922 
diagnoseMismatch(const ObjCInterfaceDecl * FirstID,const ObjCInterfaceDecl * SecondID,const struct ObjCInterfaceDecl::DefinitionData * SecondDD) const1923 bool ODRDiagsEmitter::diagnoseMismatch(
1924     const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
1925     const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const {
1926   // Multiple different declarations got merged together; tell the user
1927   // where they came from.
1928   if (FirstID == SecondID)
1929     return false;
1930 
1931   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstID);
1932   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondID);
1933 
1934   // Keep in sync with err_module_odr_violation_objc_interface.
1935   enum ODRInterfaceDifference {
1936     SuperClassType,
1937     IVarAccess,
1938   };
1939 
1940   auto DiagError = [FirstID, &FirstModule,
1941                     this](SourceLocation Loc, SourceRange Range,
1942                           ODRInterfaceDifference DiffType) {
1943     return Diag(Loc, diag::err_module_odr_violation_objc_interface)
1944            << FirstID << FirstModule.empty() << FirstModule << Range
1945            << DiffType;
1946   };
1947   auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1948                                         ODRInterfaceDifference DiffType) {
1949     return Diag(Loc, diag::note_module_odr_violation_objc_interface)
1950            << SecondModule.empty() << SecondModule << Range << DiffType;
1951   };
1952 
1953   const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1954   assert(FirstDD && SecondDD && "Definitions without DefinitionData");
1955   if (FirstDD != SecondDD) {
1956     // Check for matching super class.
1957     auto GetSuperClassSourceRange = [](const TypeSourceInfo *SuperInfo,
1958                                        const ObjCInterfaceDecl *ID) {
1959       if (!SuperInfo)
1960         return ID->getSourceRange();
1961       TypeLoc Loc = SuperInfo->getTypeLoc();
1962       return SourceRange(Loc.getBeginLoc(), Loc.getEndLoc());
1963     };
1964 
1965     ObjCInterfaceDecl *FirstSuperClass = FirstID->getSuperClass();
1966     ObjCInterfaceDecl *SecondSuperClass = nullptr;
1967     const TypeSourceInfo *FirstSuperInfo = FirstID->getSuperClassTInfo();
1968     const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;
1969     if (SecondSuperInfo)
1970       SecondSuperClass =
1971           SecondSuperInfo->getType()->castAs<ObjCObjectType>()->getInterface();
1972 
1973     if ((FirstSuperClass && SecondSuperClass &&
1974          FirstSuperClass->getODRHash() != SecondSuperClass->getODRHash()) ||
1975         (FirstSuperClass && !SecondSuperClass) ||
1976         (!FirstSuperClass && SecondSuperClass)) {
1977       QualType FirstType;
1978       if (FirstSuperInfo)
1979         FirstType = FirstSuperInfo->getType();
1980 
1981       DiagError(FirstID->getLocation(),
1982                 GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1983                 SuperClassType)
1984           << (bool)FirstSuperInfo << FirstType;
1985 
1986       QualType SecondType;
1987       if (SecondSuperInfo)
1988         SecondType = SecondSuperInfo->getType();
1989 
1990       DiagNote(SecondID->getLocation(),
1991                GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1992                SuperClassType)
1993           << (bool)SecondSuperInfo << SecondType;
1994       return true;
1995     }
1996 
1997     // Check both interfaces reference the same protocols.
1998     auto &FirstProtos = FirstID->getReferencedProtocols();
1999     auto &SecondProtos = SecondDD->ReferencedProtocols;
2000     if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
2001                                      SecondProtos, SecondID, SecondModule))
2002       return true;
2003   }
2004 
2005   auto PopulateHashes = [](DeclHashes &Hashes, const ObjCInterfaceDecl *ID,
2006                            const DeclContext *DC) {
2007     for (auto *D : ID->decls()) {
2008       if (!ODRHash::isSubDeclToBeProcessed(D, DC))
2009         continue;
2010       Hashes.emplace_back(D, computeODRHash(D));
2011     }
2012   };
2013 
2014   DeclHashes FirstHashes;
2015   DeclHashes SecondHashes;
2016   // Use definition as DeclContext because definitions are merged when
2017   // DeclContexts are merged and separate when DeclContexts are separate.
2018   PopulateHashes(FirstHashes, FirstID, FirstID->getDefinition());
2019   PopulateHashes(SecondHashes, SecondID, SecondID->getDefinition());
2020 
2021   DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2022   ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2023   ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2024   const Decl *FirstDecl = DR.FirstDecl;
2025   const Decl *SecondDecl = DR.SecondDecl;
2026 
2027   if (FirstDiffType == Other || SecondDiffType == Other) {
2028     diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2029                                   SecondModule);
2030     return true;
2031   }
2032 
2033   if (FirstDiffType != SecondDiffType) {
2034     diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2035                                           SecondModule);
2036     return true;
2037   }
2038 
2039   assert(FirstDiffType == SecondDiffType);
2040   switch (FirstDiffType) {
2041   // Already handled.
2042   case EndOfClass:
2043   case Other:
2044   // Cannot be contained by ObjCInterfaceDecl, invalid in this context.
2045   case Field:
2046   case TypeDef:
2047   case Var:
2048   // C++ only, invalid in this context.
2049   case PublicSpecifer:
2050   case PrivateSpecifer:
2051   case ProtectedSpecifer:
2052   case StaticAssert:
2053   case CXXMethod:
2054   case TypeAlias:
2055   case Friend:
2056   case FunctionTemplate:
2057     llvm_unreachable("Invalid diff type");
2058 
2059   case ObjCMethod: {
2060     if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2061                                       cast<ObjCMethodDecl>(FirstDecl),
2062                                       cast<ObjCMethodDecl>(SecondDecl)))
2063       return true;
2064     break;
2065   }
2066   case ObjCIvar: {
2067     if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2068                                  cast<FieldDecl>(FirstDecl),
2069                                  cast<FieldDecl>(SecondDecl)))
2070       return true;
2071 
2072     // Check if the access match.
2073     const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl);
2074     const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl);
2075     if (FirstIvar->getCanonicalAccessControl() !=
2076         SecondIvar->getCanonicalAccessControl()) {
2077       DiagError(FirstIvar->getLocation(), FirstIvar->getSourceRange(),
2078                 IVarAccess)
2079           << FirstIvar->getName()
2080           << (int)FirstIvar->getCanonicalAccessControl();
2081       DiagNote(SecondIvar->getLocation(), SecondIvar->getSourceRange(),
2082                IVarAccess)
2083           << SecondIvar->getName()
2084           << (int)SecondIvar->getCanonicalAccessControl();
2085       return true;
2086     }
2087     break;
2088   }
2089   case ObjCProperty: {
2090     if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2091                                         cast<ObjCPropertyDecl>(FirstDecl),
2092                                         cast<ObjCPropertyDecl>(SecondDecl)))
2093       return true;
2094     break;
2095   }
2096   }
2097 
2098   Diag(FirstDecl->getLocation(),
2099        diag::err_module_odr_violation_mismatch_decl_unknown)
2100       << FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2101       << FirstDecl->getSourceRange();
2102   Diag(SecondDecl->getLocation(),
2103        diag::note_module_odr_violation_mismatch_decl_unknown)
2104       << SecondModule.empty() << SecondModule << FirstDiffType
2105       << SecondDecl->getSourceRange();
2106   return true;
2107 }
2108 
diagnoseMismatch(const ObjCProtocolDecl * FirstProtocol,const ObjCProtocolDecl * SecondProtocol,const struct ObjCProtocolDecl::DefinitionData * SecondDD) const2109 bool ODRDiagsEmitter::diagnoseMismatch(
2110     const ObjCProtocolDecl *FirstProtocol,
2111     const ObjCProtocolDecl *SecondProtocol,
2112     const struct ObjCProtocolDecl::DefinitionData *SecondDD) const {
2113   if (FirstProtocol == SecondProtocol)
2114     return false;
2115 
2116   std::string FirstModule = getOwningModuleNameForDiagnostic(FirstProtocol);
2117   std::string SecondModule = getOwningModuleNameForDiagnostic(SecondProtocol);
2118 
2119   const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2120   assert(FirstDD && SecondDD && "Definitions without DefinitionData");
2121   // Diagnostics from ObjCProtocol DefinitionData are emitted here.
2122   if (FirstDD != SecondDD) {
2123     // Check both protocols reference the same protocols.
2124     const ObjCProtocolList &FirstProtocols =
2125         FirstProtocol->getReferencedProtocols();
2126     const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols;
2127     if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2128                                      SecondProtocols, SecondProtocol,
2129                                      SecondModule))
2130       return true;
2131   }
2132 
2133   auto PopulateHashes = [](DeclHashes &Hashes, const ObjCProtocolDecl *ID,
2134                            const DeclContext *DC) {
2135     for (const Decl *D : ID->decls()) {
2136       if (!ODRHash::isSubDeclToBeProcessed(D, DC))
2137         continue;
2138       Hashes.emplace_back(D, computeODRHash(D));
2139     }
2140   };
2141 
2142   DeclHashes FirstHashes;
2143   DeclHashes SecondHashes;
2144   // Use definition as DeclContext because definitions are merged when
2145   // DeclContexts are merged and separate when DeclContexts are separate.
2146   PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition());
2147   PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition());
2148 
2149   DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2150   ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2151   ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2152   const Decl *FirstDecl = DR.FirstDecl;
2153   const Decl *SecondDecl = DR.SecondDecl;
2154 
2155   if (FirstDiffType == Other || SecondDiffType == Other) {
2156     diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2157                                   SecondProtocol, SecondModule);
2158     return true;
2159   }
2160 
2161   if (FirstDiffType != SecondDiffType) {
2162     diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2163                                           SecondProtocol, SecondModule);
2164     return true;
2165   }
2166 
2167   assert(FirstDiffType == SecondDiffType);
2168   switch (FirstDiffType) {
2169   // Already handled.
2170   case EndOfClass:
2171   case Other:
2172   // Cannot be contained by ObjCProtocolDecl, invalid in this context.
2173   case Field:
2174   case TypeDef:
2175   case Var:
2176   case ObjCIvar:
2177   // C++ only, invalid in this context.
2178   case PublicSpecifer:
2179   case PrivateSpecifer:
2180   case ProtectedSpecifer:
2181   case StaticAssert:
2182   case CXXMethod:
2183   case TypeAlias:
2184   case Friend:
2185   case FunctionTemplate:
2186     llvm_unreachable("Invalid diff type");
2187   case ObjCMethod: {
2188     if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2189                                       cast<ObjCMethodDecl>(FirstDecl),
2190                                       cast<ObjCMethodDecl>(SecondDecl)))
2191       return true;
2192     break;
2193   }
2194   case ObjCProperty: {
2195     if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2196                                         SecondModule,
2197                                         cast<ObjCPropertyDecl>(FirstDecl),
2198                                         cast<ObjCPropertyDecl>(SecondDecl)))
2199       return true;
2200     break;
2201   }
2202   }
2203 
2204   Diag(FirstDecl->getLocation(),
2205        diag::err_module_odr_violation_mismatch_decl_unknown)
2206       << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2207       << FirstDecl->getSourceRange();
2208   Diag(SecondDecl->getLocation(),
2209        diag::note_module_odr_violation_mismatch_decl_unknown)
2210       << SecondModule.empty() << SecondModule << FirstDiffType
2211       << SecondDecl->getSourceRange();
2212   return true;
2213 }
2214