clang  16.0.0git
ODRDiagsEmitter.cpp
Go to the documentation of this file.
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 
10 #include "clang/AST/DeclFriend.h"
11 #include "clang/AST/DeclTemplate.h"
12 #include "clang/AST/ODRHash.h"
14 #include "clang/Basic/Module.h"
15 
16 using namespace clang;
17 
18 static unsigned computeODRHash(QualType Ty) {
19  ODRHash Hasher;
20  Hasher.AddQualType(Ty);
21  return Hasher.CalculateHash();
22 }
23 
24 static unsigned computeODRHash(const Stmt *S) {
25  ODRHash Hasher;
26  Hasher.AddStmt(S);
27  return Hasher.CalculateHash();
28 }
29 
30 static unsigned computeODRHash(const Decl *D) {
31  assert(D);
32  ODRHash Hasher;
33  Hasher.AddSubDecl(D);
34  return Hasher.CalculateHash();
35 }
36 
37 static unsigned computeODRHash(const TemplateArgument &TA) {
38  ODRHash Hasher;
39  Hasher.AddTemplateArgument(TA);
40  return Hasher.CalculateHash();
41 }
42 
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>
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 
144 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 << 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  assert(Context.hasSameType(FirstField->getType(), SecondField->getType()));
179  (void)Context;
180 
181  QualType FirstType = FirstField->getType();
182  QualType SecondType = SecondField->getType();
183  if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
184  DiagError(FieldTypeName) << FirstII << FirstType;
185  DiagNote(FieldTypeName) << SecondII << SecondType;
186  return true;
187  }
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 
246 bool ODRDiagsEmitter::diagnoseSubMismatchTypedef(
247  const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
248  const TypedefNameDecl *FirstTD, const TypedefNameDecl *SecondTD,
249  bool IsTypeAlias) const {
250  enum ODRTypedefDifference {
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 
286 bool ODRDiagsEmitter::diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
287  StringRef FirstModule,
288  StringRef SecondModule,
289  const VarDecl *FirstVD,
290  const VarDecl *SecondVD) const {
291  enum ODRVarDifference {
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 
361 bool ODRDiagsEmitter::diagnoseSubMismatchProtocols(
362  const ObjCProtocolList &FirstProtocols,
363  const ObjCContainerDecl *FirstContainer, StringRef FirstModule,
364  const ObjCProtocolList &SecondProtocols,
365  const ObjCContainerDecl *SecondContainer, StringRef SecondModule) const {
366  // Keep in sync with err_module_odr_violation_referenced_protocols.
367  enum ODRReferencedProtocolDifference {
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 
420 bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod(
421  const NamedDecl *FirstObjCContainer, StringRef FirstModule,
422  StringRef SecondModule, const ObjCMethodDecl *FirstMethod,
423  const ObjCMethodDecl *SecondMethod) const {
424  enum ODRMethodDifference {
425  ReturnType,
426  InstanceOrClass,
427  ControlLevel, // optional/required
428  DesignatedInitializer,
429  Directness,
430  Name,
431  };
432 
433  auto DiagError = [FirstObjCContainer, FirstModule, FirstMethod,
434  this](ODRMethodDifference DiffType) {
435  return Diag(FirstMethod->getLocation(),
436  diag::err_module_odr_violation_objc_method)
437  << FirstObjCContainer << FirstModule.empty() << FirstModule
438  << FirstMethod->getSourceRange() << DiffType;
439  };
440  auto DiagNote = [SecondModule, SecondMethod,
441  this](ODRMethodDifference DiffType) {
442  return Diag(SecondMethod->getLocation(),
443  diag::note_module_odr_violation_objc_method)
444  << SecondModule.empty() << SecondModule
445  << SecondMethod->getSourceRange() << DiffType;
446  };
447 
448  if (computeODRHash(FirstMethod->getReturnType()) !=
449  computeODRHash(SecondMethod->getReturnType())) {
450  DiagError(ReturnType) << FirstMethod << FirstMethod->getReturnType();
451  DiagNote(ReturnType) << SecondMethod << SecondMethod->getReturnType();
452  return true;
453  }
454 
455  if (FirstMethod->isInstanceMethod() != SecondMethod->isInstanceMethod()) {
456  DiagError(InstanceOrClass)
457  << FirstMethod << FirstMethod->isInstanceMethod();
458  DiagNote(InstanceOrClass)
459  << SecondMethod << SecondMethod->isInstanceMethod();
460  return true;
461  }
462  if (FirstMethod->getImplementationControl() !=
463  SecondMethod->getImplementationControl()) {
464  DiagError(ControlLevel) << FirstMethod->getImplementationControl();
465  DiagNote(ControlLevel) << SecondMethod->getImplementationControl();
466  return true;
467  }
468  if (FirstMethod->isThisDeclarationADesignatedInitializer() !=
469  SecondMethod->isThisDeclarationADesignatedInitializer()) {
470  DiagError(DesignatedInitializer)
471  << FirstMethod
472  << FirstMethod->isThisDeclarationADesignatedInitializer();
473  DiagNote(DesignatedInitializer)
474  << SecondMethod
475  << SecondMethod->isThisDeclarationADesignatedInitializer();
476  return true;
477  }
478  if (FirstMethod->isDirectMethod() != SecondMethod->isDirectMethod()) {
479  DiagError(Directness) << FirstMethod << FirstMethod->isDirectMethod();
480  DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();
481  return true;
482  }
483  if (diagnoseSubMismatchMethodParameters(Diags, FirstObjCContainer,
484  FirstModule, SecondModule,
485  FirstMethod, SecondMethod))
486  return true;
487 
488  // Check method name *after* looking at the parameters otherwise we get a
489  // less ideal diagnostics: a ObjCMethodName mismatch given that selectors
490  // for different parameters are likely to be different.
491  DeclarationName FirstName = FirstMethod->getDeclName();
492  DeclarationName SecondName = SecondMethod->getDeclName();
493  if (FirstName != SecondName) {
494  DiagError(Name) << FirstName;
495  DiagNote(Name) << SecondName;
496  return true;
497  }
498 
499  return false;
500 }
501 
502 bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
503  const NamedDecl *FirstObjCContainer, StringRef FirstModule,
504  StringRef SecondModule, const ObjCPropertyDecl *FirstProp,
505  const ObjCPropertyDecl *SecondProp) const {
506  enum ODRPropertyDifference {
507  Name,
508  Type,
509  ControlLevel, // optional/required
510  Attribute,
511  };
512 
513  auto DiagError = [FirstObjCContainer, FirstModule, FirstProp,
514  this](SourceLocation Loc, ODRPropertyDifference DiffType) {
515  return Diag(Loc, diag::err_module_odr_violation_objc_property)
516  << FirstObjCContainer << FirstModule.empty() << FirstModule
517  << FirstProp->getSourceRange() << DiffType;
518  };
519  auto DiagNote = [SecondModule, SecondProp,
520  this](SourceLocation Loc, ODRPropertyDifference DiffType) {
521  return Diag(Loc, diag::note_module_odr_violation_objc_property)
522  << SecondModule.empty() << SecondModule
523  << SecondProp->getSourceRange() << DiffType;
524  };
525 
526  IdentifierInfo *FirstII = FirstProp->getIdentifier();
527  IdentifierInfo *SecondII = SecondProp->getIdentifier();
528  if (FirstII->getName() != SecondII->getName()) {
529  DiagError(FirstProp->getLocation(), Name) << FirstII;
530  DiagNote(SecondProp->getLocation(), Name) << SecondII;
531  return true;
532  }
533  if (computeODRHash(FirstProp->getType()) !=
534  computeODRHash(SecondProp->getType())) {
535  DiagError(FirstProp->getLocation(), Type)
536  << FirstII << FirstProp->getType();
537  DiagNote(SecondProp->getLocation(), Type)
538  << SecondII << SecondProp->getType();
539  return true;
540  }
541  if (FirstProp->getPropertyImplementation() !=
542  SecondProp->getPropertyImplementation()) {
543  DiagError(FirstProp->getLocation(), ControlLevel)
544  << FirstProp->getPropertyImplementation();
545  DiagNote(SecondProp->getLocation(), ControlLevel)
546  << SecondProp->getPropertyImplementation();
547  return true;
548  }
549 
550  // Go over the property attributes and stop at the first mismatch.
551  unsigned FirstAttrs = (unsigned)FirstProp->getPropertyAttributes();
552  unsigned SecondAttrs = (unsigned)SecondProp->getPropertyAttributes();
553  if (FirstAttrs != SecondAttrs) {
554  for (unsigned I = 0; I < NumObjCPropertyAttrsBits; ++I) {
555  unsigned CheckedAttr = (1 << I);
556  if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))
557  continue;
558 
559  bool IsFirstWritten =
560  (unsigned)FirstProp->getPropertyAttributesAsWritten() & CheckedAttr;
561  bool IsSecondWritten =
562  (unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;
563  DiagError(IsFirstWritten ? FirstProp->getLParenLoc()
564  : FirstProp->getLocation(),
565  Attribute)
566  << FirstII << (I + 1) << IsFirstWritten;
567  DiagNote(IsSecondWritten ? SecondProp->getLParenLoc()
568  : SecondProp->getLocation(),
569  Attribute)
570  << SecondII << (I + 1);
571  return true;
572  }
573  }
574 
575  return false;
576 }
577 
578 ODRDiagsEmitter::DiffResult
579 ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,
580  DeclHashes &SecondHashes) {
581  auto DifferenceSelector = [](const Decl *D) {
582  assert(D && "valid Decl required");
583  switch (D->getKind()) {
584  default:
585  return Other;
586  case Decl::AccessSpec:
587  switch (D->getAccess()) {
588  case AS_public:
589  return PublicSpecifer;
590  case AS_private:
591  return PrivateSpecifer;
592  case AS_protected:
593  return ProtectedSpecifer;
594  case AS_none:
595  break;
596  }
597  llvm_unreachable("Invalid access specifier");
598  case Decl::StaticAssert:
599  return StaticAssert;
600  case Decl::Field:
601  return Field;
602  case Decl::CXXMethod:
603  case Decl::CXXConstructor:
604  case Decl::CXXDestructor:
605  return CXXMethod;
606  case Decl::TypeAlias:
607  return TypeAlias;
608  case Decl::Typedef:
609  return TypeDef;
610  case Decl::Var:
611  return Var;
612  case Decl::Friend:
613  return Friend;
614  case Decl::FunctionTemplate:
615  return FunctionTemplate;
616  case Decl::ObjCMethod:
617  return ObjCMethod;
618  case Decl::ObjCProperty:
619  return ObjCProperty;
620  }
621  };
622 
623  DiffResult DR;
624  auto FirstIt = FirstHashes.begin();
625  auto SecondIt = SecondHashes.begin();
626  while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
627  if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
628  FirstIt->second == SecondIt->second) {
629  ++FirstIt;
630  ++SecondIt;
631  continue;
632  }
633 
634  DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
635  DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
636 
637  DR.FirstDiffType =
638  DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;
639  DR.SecondDiffType =
640  DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;
641  return DR;
642  }
643  return DR;
644 }
645 
646 void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(
647  DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
648  const NamedDecl *SecondRecord, StringRef SecondModule) const {
649  Diag(FirstRecord->getLocation(),
650  diag::err_module_odr_violation_different_definitions)
651  << FirstRecord << FirstModule.empty() << FirstModule;
652 
653  if (DR.FirstDecl) {
654  Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
655  << FirstRecord << DR.FirstDecl->getSourceRange();
656  }
657 
658  Diag(SecondRecord->getLocation(),
659  diag::note_module_odr_violation_different_definitions)
660  << SecondModule;
661 
662  if (DR.SecondDecl) {
663  Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
664  << DR.SecondDecl->getSourceRange();
665  }
666 }
667 
668 void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
669  DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
670  const NamedDecl *SecondRecord, StringRef SecondModule) const {
671  auto GetMismatchedDeclLoc = [](const NamedDecl *Container,
672  ODRMismatchDecl DiffType, const Decl *D) {
673  SourceLocation Loc;
675  if (DiffType == EndOfClass) {
676  if (auto *Tag = dyn_cast<TagDecl>(Container))
677  Loc = Tag->getBraceRange().getEnd();
678  else
679  Loc = Container->getEndLoc();
680  } else {
681  Loc = D->getLocation();
682  Range = D->getSourceRange();
683  }
684  return std::make_pair(Loc, Range);
685  };
686 
687  auto FirstDiagInfo =
688  GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
689  Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
690  << FirstRecord << FirstModule.empty() << FirstModule
691  << FirstDiagInfo.second << DR.FirstDiffType;
692 
693  auto SecondDiagInfo =
694  GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
695  Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
696  << SecondModule.empty() << SecondModule << SecondDiagInfo.second
697  << DR.SecondDiffType;
698 }
699 
701  const CXXRecordDecl *FirstRecord, const CXXRecordDecl *SecondRecord,
702  const struct CXXRecordDecl::DefinitionData *SecondDD) const {
703  // Multiple different declarations got merged together; tell the user
704  // where they came from.
705  if (FirstRecord == SecondRecord)
706  return false;
707 
708  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
709  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
710 
711  const struct CXXRecordDecl::DefinitionData *FirstDD =
712  FirstRecord->DefinitionData;
713  assert(FirstDD && SecondDD && "Definitions without DefinitionData");
714 
715  // Diagnostics from DefinitionData are emitted here.
716  if (FirstDD != SecondDD) {
717  // Keep in sync with err_module_odr_violation_definition_data.
718  enum ODRDefinitionDataDifference {
719  NumBases,
720  NumVBases,
721  BaseType,
722  BaseVirtual,
723  BaseAccess,
724  };
725  auto DiagBaseError = [FirstRecord, &FirstModule,
726  this](SourceLocation Loc, SourceRange Range,
727  ODRDefinitionDataDifference DiffType) {
728  return Diag(Loc, diag::err_module_odr_violation_definition_data)
729  << FirstRecord << FirstModule.empty() << FirstModule << Range
730  << DiffType;
731  };
732  auto DiagBaseNote = [&SecondModule,
733  this](SourceLocation Loc, SourceRange Range,
734  ODRDefinitionDataDifference DiffType) {
735  return Diag(Loc, diag::note_module_odr_violation_definition_data)
736  << SecondModule << Range << DiffType;
737  };
738  auto GetSourceRange = [](const struct CXXRecordDecl::DefinitionData *DD) {
739  unsigned NumBases = DD->NumBases;
740  if (NumBases == 0)
741  return SourceRange();
742  ArrayRef<CXXBaseSpecifier> bases = DD->bases();
743  return SourceRange(bases[0].getBeginLoc(),
744  bases[NumBases - 1].getEndLoc());
745  };
746 
747  unsigned FirstNumBases = FirstDD->NumBases;
748  unsigned FirstNumVBases = FirstDD->NumVBases;
749  unsigned SecondNumBases = SecondDD->NumBases;
750  unsigned SecondNumVBases = SecondDD->NumVBases;
751  if (FirstNumBases != SecondNumBases) {
752  DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
753  NumBases)
754  << FirstNumBases;
755  DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
756  NumBases)
757  << SecondNumBases;
758  return true;
759  }
760 
761  if (FirstNumVBases != SecondNumVBases) {
762  DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
763  NumVBases)
764  << FirstNumVBases;
765  DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
766  NumVBases)
767  << SecondNumVBases;
768  return true;
769  }
770 
771  ArrayRef<CXXBaseSpecifier> FirstBases = FirstDD->bases();
772  ArrayRef<CXXBaseSpecifier> SecondBases = SecondDD->bases();
773  for (unsigned I = 0; I < FirstNumBases; ++I) {
774  const CXXBaseSpecifier FirstBase = FirstBases[I];
775  const CXXBaseSpecifier SecondBase = SecondBases[I];
776  if (computeODRHash(FirstBase.getType()) !=
777  computeODRHash(SecondBase.getType())) {
778  DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
779  BaseType)
780  << (I + 1) << FirstBase.getType();
781  DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
782  BaseType)
783  << (I + 1) << SecondBase.getType();
784  return true;
785  }
786 
787  if (FirstBase.isVirtual() != SecondBase.isVirtual()) {
788  DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
789  BaseVirtual)
790  << (I + 1) << FirstBase.isVirtual() << FirstBase.getType();
791  DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
792  BaseVirtual)
793  << (I + 1) << SecondBase.isVirtual() << SecondBase.getType();
794  return true;
795  }
796 
797  if (FirstBase.getAccessSpecifierAsWritten() !=
798  SecondBase.getAccessSpecifierAsWritten()) {
799  DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
800  BaseAccess)
801  << (I + 1) << FirstBase.getType()
802  << (int)FirstBase.getAccessSpecifierAsWritten();
803  DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
804  BaseAccess)
805  << (I + 1) << SecondBase.getType()
806  << (int)SecondBase.getAccessSpecifierAsWritten();
807  return true;
808  }
809  }
810  }
811 
812  const ClassTemplateDecl *FirstTemplate =
813  FirstRecord->getDescribedClassTemplate();
814  const ClassTemplateDecl *SecondTemplate =
815  SecondRecord->getDescribedClassTemplate();
816 
817  assert(!FirstTemplate == !SecondTemplate &&
818  "Both pointers should be null or non-null");
819 
820  if (FirstTemplate && SecondTemplate) {
821  ArrayRef<const NamedDecl *> FirstTemplateParams =
822  FirstTemplate->getTemplateParameters()->asArray();
823  ArrayRef<const NamedDecl *> SecondTemplateParams =
824  SecondTemplate->getTemplateParameters()->asArray();
825  assert(FirstTemplateParams.size() == SecondTemplateParams.size() &&
826  "Number of template parameters should be equal.");
827  for (auto Pair : llvm::zip(FirstTemplateParams, SecondTemplateParams)) {
828  const NamedDecl *FirstDecl = std::get<0>(Pair);
829  const NamedDecl *SecondDecl = std::get<1>(Pair);
830  if (computeODRHash(FirstDecl) == computeODRHash(SecondDecl))
831  continue;
832 
833  assert(FirstDecl->getKind() == SecondDecl->getKind() &&
834  "Parameter Decl's should be the same kind.");
835 
836  enum ODRTemplateDifference {
837  ParamEmptyName,
838  ParamName,
839  ParamSingleDefaultArgument,
840  ParamDifferentDefaultArgument,
841  };
842 
843  auto hasDefaultArg = [](const NamedDecl *D) {
844  if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
845  return TTP->hasDefaultArgument() &&
846  !TTP->defaultArgumentWasInherited();
847  if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
848  return NTTP->hasDefaultArgument() &&
849  !NTTP->defaultArgumentWasInherited();
850  auto *TTP = cast<TemplateTemplateParmDecl>(D);
851  return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();
852  };
853  bool hasFirstArg = hasDefaultArg(FirstDecl);
854  bool hasSecondArg = hasDefaultArg(SecondDecl);
855 
856  ODRTemplateDifference ErrDiffType;
857  ODRTemplateDifference NoteDiffType;
858 
859  DeclarationName FirstName = FirstDecl->getDeclName();
860  DeclarationName SecondName = SecondDecl->getDeclName();
861 
862  if (FirstName != SecondName) {
863  bool FirstNameEmpty =
864  FirstName.isIdentifier() && !FirstName.getAsIdentifierInfo();
865  bool SecondNameEmpty =
866  SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo();
867  ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;
868  NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;
869  } else if (hasFirstArg == hasSecondArg)
870  ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
871  else
872  ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
873 
874  Diag(FirstDecl->getLocation(),
875  diag::err_module_odr_violation_template_parameter)
876  << FirstRecord << FirstModule.empty() << FirstModule
877  << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg
878  << FirstName;
879  Diag(SecondDecl->getLocation(),
880  diag::note_module_odr_violation_template_parameter)
881  << SecondModule << SecondDecl->getSourceRange() << NoteDiffType
882  << hasSecondArg << SecondName;
883  return true;
884  }
885  }
886 
887  auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,
888  const DeclContext *DC) {
889  for (const Decl *D : Record->decls()) {
891  continue;
892  Hashes.emplace_back(D, computeODRHash(D));
893  }
894  };
895 
896  DeclHashes FirstHashes;
897  DeclHashes SecondHashes;
898  const DeclContext *DC = FirstRecord;
899  PopulateHashes(FirstHashes, FirstRecord, DC);
900  PopulateHashes(SecondHashes, SecondRecord, DC);
901 
902  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
903  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
904  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
905  const Decl *FirstDecl = DR.FirstDecl;
906  const Decl *SecondDecl = DR.SecondDecl;
907 
908  if (FirstDiffType == Other || SecondDiffType == Other) {
909  diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
910  SecondModule);
911  return true;
912  }
913 
914  if (FirstDiffType != SecondDiffType) {
915  diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
916  SecondRecord, SecondModule);
917  return true;
918  }
919 
920  // Used with err_module_odr_violation_record and
921  // note_module_odr_violation_record
922  enum ODRCXXRecordDifference {
923  StaticAssertCondition,
924  StaticAssertMessage,
925  StaticAssertOnlyMessage,
926  MethodName,
927  MethodDeleted,
928  MethodDefaulted,
929  MethodVirtual,
930  MethodStatic,
931  MethodVolatile,
932  MethodConst,
933  MethodInline,
934  MethodParameterSingleDefaultArgument,
935  MethodParameterDifferentDefaultArgument,
936  MethodNoTemplateArguments,
937  MethodDifferentNumberTemplateArguments,
938  MethodDifferentTemplateArgument,
939  MethodSingleBody,
940  MethodDifferentBody,
941  FriendTypeFunction,
942  FriendType,
943  FriendFunction,
944  FunctionTemplateDifferentNumberParameters,
945  FunctionTemplateParameterDifferentKind,
946  FunctionTemplateParameterName,
947  FunctionTemplateParameterSingleDefaultArgument,
948  FunctionTemplateParameterDifferentDefaultArgument,
949  FunctionTemplateParameterDifferentType,
950  FunctionTemplatePackParameter,
951  };
952  auto DiagError = [FirstRecord, &FirstModule,
953  this](SourceLocation Loc, SourceRange Range,
954  ODRCXXRecordDifference DiffType) {
955  return Diag(Loc, diag::err_module_odr_violation_record)
956  << FirstRecord << FirstModule.empty() << FirstModule << Range
957  << DiffType;
958  };
959  auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
960  ODRCXXRecordDifference DiffType) {
961  return Diag(Loc, diag::note_module_odr_violation_record)
962  << SecondModule << Range << DiffType;
963  };
964 
965  assert(FirstDiffType == SecondDiffType);
966  switch (FirstDiffType) {
967  case Other:
968  case EndOfClass:
969  case PublicSpecifer:
970  case PrivateSpecifer:
971  case ProtectedSpecifer:
972  case ObjCMethod:
973  case ObjCProperty:
974  llvm_unreachable("Invalid diff type");
975 
976  case StaticAssert: {
977  const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
978  const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
979 
980  const Expr *FirstExpr = FirstSA->getAssertExpr();
981  const Expr *SecondExpr = SecondSA->getAssertExpr();
982  unsigned FirstODRHash = computeODRHash(FirstExpr);
983  unsigned SecondODRHash = computeODRHash(SecondExpr);
984  if (FirstODRHash != SecondODRHash) {
985  DiagError(FirstExpr->getBeginLoc(), FirstExpr->getSourceRange(),
986  StaticAssertCondition);
987  DiagNote(SecondExpr->getBeginLoc(), SecondExpr->getSourceRange(),
988  StaticAssertCondition);
989  return true;
990  }
991 
992  const StringLiteral *FirstStr = FirstSA->getMessage();
993  const StringLiteral *SecondStr = SecondSA->getMessage();
994  assert((FirstStr || SecondStr) && "Both messages cannot be empty");
995  if ((FirstStr && !SecondStr) || (!FirstStr && SecondStr)) {
996  SourceLocation FirstLoc, SecondLoc;
997  SourceRange FirstRange, SecondRange;
998  if (FirstStr) {
999  FirstLoc = FirstStr->getBeginLoc();
1000  FirstRange = FirstStr->getSourceRange();
1001  } else {
1002  FirstLoc = FirstSA->getBeginLoc();
1003  FirstRange = FirstSA->getSourceRange();
1004  }
1005  if (SecondStr) {
1006  SecondLoc = SecondStr->getBeginLoc();
1007  SecondRange = SecondStr->getSourceRange();
1008  } else {
1009  SecondLoc = SecondSA->getBeginLoc();
1010  SecondRange = SecondSA->getSourceRange();
1011  }
1012  DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
1013  << (FirstStr == nullptr);
1014  DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
1015  << (SecondStr == nullptr);
1016  return true;
1017  }
1018 
1019  if (FirstStr && SecondStr &&
1020  FirstStr->getString() != SecondStr->getString()) {
1021  DiagError(FirstStr->getBeginLoc(), FirstStr->getSourceRange(),
1022  StaticAssertMessage);
1023  DiagNote(SecondStr->getBeginLoc(), SecondStr->getSourceRange(),
1024  StaticAssertMessage);
1025  return true;
1026  }
1027  break;
1028  }
1029 
1030  case Field: {
1031  if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1032  cast<FieldDecl>(FirstDecl),
1033  cast<FieldDecl>(SecondDecl)))
1034  return true;
1035  break;
1036  }
1037 
1038  case CXXMethod: {
1039  enum {
1040  DiagMethod,
1041  DiagConstructor,
1042  DiagDestructor,
1043  } FirstMethodType,
1044  SecondMethodType;
1045  auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl *D) {
1046  if (isa<CXXConstructorDecl>(D))
1047  return DiagConstructor;
1048  if (isa<CXXDestructorDecl>(D))
1049  return DiagDestructor;
1050  return DiagMethod;
1051  };
1052  const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
1053  const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
1054  FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
1055  SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
1056  DeclarationName FirstName = FirstMethod->getDeclName();
1057  DeclarationName SecondName = SecondMethod->getDeclName();
1058  auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType,
1059  FirstName](ODRCXXRecordDifference DiffType) {
1060  return DiagError(FirstMethod->getLocation(),
1061  FirstMethod->getSourceRange(), DiffType)
1062  << FirstMethodType << FirstName;
1063  };
1064  auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,
1065  SecondName](ODRCXXRecordDifference DiffType) {
1066  return DiagNote(SecondMethod->getLocation(),
1067  SecondMethod->getSourceRange(), DiffType)
1068  << SecondMethodType << SecondName;
1069  };
1070 
1071  if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
1072  DiagMethodError(MethodName);
1073  DiagMethodNote(MethodName);
1074  return true;
1075  }
1076 
1077  const bool FirstDeleted = FirstMethod->isDeletedAsWritten();
1078  const bool SecondDeleted = SecondMethod->isDeletedAsWritten();
1079  if (FirstDeleted != SecondDeleted) {
1080  DiagMethodError(MethodDeleted) << FirstDeleted;
1081  DiagMethodNote(MethodDeleted) << SecondDeleted;
1082  return true;
1083  }
1084 
1085  const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted();
1086  const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted();
1087  if (FirstDefaulted != SecondDefaulted) {
1088  DiagMethodError(MethodDefaulted) << FirstDefaulted;
1089  DiagMethodNote(MethodDefaulted) << SecondDefaulted;
1090  return true;
1091  }
1092 
1093  const bool FirstVirtual = FirstMethod->isVirtualAsWritten();
1094  const bool SecondVirtual = SecondMethod->isVirtualAsWritten();
1095  const bool FirstPure = FirstMethod->isPure();
1096  const bool SecondPure = SecondMethod->isPure();
1097  if ((FirstVirtual || SecondVirtual) &&
1098  (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
1099  DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
1100  DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
1101  return true;
1102  }
1103 
1104  // CXXMethodDecl::isStatic uses the canonical Decl. With Decl merging,
1105  // FirstDecl is the canonical Decl of SecondDecl, so the storage
1106  // class needs to be checked instead.
1107  StorageClass FirstStorage = FirstMethod->getStorageClass();
1108  StorageClass SecondStorage = SecondMethod->getStorageClass();
1109  const bool FirstStatic = FirstStorage == SC_Static;
1110  const bool SecondStatic = SecondStorage == SC_Static;
1111  if (FirstStatic != SecondStatic) {
1112  DiagMethodError(MethodStatic) << FirstStatic;
1113  DiagMethodNote(MethodStatic) << SecondStatic;
1114  return true;
1115  }
1116 
1117  const bool FirstVolatile = FirstMethod->isVolatile();
1118  const bool SecondVolatile = SecondMethod->isVolatile();
1119  if (FirstVolatile != SecondVolatile) {
1120  DiagMethodError(MethodVolatile) << FirstVolatile;
1121  DiagMethodNote(MethodVolatile) << SecondVolatile;
1122  return true;
1123  }
1124 
1125  const bool FirstConst = FirstMethod->isConst();
1126  const bool SecondConst = SecondMethod->isConst();
1127  if (FirstConst != SecondConst) {
1128  DiagMethodError(MethodConst) << FirstConst;
1129  DiagMethodNote(MethodConst) << SecondConst;
1130  return true;
1131  }
1132 
1133  const bool FirstInline = FirstMethod->isInlineSpecified();
1134  const bool SecondInline = SecondMethod->isInlineSpecified();
1135  if (FirstInline != SecondInline) {
1136  DiagMethodError(MethodInline) << FirstInline;
1137  DiagMethodNote(MethodInline) << SecondInline;
1138  return true;
1139  }
1140 
1141  if (diagnoseSubMismatchMethodParameters(Diags, FirstRecord,
1142  FirstModule, SecondModule,
1143  FirstMethod, SecondMethod))
1144  return true;
1145 
1146  for (unsigned I = 0, N = FirstMethod->param_size(); I < N; ++I) {
1147  const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
1148  const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
1149 
1150  const Expr *FirstInit = FirstParam->getInit();
1151  const Expr *SecondInit = SecondParam->getInit();
1152  if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1153  DiagMethodError(MethodParameterSingleDefaultArgument)
1154  << (I + 1) << (FirstInit == nullptr)
1155  << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
1156  DiagMethodNote(MethodParameterSingleDefaultArgument)
1157  << (I + 1) << (SecondInit == nullptr)
1158  << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
1159  return true;
1160  }
1161 
1162  if (FirstInit && SecondInit &&
1163  computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1164  DiagMethodError(MethodParameterDifferentDefaultArgument)
1165  << (I + 1) << FirstInit->getSourceRange();
1166  DiagMethodNote(MethodParameterDifferentDefaultArgument)
1167  << (I + 1) << SecondInit->getSourceRange();
1168  return true;
1169  }
1170  }
1171 
1172  const TemplateArgumentList *FirstTemplateArgs =
1173  FirstMethod->getTemplateSpecializationArgs();
1174  const TemplateArgumentList *SecondTemplateArgs =
1175  SecondMethod->getTemplateSpecializationArgs();
1176 
1177  if ((FirstTemplateArgs && !SecondTemplateArgs) ||
1178  (!FirstTemplateArgs && SecondTemplateArgs)) {
1179  DiagMethodError(MethodNoTemplateArguments)
1180  << (FirstTemplateArgs != nullptr);
1181  DiagMethodNote(MethodNoTemplateArguments)
1182  << (SecondTemplateArgs != nullptr);
1183  return true;
1184  }
1185 
1186  if (FirstTemplateArgs && SecondTemplateArgs) {
1187  // Remove pack expansions from argument list.
1188  auto ExpandTemplateArgumentList = [](const TemplateArgumentList *TAL) {
1190  for (const TemplateArgument &TA : TAL->asArray()) {
1191  if (TA.getKind() != TemplateArgument::Pack) {
1192  ExpandedList.push_back(&TA);
1193  continue;
1194  }
1195  llvm::append_range(ExpandedList,
1196  llvm::make_pointer_range(TA.getPackAsArray()));
1197  }
1198  return ExpandedList;
1199  };
1201  ExpandTemplateArgumentList(FirstTemplateArgs);
1203  ExpandTemplateArgumentList(SecondTemplateArgs);
1204 
1205  if (FirstExpandedList.size() != SecondExpandedList.size()) {
1206  DiagMethodError(MethodDifferentNumberTemplateArguments)
1207  << (unsigned)FirstExpandedList.size();
1208  DiagMethodNote(MethodDifferentNumberTemplateArguments)
1209  << (unsigned)SecondExpandedList.size();
1210  return true;
1211  }
1212 
1213  for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
1214  const TemplateArgument &FirstTA = *FirstExpandedList[i],
1215  &SecondTA = *SecondExpandedList[i];
1216  if (computeODRHash(FirstTA) == computeODRHash(SecondTA))
1217  continue;
1218 
1219  DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;
1220  DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;
1221  return true;
1222  }
1223  }
1224 
1225  // Compute the hash of the method as if it has no body.
1226  auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) {
1227  ODRHash Hasher;
1228  Hasher.AddFunctionDecl(D, true /*SkipBody*/);
1229  return Hasher.CalculateHash();
1230  };
1231 
1232  // Compare the hash generated to the hash stored. A difference means
1233  // that a body was present in the original source. Due to merging,
1234  // the standard way of detecting a body will not work.
1235  const bool HasFirstBody =
1236  ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();
1237  const bool HasSecondBody =
1238  ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash();
1239 
1240  if (HasFirstBody != HasSecondBody) {
1241  DiagMethodError(MethodSingleBody) << HasFirstBody;
1242  DiagMethodNote(MethodSingleBody) << HasSecondBody;
1243  return true;
1244  }
1245 
1246  if (HasFirstBody && HasSecondBody) {
1247  DiagMethodError(MethodDifferentBody);
1248  DiagMethodNote(MethodDifferentBody);
1249  return true;
1250  }
1251 
1252  break;
1253  }
1254 
1255  case TypeAlias:
1256  case TypeDef: {
1257  if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1258  cast<TypedefNameDecl>(FirstDecl),
1259  cast<TypedefNameDecl>(SecondDecl),
1260  FirstDiffType == TypeAlias))
1261  return true;
1262  break;
1263  }
1264  case Var: {
1265  if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1266  cast<VarDecl>(FirstDecl),
1267  cast<VarDecl>(SecondDecl)))
1268  return true;
1269  break;
1270  }
1271  case Friend: {
1272  const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
1273  const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
1274 
1275  const NamedDecl *FirstND = FirstFriend->getFriendDecl();
1276  const NamedDecl *SecondND = SecondFriend->getFriendDecl();
1277 
1278  TypeSourceInfo *FirstTSI = FirstFriend->getFriendType();
1279  TypeSourceInfo *SecondTSI = SecondFriend->getFriendType();
1280 
1281  if (FirstND && SecondND) {
1282  DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1283  FriendFunction)
1284  << FirstND;
1285  DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1286  FriendFunction)
1287  << SecondND;
1288  return true;
1289  }
1290 
1291  if (FirstTSI && SecondTSI) {
1292  QualType FirstFriendType = FirstTSI->getType();
1293  QualType SecondFriendType = SecondTSI->getType();
1294  assert(computeODRHash(FirstFriendType) !=
1295  computeODRHash(SecondFriendType));
1296  DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1297  FriendType)
1298  << FirstFriendType;
1299  DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1300  FriendType)
1301  << SecondFriendType;
1302  return true;
1303  }
1304 
1305  DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1306  FriendTypeFunction)
1307  << (FirstTSI == nullptr);
1308  DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1309  FriendTypeFunction)
1310  << (SecondTSI == nullptr);
1311  return true;
1312  }
1313  case FunctionTemplate: {
1314  const FunctionTemplateDecl *FirstTemplate =
1315  cast<FunctionTemplateDecl>(FirstDecl);
1316  const FunctionTemplateDecl *SecondTemplate =
1317  cast<FunctionTemplateDecl>(SecondDecl);
1318 
1319  TemplateParameterList *FirstTPL = FirstTemplate->getTemplateParameters();
1320  TemplateParameterList *SecondTPL = SecondTemplate->getTemplateParameters();
1321 
1322  auto DiagTemplateError = [&DiagError,
1323  FirstTemplate](ODRCXXRecordDifference DiffType) {
1324  return DiagError(FirstTemplate->getLocation(),
1325  FirstTemplate->getSourceRange(), DiffType)
1326  << FirstTemplate;
1327  };
1328  auto DiagTemplateNote = [&DiagNote,
1329  SecondTemplate](ODRCXXRecordDifference DiffType) {
1330  return DiagNote(SecondTemplate->getLocation(),
1331  SecondTemplate->getSourceRange(), DiffType)
1332  << SecondTemplate;
1333  };
1334 
1335  if (FirstTPL->size() != SecondTPL->size()) {
1336  DiagTemplateError(FunctionTemplateDifferentNumberParameters)
1337  << FirstTPL->size();
1338  DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
1339  << SecondTPL->size();
1340  return true;
1341  }
1342 
1343  for (unsigned i = 0, e = FirstTPL->size(); i != e; ++i) {
1344  NamedDecl *FirstParam = FirstTPL->getParam(i);
1345  NamedDecl *SecondParam = SecondTPL->getParam(i);
1346 
1347  if (FirstParam->getKind() != SecondParam->getKind()) {
1348  enum {
1349  TemplateTypeParameter,
1350  NonTypeTemplateParameter,
1351  TemplateTemplateParameter,
1352  };
1353  auto GetParamType = [](NamedDecl *D) {
1354  switch (D->getKind()) {
1355  default:
1356  llvm_unreachable("Unexpected template parameter type");
1357  case Decl::TemplateTypeParm:
1358  return TemplateTypeParameter;
1359  case Decl::NonTypeTemplateParm:
1360  return NonTypeTemplateParameter;
1361  case Decl::TemplateTemplateParm:
1362  return TemplateTemplateParameter;
1363  }
1364  };
1365 
1366  DiagTemplateError(FunctionTemplateParameterDifferentKind)
1367  << (i + 1) << GetParamType(FirstParam);
1368  DiagTemplateNote(FunctionTemplateParameterDifferentKind)
1369  << (i + 1) << GetParamType(SecondParam);
1370  return true;
1371  }
1372 
1373  if (FirstParam->getName() != SecondParam->getName()) {
1374  DiagTemplateError(FunctionTemplateParameterName)
1375  << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam;
1376  DiagTemplateNote(FunctionTemplateParameterName)
1377  << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam;
1378  return true;
1379  }
1380 
1381  if (isa<TemplateTypeParmDecl>(FirstParam) &&
1382  isa<TemplateTypeParmDecl>(SecondParam)) {
1383  TemplateTypeParmDecl *FirstTTPD =
1384  cast<TemplateTypeParmDecl>(FirstParam);
1385  TemplateTypeParmDecl *SecondTTPD =
1386  cast<TemplateTypeParmDecl>(SecondParam);
1387  bool HasFirstDefaultArgument =
1388  FirstTTPD->hasDefaultArgument() &&
1389  !FirstTTPD->defaultArgumentWasInherited();
1390  bool HasSecondDefaultArgument =
1391  SecondTTPD->hasDefaultArgument() &&
1392  !SecondTTPD->defaultArgumentWasInherited();
1393  if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1394  DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1395  << (i + 1) << HasFirstDefaultArgument;
1396  DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1397  << (i + 1) << HasSecondDefaultArgument;
1398  return true;
1399  }
1400 
1401  if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1402  QualType FirstType = FirstTTPD->getDefaultArgument();
1403  QualType SecondType = SecondTTPD->getDefaultArgument();
1404  if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
1405  DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1406  << (i + 1) << FirstType;
1407  DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1408  << (i + 1) << SecondType;
1409  return true;
1410  }
1411  }
1412 
1413  if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1414  DiagTemplateError(FunctionTemplatePackParameter)
1415  << (i + 1) << FirstTTPD->isParameterPack();
1416  DiagTemplateNote(FunctionTemplatePackParameter)
1417  << (i + 1) << SecondTTPD->isParameterPack();
1418  return true;
1419  }
1420  }
1421 
1422  if (isa<TemplateTemplateParmDecl>(FirstParam) &&
1423  isa<TemplateTemplateParmDecl>(SecondParam)) {
1424  TemplateTemplateParmDecl *FirstTTPD =
1425  cast<TemplateTemplateParmDecl>(FirstParam);
1426  TemplateTemplateParmDecl *SecondTTPD =
1427  cast<TemplateTemplateParmDecl>(SecondParam);
1428 
1429  TemplateParameterList *FirstTPL = FirstTTPD->getTemplateParameters();
1430  TemplateParameterList *SecondTPL = SecondTTPD->getTemplateParameters();
1431 
1432  auto ComputeTemplateParameterListODRHash =
1433  [](const TemplateParameterList *TPL) {
1434  assert(TPL);
1435  ODRHash Hasher;
1436  Hasher.AddTemplateParameterList(TPL);
1437  return Hasher.CalculateHash();
1438  };
1439 
1440  if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1441  ComputeTemplateParameterListODRHash(SecondTPL)) {
1442  DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1443  DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1444  return true;
1445  }
1446 
1447  bool HasFirstDefaultArgument =
1448  FirstTTPD->hasDefaultArgument() &&
1449  !FirstTTPD->defaultArgumentWasInherited();
1450  bool HasSecondDefaultArgument =
1451  SecondTTPD->hasDefaultArgument() &&
1452  !SecondTTPD->defaultArgumentWasInherited();
1453  if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1454  DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1455  << (i + 1) << HasFirstDefaultArgument;
1456  DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1457  << (i + 1) << HasSecondDefaultArgument;
1458  return true;
1459  }
1460 
1461  if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1462  TemplateArgument FirstTA =
1463  FirstTTPD->getDefaultArgument().getArgument();
1464  TemplateArgument SecondTA =
1465  SecondTTPD->getDefaultArgument().getArgument();
1466  if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {
1467  DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1468  << (i + 1) << FirstTA;
1469  DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1470  << (i + 1) << SecondTA;
1471  return true;
1472  }
1473  }
1474 
1475  if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1476  DiagTemplateError(FunctionTemplatePackParameter)
1477  << (i + 1) << FirstTTPD->isParameterPack();
1478  DiagTemplateNote(FunctionTemplatePackParameter)
1479  << (i + 1) << SecondTTPD->isParameterPack();
1480  return true;
1481  }
1482  }
1483 
1484  if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
1485  isa<NonTypeTemplateParmDecl>(SecondParam)) {
1486  NonTypeTemplateParmDecl *FirstNTTPD =
1487  cast<NonTypeTemplateParmDecl>(FirstParam);
1488  NonTypeTemplateParmDecl *SecondNTTPD =
1489  cast<NonTypeTemplateParmDecl>(SecondParam);
1490 
1491  QualType FirstType = FirstNTTPD->getType();
1492  QualType SecondType = SecondNTTPD->getType();
1493  if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
1494  DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1495  DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1496  return true;
1497  }
1498 
1499  bool HasFirstDefaultArgument =
1500  FirstNTTPD->hasDefaultArgument() &&
1501  !FirstNTTPD->defaultArgumentWasInherited();
1502  bool HasSecondDefaultArgument =
1503  SecondNTTPD->hasDefaultArgument() &&
1504  !SecondNTTPD->defaultArgumentWasInherited();
1505  if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1506  DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1507  << (i + 1) << HasFirstDefaultArgument;
1508  DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1509  << (i + 1) << HasSecondDefaultArgument;
1510  return true;
1511  }
1512 
1513  if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1514  Expr *FirstDefaultArgument = FirstNTTPD->getDefaultArgument();
1515  Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument();
1516  if (computeODRHash(FirstDefaultArgument) !=
1517  computeODRHash(SecondDefaultArgument)) {
1518  DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1519  << (i + 1) << FirstDefaultArgument;
1520  DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1521  << (i + 1) << SecondDefaultArgument;
1522  return true;
1523  }
1524  }
1525 
1526  if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) {
1527  DiagTemplateError(FunctionTemplatePackParameter)
1528  << (i + 1) << FirstNTTPD->isParameterPack();
1529  DiagTemplateNote(FunctionTemplatePackParameter)
1530  << (i + 1) << SecondNTTPD->isParameterPack();
1531  return true;
1532  }
1533  }
1534  }
1535  break;
1536  }
1537  }
1538 
1539  Diag(FirstDecl->getLocation(),
1540  diag::err_module_odr_violation_mismatch_decl_unknown)
1541  << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1542  << FirstDecl->getSourceRange();
1543  Diag(SecondDecl->getLocation(),
1544  diag::note_module_odr_violation_mismatch_decl_unknown)
1545  << SecondModule.empty() << SecondModule << FirstDiffType
1546  << SecondDecl->getSourceRange();
1547  return true;
1548 }
1549 
1551  const FunctionDecl *FirstFunction,
1552  const FunctionDecl *SecondFunction) const {
1553  if (FirstFunction == SecondFunction)
1554  return false;
1555 
1556  // Keep in sync with select options in err_module_odr_violation_function.
1557  enum ODRFunctionDifference {
1558  ReturnType,
1559  ParameterName,
1560  ParameterType,
1561  ParameterSingleDefaultArgument,
1562  ParameterDifferentDefaultArgument,
1563  FunctionBody,
1564  };
1565 
1566  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);
1567  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondFunction);
1568 
1569  auto DiagError = [FirstFunction, &FirstModule,
1570  this](SourceLocation Loc, SourceRange Range,
1571  ODRFunctionDifference DiffType) {
1572  return Diag(Loc, diag::err_module_odr_violation_function)
1573  << FirstFunction << FirstModule.empty() << FirstModule << Range
1574  << DiffType;
1575  };
1576  auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1577  ODRFunctionDifference DiffType) {
1578  return Diag(Loc, diag::note_module_odr_violation_function)
1579  << SecondModule << Range << DiffType;
1580  };
1581 
1582  if (computeODRHash(FirstFunction->getReturnType()) !=
1583  computeODRHash(SecondFunction->getReturnType())) {
1584  DiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),
1585  FirstFunction->getReturnTypeSourceRange(), ReturnType)
1586  << FirstFunction->getReturnType();
1587  DiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),
1588  SecondFunction->getReturnTypeSourceRange(), ReturnType)
1589  << SecondFunction->getReturnType();
1590  return true;
1591  }
1592 
1593  assert(FirstFunction->param_size() == SecondFunction->param_size() &&
1594  "Merged functions with different number of parameters");
1595 
1596  size_t ParamSize = FirstFunction->param_size();
1597  for (unsigned I = 0; I < ParamSize; ++I) {
1598  const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I);
1599  const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I);
1600 
1601  assert(Context.hasSameType(FirstParam->getType(), SecondParam->getType()) &&
1602  "Merged function has different parameter types.");
1603 
1604  if (FirstParam->getDeclName() != SecondParam->getDeclName()) {
1605  DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1606  ParameterName)
1607  << I + 1 << FirstParam->getDeclName();
1608  DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1609  ParameterName)
1610  << I + 1 << SecondParam->getDeclName();
1611  return true;
1612  };
1613 
1614  QualType FirstParamType = FirstParam->getType();
1615  QualType SecondParamType = SecondParam->getType();
1616  if (FirstParamType != SecondParamType &&
1617  computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) {
1618  if (const DecayedType *ParamDecayedType =
1619  FirstParamType->getAs<DecayedType>()) {
1620  DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1621  ParameterType)
1622  << (I + 1) << FirstParamType << true
1623  << ParamDecayedType->getOriginalType();
1624  } else {
1625  DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1626  ParameterType)
1627  << (I + 1) << FirstParamType << false;
1628  }
1629 
1630  if (const DecayedType *ParamDecayedType =
1631  SecondParamType->getAs<DecayedType>()) {
1632  DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1633  ParameterType)
1634  << (I + 1) << SecondParamType << true
1635  << ParamDecayedType->getOriginalType();
1636  } else {
1637  DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1638  ParameterType)
1639  << (I + 1) << SecondParamType << false;
1640  }
1641  return true;
1642  }
1643 
1644  const Expr *FirstInit = FirstParam->getInit();
1645  const Expr *SecondInit = SecondParam->getInit();
1646  if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1647  DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1648  ParameterSingleDefaultArgument)
1649  << (I + 1) << (FirstInit == nullptr)
1650  << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
1651  DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1652  ParameterSingleDefaultArgument)
1653  << (I + 1) << (SecondInit == nullptr)
1654  << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
1655  return true;
1656  }
1657 
1658  if (FirstInit && SecondInit &&
1659  computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1660  DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1661  ParameterDifferentDefaultArgument)
1662  << (I + 1) << FirstInit->getSourceRange();
1663  DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1664  ParameterDifferentDefaultArgument)
1665  << (I + 1) << SecondInit->getSourceRange();
1666  return true;
1667  }
1668 
1669  assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) &&
1670  "Undiagnosed parameter difference.");
1671  }
1672 
1673  // If no error has been generated before now, assume the problem is in
1674  // the body and generate a message.
1675  DiagError(FirstFunction->getLocation(), FirstFunction->getSourceRange(),
1676  FunctionBody);
1677  DiagNote(SecondFunction->getLocation(), SecondFunction->getSourceRange(),
1678  FunctionBody);
1679  return true;
1680 }
1681 
1683  const EnumDecl *SecondEnum) const {
1684  if (FirstEnum == SecondEnum)
1685  return false;
1686 
1687  // Keep in sync with select options in err_module_odr_violation_enum.
1688  enum ODREnumDifference {
1689  SingleScopedEnum,
1690  EnumTagKeywordMismatch,
1691  SingleSpecifiedType,
1692  DifferentSpecifiedTypes,
1693  DifferentNumberEnumConstants,
1694  EnumConstantName,
1695  EnumConstantSingleInitializer,
1696  EnumConstantDifferentInitializer,
1697  };
1698 
1699  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum);
1700  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondEnum);
1701 
1702  auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor,
1703  ODREnumDifference DiffType) {
1704  return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1705  << FirstEnum << FirstModule.empty() << FirstModule
1706  << DiagAnchor->getSourceRange() << DiffType;
1707  };
1708  auto DiagNote = [&SecondModule, this](const auto *DiagAnchor,
1709  ODREnumDifference DiffType) {
1710  return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1711  << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1712  };
1713 
1714  if (FirstEnum->isScoped() != SecondEnum->isScoped()) {
1715  DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();
1716  DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();
1717  return true;
1718  }
1719 
1720  if (FirstEnum->isScoped() && SecondEnum->isScoped()) {
1721  if (FirstEnum->isScopedUsingClassTag() !=
1722  SecondEnum->isScopedUsingClassTag()) {
1723  DiagError(FirstEnum, EnumTagKeywordMismatch)
1724  << FirstEnum->isScopedUsingClassTag();
1725  DiagNote(SecondEnum, EnumTagKeywordMismatch)
1726  << SecondEnum->isScopedUsingClassTag();
1727  return true;
1728  }
1729  }
1730 
1731  QualType FirstUnderlyingType =
1732  FirstEnum->getIntegerTypeSourceInfo()
1733  ? FirstEnum->getIntegerTypeSourceInfo()->getType()
1734  : QualType();
1735  QualType SecondUnderlyingType =
1736  SecondEnum->getIntegerTypeSourceInfo()
1737  ? SecondEnum->getIntegerTypeSourceInfo()->getType()
1738  : QualType();
1739  if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {
1740  DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull();
1741  DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull();
1742  return true;
1743  }
1744 
1745  if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {
1746  if (computeODRHash(FirstUnderlyingType) !=
1747  computeODRHash(SecondUnderlyingType)) {
1748  DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1749  DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1750  return true;
1751  }
1752  }
1753 
1754  // Compare enum constants.
1755  using DeclHashes =
1757  auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, const EnumDecl *Enum) {
1758  for (const Decl *D : Enum->decls()) {
1759  // Due to decl merging, the first EnumDecl is the parent of
1760  // Decls in both records.
1761  if (!ODRHash::isSubDeclToBeProcessed(D, FirstEnum))
1762  continue;
1763  assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");
1764  Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D));
1765  }
1766  };
1767  DeclHashes FirstHashes;
1768  PopulateHashes(FirstHashes, FirstEnum);
1769  DeclHashes SecondHashes;
1770  PopulateHashes(SecondHashes, SecondEnum);
1771 
1772  if (FirstHashes.size() != SecondHashes.size()) {
1773  DiagError(FirstEnum, DifferentNumberEnumConstants)
1774  << (int)FirstHashes.size();
1775  DiagNote(SecondEnum, DifferentNumberEnumConstants)
1776  << (int)SecondHashes.size();
1777  return true;
1778  }
1779 
1780  for (unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {
1781  if (FirstHashes[I].second == SecondHashes[I].second)
1782  continue;
1783  const EnumConstantDecl *FirstConstant = FirstHashes[I].first;
1784  const EnumConstantDecl *SecondConstant = SecondHashes[I].first;
1785 
1786  if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) {
1787  DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1788  DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1789  return true;
1790  }
1791 
1792  const Expr *FirstInit = FirstConstant->getInitExpr();
1793  const Expr *SecondInit = SecondConstant->getInitExpr();
1794  if (!FirstInit && !SecondInit)
1795  continue;
1796 
1797  if (!FirstInit || !SecondInit) {
1798  DiagError(FirstConstant, EnumConstantSingleInitializer)
1799  << I + 1 << FirstConstant << (FirstInit != nullptr);
1800  DiagNote(SecondConstant, EnumConstantSingleInitializer)
1801  << I + 1 << SecondConstant << (SecondInit != nullptr);
1802  return true;
1803  }
1804 
1805  if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1806  DiagError(FirstConstant, EnumConstantDifferentInitializer)
1807  << I + 1 << FirstConstant;
1808  DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1809  << I + 1 << SecondConstant;
1810  return true;
1811  }
1812  }
1813  return false;
1814 }
1815 
1817  const ObjCProtocolDecl *FirstProtocol,
1818  const ObjCProtocolDecl *SecondProtocol,
1819  const struct ObjCProtocolDecl::DefinitionData *SecondDD) const {
1820  if (FirstProtocol == SecondProtocol)
1821  return false;
1822 
1823  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstProtocol);
1824  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondProtocol);
1825 
1826  const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
1827  assert(FirstDD && SecondDD && "Definitions without DefinitionData");
1828  // Diagnostics from ObjCProtocol DefinitionData are emitted here.
1829  if (FirstDD != SecondDD) {
1830  // Check both protocols reference the same protocols.
1831  const ObjCProtocolList &FirstProtocols =
1832  FirstProtocol->getReferencedProtocols();
1833  const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols;
1834  if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
1835  SecondProtocols, SecondProtocol,
1836  SecondModule))
1837  return true;
1838  }
1839 
1840  auto PopulateHashes = [](DeclHashes &Hashes, const ObjCProtocolDecl *ID,
1841  const DeclContext *DC) {
1842  for (const Decl *D : ID->decls()) {
1843  if (!ODRHash::isSubDeclToBeProcessed(D, DC))
1844  continue;
1845  Hashes.emplace_back(D, computeODRHash(D));
1846  }
1847  };
1848 
1849  DeclHashes FirstHashes;
1850  DeclHashes SecondHashes;
1851  // Use definition as DeclContext because definitions are merged when
1852  // DeclContexts are merged and separate when DeclContexts are separate.
1853  PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition());
1854  PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition());
1855 
1856  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1857  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1858  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1859  const Decl *FirstDecl = DR.FirstDecl;
1860  const Decl *SecondDecl = DR.SecondDecl;
1861 
1862  if (FirstDiffType == Other || SecondDiffType == Other) {
1863  diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
1864  SecondProtocol, SecondModule);
1865  return true;
1866  }
1867 
1868  if (FirstDiffType != SecondDiffType) {
1869  diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
1870  SecondProtocol, SecondModule);
1871  return true;
1872  }
1873 
1874  assert(FirstDiffType == SecondDiffType);
1875  switch (FirstDiffType) {
1876  // Already handled.
1877  case EndOfClass:
1878  case Other:
1879  // Cannot be contained by ObjCProtocolDecl, invalid in this context.
1880  case Field:
1881  case TypeDef:
1882  case Var:
1883  // C++ only, invalid in this context.
1884  case PublicSpecifer:
1885  case PrivateSpecifer:
1886  case ProtectedSpecifer:
1887  case StaticAssert:
1888  case CXXMethod:
1889  case TypeAlias:
1890  case Friend:
1891  case FunctionTemplate:
1892  llvm_unreachable("Invalid diff type");
1893  case ObjCMethod: {
1894  if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
1895  cast<ObjCMethodDecl>(FirstDecl),
1896  cast<ObjCMethodDecl>(SecondDecl)))
1897  return true;
1898  break;
1899  }
1900  case ObjCProperty: {
1901  if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
1902  SecondModule,
1903  cast<ObjCPropertyDecl>(FirstDecl),
1904  cast<ObjCPropertyDecl>(SecondDecl)))
1905  return true;
1906  break;
1907  }
1908  }
1909 
1910  Diag(FirstDecl->getLocation(),
1911  diag::err_module_odr_violation_mismatch_decl_unknown)
1912  << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
1913  << FirstDecl->getSourceRange();
1914  Diag(SecondDecl->getLocation(),
1915  diag::note_module_odr_violation_mismatch_decl_unknown)
1916  << SecondModule.empty() << SecondModule << FirstDiffType
1917  << SecondDecl->getSourceRange();
1918  return true;
1919 }
clang::FunctionDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:4131
clang::TypeDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.h:3262
clang::FieldDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:4363
clang::CXXBaseSpecifier::getType
QualType getType() const
Retrieves the type of the base class.
Definition: DeclCXX.h:245
clang::VarDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2115
clang::Decl::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:424
clang::TypeSourceInfo::getType
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6604
clang::TemplateTemplateParmDecl::hasDefaultArgument
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Definition: DeclTemplate.h:1745
clang::TemplateTypeParmDecl::defaultArgumentWasInherited
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
Definition: DeclTemplate.h:1292
clang::EnumDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Overrides to provide correct range when there's an enum-base specifier with forward declarations.
Definition: Decl.cpp:4649
clang::FunctionDecl::getReturnType
QualType getReturnType() const
Definition: Decl.h:2625
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
clang::Decl::getImportedOwningModule
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition: DeclBase.h:778
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1389
clang::StaticAssertDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclCXX.h:3992
clang::TemplateTypeParmDecl::getDefaultArgument
QualType getDefaultArgument() const
Retrieve the default argument, if any.
Definition: DeclTemplate.h:1278
computeODRHash
static unsigned computeODRHash(QualType Ty)
Definition: ODRDiagsEmitter.cpp:18
Diag
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Definition: LiteralSupport.cpp:79
clang::StringLiteral::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.h:1951
llvm::SmallVector
Definition: LLVM.h:38
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:247
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:219
clang::AS_private
@ AS_private
Definition: Specifiers.h:114
clang::EnumDecl::getIntegerTypeSourceInfo
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
Definition: Decl.h:3881
clang::Stmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:324
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::NonTypeTemplateParmDecl
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Definition: DeclTemplate.h:1410
clang::FunctionDecl::getParamDecl
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2594
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2930
clang::DiagnosticsEngine
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
clang::FieldDecl::getInClassInitializer
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
Definition: Decl.h:3077
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1712
int
__device__ int
Definition: __clang_hip_libdevice_declares.h:63
Module.h
clang::EnumConstantDecl::getInitExpr
const Expr * getInitExpr() const
Definition: Decl.h:3164
clang::ODRHash::AddTemplateParameterList
void AddTemplateParameterList(const TemplateParameterList *TPL)
Definition: ODRHash.cpp:193
clang::NonTypeTemplateParmDecl::hasDefaultArgument
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Definition: DeclTemplate.h:1489
clang::DeclarationName::getAsIdentifierInfo
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
Definition: DeclarationName.h:419
clang::CXXBaseSpecifier::getAccessSpecifierAsWritten
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
Definition: DeclCXX.h:238
clang::FunctionDecl::param_size
size_t param_size() const
Definition: Decl.h:2587
clang::DeclarationName
The name of a declaration.
Definition: DeclarationName.h:144
clang::EnumDecl
Represents an enum.
Definition: Decl.h:3705
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1565
clang::ODRDiagsEmitter::getOwningModuleNameForDiagnostic
static std::string getOwningModuleNameForDiagnostic(const Decl *D)
Get the best name we know for the module that owns the given declaration, or an empty string if the d...
Definition: ODRDiagsEmitter.cpp:43
clang::TemplateTypeParmDecl::hasDefaultArgument
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Definition: DeclTemplate.h:1275
clang::TypedefType
Definition: Type.h:4535
clang::AS_none
@ AS_none
Definition: Specifiers.h:115
clang::CXXRecordDecl::getDescribedClassTemplate
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
Definition: DeclCXX.cpp:1839
clang::FunctionTemplateDecl
Declaration of a template function.
Definition: DeclTemplate.h:1006
clang::ODRHash::isSubDeclToBeProcessed
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent)
Definition: ODRHash.cpp:514
clang::NonTypeTemplateParmDecl::defaultArgumentWasInherited
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
Definition: DeclTemplate.h:1499
clang::FriendDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Retrieves the source range for the friend declaration.
Definition: DeclFriend.h:148
clang::Module
Describes a module or submodule.
Definition: Module.h:98
clang::TemplateParameterList::getParam
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:139
DeclTemplate.h
clang::ODRHash::AddQualType
void AddQualType(QualType T)
Definition: ODRHash.cpp:1222
DeclFriend.h
clang::Decl::getKind
Kind getKind() const
Definition: DeclBase.h:435
clang::AS_public
@ AS_public
Definition: Specifiers.h:112
clang::FieldDecl::getBitWidth
Expr * getBitWidth() const
Definition: Decl.h:3019
clang::FunctionDecl::getReturnTypeSourceRange
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
Definition: Decl.cpp:3633
clang::ODRHash::AddFunctionDecl
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
Definition: ODRHash.cpp:592
clang::FriendDecl::getFriendDecl
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition: DeclFriend.h:138
clang::FriendDecl::getFriendLoc
SourceLocation getFriendLoc() const
Retrieves the location of the 'friend' keyword.
Definition: DeclFriend.h:143
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7386
clang::TemplateArgument
Represents a template argument.
Definition: TemplateBase.h:61
clang::ObjCProtocolList
A list of Objective-C protocols, along with the source locations at which they were referenced.
Definition: DeclObjC.h:102
clang::StaticAssertDecl::getMessage
StringLiteral * getMessage()
Definition: DeclCXX.h:3985
diagnoseSubMismatchMethodParameters
static bool diagnoseSubMismatchMethodParameters(DiagnosticsEngine &Diags, const NamedDecl *FirstContainer, StringRef FirstModule, StringRef SecondModule, const MethodT *FirstMethod, const MethodT *SecondMethod)
Definition: ODRDiagsEmitter.cpp:53
clang::TypedefNameDecl::getUnderlyingType
QualType getUnderlyingType() const
Definition: Decl.h:3330
clang::CXXBaseSpecifier::isVirtual
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
Definition: DeclCXX.h:199
clang::NumObjCPropertyAttrsBits
@ NumObjCPropertyAttrsBits
Number of bits fitting all the property attributes.
Definition: DeclObjCCommon.h:50
clang::ODRHash::AddTemplateArgument
void AddTemplateArgument(TemplateArgument TA)
Definition: ODRHash.cpp:161
clang::FriendDecl
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition: DeclFriend.h:53
clang::TemplateTemplateParmDecl
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Definition: DeclTemplate.h:1627
clang::ParmVarDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2854
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:906
clang::TemplateArgumentLoc::getArgument
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:506
clang::CXXBaseSpecifier::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
Definition: DeclCXX.h:189
clang::TemplateParameterList
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:70
clang::StringLiteral
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1776
clang::EnumConstantDecl
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3145
clang::ODRDiagsEmitter::diagnoseMismatch
bool diagnoseMismatch(const FunctionDecl *FirstFunction, const FunctionDecl *SecondFunction) const
Diagnose ODR mismatch between 2 FunctionDecl.
Definition: ODRDiagsEmitter.cpp:1550
clang::EnumDecl::isScopedUsingClassTag
bool isScopedUsingClassTag() const
Returns true if this is a C++11 scoped enumeration.
Definition: Decl.h:3913
clang::TemplateTypeParmDecl
Declaration of a template type parameter.
Definition: DeclTemplate.h:1205
clang::FieldDecl::isMutable
bool isMutable() const
Determines whether this field is mutable (C++ only).
Definition: Decl.h:3005
clang::ODRHash
Definition: ODRHash.h:41
clang::SC_Static
@ SC_Static
Definition: Specifiers.h:240
clang::TemplateDecl::getTemplateParameters
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:427
clang::transformer::EditKind::Range
@ Range
clang::ObjCListBase::size
unsigned size() const
Definition: DeclObjC.h:71
clang::Decl::getSourceRange
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:420
ODRDiagsEmitter.h
clang::StaticAssertDecl::getAssertExpr
Expr * getAssertExpr()
Definition: DeclCXX.h:3982
clang::TemplateTemplateParmDecl::defaultArgumentWasInherited
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
Definition: DeclTemplate.h:1758
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::RISCV::TA
@ TA
Definition: RISCVVIntrinsicUtils.h:98
clang::FieldDecl::isBitField
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:3008
clang::EnumDecl::isScoped
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
Definition: Decl.h:3910
clang::NonTypeTemplateParmDecl::getDefaultArgument
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
Definition: DeclTemplate.h:1492
clang::StaticAssertDecl
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:3959
clang::NamedDecl::getIdentifier
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:268
clang::ClassTemplateDecl
Declaration of a class template.
Definition: DeclTemplate.h:2273
clang::AS_protected
@ AS_protected
Definition: Specifiers.h:113
clang::DeclarationName::isIdentifier
bool isIdentifier() const
Predicate functions for querying what type of name this is.
Definition: DeclarationName.h:384
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:802
llvm::ArrayRef
Definition: LLVM.h:34
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::ObjCPropertyDecl
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:732
clang::ObjCProtocolList::loc_begin
loc_iterator loc_begin() const
Definition: DeclObjC.h:112
GCCTypeClass::Enum
@ Enum
clang::TemplateArgumentList
A template argument list.
Definition: DeclTemplate.h:238
clang::TemplateParameterList::size
unsigned size() const
Definition: DeclTemplate.h:130
clang::VarDecl::getInit
const Expr * getInit() const
Definition: Decl.h:1315
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:85
clang::TemplateParameterList::asArray
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:132
ODRHash.h
clang::TemplateTypeParmDecl::isParameterPack
bool isParameterPack() const
Returns whether this is a parameter pack.
Definition: DeclTemplate.cpp:699
clang::ObjCMethodDecl
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
clang::ODRHash::AddStmt
void AddStmt(const Stmt *S)
Definition: ODRHash.cpp:24
clang::IdentifierInfo::getName
StringRef getName() const
Return the actual identifier string.
Definition: IdentifierTable.h:196
clang::Builtin::ID
ID
Definition: Builtins.h:52
clang::TemplateTemplateParmDecl::getDefaultArgument
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
Definition: DeclTemplate.h:1748
clang
Definition: CalledOnceCheck.h:17
clang::NonTypeTemplateParmDecl::isParameterPack
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
Definition: DeclTemplate.h:1524
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:71
clang::VarDecl::isConstexpr
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1509
clang::TemplateDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:452
clang::ObjCProtocolDecl
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2050
clang::CXXBaseSpecifier
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
clang::TypeSourceInfo
A container of type source information.
Definition: Type.h:6593
clang::NamedDecl::getDeclName
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
unsigned
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
clang::TypedefNameDecl
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3275
clang::ObjCContainerDecl
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:944
clang::ODRHash::AddSubDecl
void AddSubDecl(const Decl *D)
Definition: ODRHash.cpp:539
DiagnosticAST.h
clang::ASTContext::hasSameType
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2544
clang::ODRHash::CalculateHash
unsigned CalculateHash()
Definition: ODRHash.cpp:208
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:712
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::ObjCProtocolDecl::getReferencedProtocols
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2118
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:432
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1904
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3983
clang::StringLiteral::getString
StringRef getString() const
Definition: Expr.h:1859
clang::DecayedType
Represents a pointer type decayed from an array or function type.
Definition: Type.h:2832
clang::ObjCProtocolDecl::getDefinition
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Definition: DeclObjC.h:2215
clang::FriendDecl::getFriendType
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:123
clang::DiagnosticsEngine::Report
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1537
clang::TemplateTemplateParmDecl::isParameterPack
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
Definition: DeclTemplate.h:1696
clang::TemplateArgument::Pack
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:100
clang::CXXMethodDecl
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1983
clang::StorageClass
StorageClass
Storage classes.
Definition: Specifiers.h:236
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274