46 return M->getFullModuleName();
52template <
typename MethodT>
55 StringRef FirstModule,
56 StringRef SecondModule,
57 const MethodT *FirstMethod,
58 const MethodT *SecondMethod) {
64 auto GetDiagMethodType = [](
const NamedDecl *D) {
65 if (isa<CXXConstructorDecl>(D))
66 return DiagConstructor;
67 if (isa<CXXDestructorDecl>(D))
68 return DiagDestructor;
72 enum ODRMethodParametersDifference {
77 auto DiagError = [&Diags, &GetDiagMethodType, FirstContainer, FirstModule,
78 FirstMethod](ODRMethodParametersDifference DiffType) {
80 DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);
81 return Diags.
Report(FirstMethod->getLocation(),
82 diag::err_module_odr_violation_method_params)
83 << FirstContainer << FirstModule.empty() << FirstModule
87 auto DiagNote = [&Diags, &GetDiagMethodType, SecondModule,
88 SecondMethod](ODRMethodParametersDifference DiffType) {
90 DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);
91 return Diags.
Report(SecondMethod->getLocation(),
92 diag::note_module_odr_violation_method_params)
93 << SecondModule.empty() << SecondModule
94 << SecondMethod->getSourceRange() << DiffType << SecondMethodType
98 const unsigned FirstNumParameters = FirstMethod->param_size();
99 const unsigned SecondNumParameters = SecondMethod->param_size();
100 if (FirstNumParameters != SecondNumParameters) {
101 DiagError(NumberParameters) << FirstNumParameters;
102 DiagNote(NumberParameters) << SecondNumParameters;
106 for (
unsigned I = 0; I < FirstNumParameters; ++I) {
107 const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
108 const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
112 if (FirstParamType != SecondParamType &&
116 DiagError(ParameterType) << (I + 1) << FirstParamType <<
true
117 << ParamDecayedType->getOriginalType();
119 DiagError(ParameterType) << (I + 1) << FirstParamType <<
false;
124 DiagNote(ParameterType) << (I + 1) << SecondParamType <<
true
125 << ParamDecayedType->getOriginalType();
127 DiagNote(ParameterType) << (I + 1) << SecondParamType <<
false;
134 if (FirstParamName != SecondParamName) {
135 DiagError(ParameterName) << (I + 1) << FirstParamName;
136 DiagNote(ParameterName) << (I + 1) << SecondParamName;
144bool ODRDiagsEmitter::diagnoseSubMismatchField(
145 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
147 enum ODRFieldDifference {
151 FieldDifferentWidthBitField,
153 FieldSingleInitializer,
154 FieldDifferentInitializers,
157 auto DiagError = [FirstRecord, FirstField, FirstModule,
158 this](ODRFieldDifference DiffType) {
159 return Diag(FirstField->
getLocation(), diag::err_module_odr_violation_field)
160 << FirstRecord << FirstModule.empty() << FirstModule
163 auto DiagNote = [SecondField, SecondModule,
164 this](ODRFieldDifference DiffType) {
166 diag::note_module_odr_violation_field)
167 << SecondModule.empty() << SecondModule << SecondField->
getSourceRange() << DiffType;
173 DiagError(FieldName) << FirstII;
174 DiagNote(FieldName) << SecondII;
181 DiagError(FieldTypeName) << FirstII << FirstType;
182 DiagNote(FieldTypeName) << SecondII << SecondType;
189 const bool IsFirstBitField = FirstField->
isBitField();
190 const bool IsSecondBitField = SecondField->
isBitField();
191 if (IsFirstBitField != IsSecondBitField) {
192 DiagError(FieldSingleBitField) << FirstII << IsFirstBitField;
193 DiagNote(FieldSingleBitField) << SecondII << IsSecondBitField;
197 if (IsFirstBitField && IsSecondBitField) {
200 if (FirstBitWidthHash != SecondBitWidthHash) {
201 DiagError(FieldDifferentWidthBitField)
203 DiagNote(FieldDifferentWidthBitField)
209 if (!LangOpts.CPlusPlus)
212 const bool IsFirstMutable = FirstField->
isMutable();
213 const bool IsSecondMutable = SecondField->
isMutable();
214 if (IsFirstMutable != IsSecondMutable) {
215 DiagError(FieldSingleMutable) << FirstII << IsFirstMutable;
216 DiagNote(FieldSingleMutable) << SecondII << IsSecondMutable;
222 if ((!FirstInitializer && SecondInitializer) ||
223 (FirstInitializer && !SecondInitializer)) {
224 DiagError(FieldSingleInitializer)
225 << FirstII << (FirstInitializer !=
nullptr);
226 DiagNote(FieldSingleInitializer)
227 << SecondII << (SecondInitializer !=
nullptr);
231 if (FirstInitializer && SecondInitializer) {
234 if (FirstInitHash != SecondInitHash) {
235 DiagError(FieldDifferentInitializers)
237 DiagNote(FieldDifferentInitializers)
246bool ODRDiagsEmitter::diagnoseSubMismatchTypedef(
247 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
249 bool IsTypeAlias)
const {
250 enum ODRTypedefDifference {
255 auto DiagError = [FirstRecord, FirstTD, FirstModule,
256 this](ODRTypedefDifference DiffType) {
257 return Diag(FirstTD->
getLocation(), diag::err_module_odr_violation_typedef)
258 << FirstRecord << FirstModule.empty() << FirstModule
261 auto DiagNote = [SecondTD, SecondModule,
262 this](ODRTypedefDifference DiffType) {
264 diag::note_module_odr_violation_typedef)
270 if (FirstName != SecondName) {
271 DiagError(TypedefName) << IsTypeAlias << FirstName;
272 DiagNote(TypedefName) << IsTypeAlias << SecondName;
279 DiagError(
TypedefType) << IsTypeAlias << FirstName << FirstType;
280 DiagNote(
TypedefType) << IsTypeAlias << SecondName << SecondType;
286bool ODRDiagsEmitter::diagnoseSubMismatchVar(
const NamedDecl *FirstRecord,
287 StringRef FirstModule,
288 StringRef SecondModule,
290 const VarDecl *SecondVD)
const {
291 enum ODRVarDifference {
294 VarSingleInitializer,
295 VarDifferentInitializer,
299 auto DiagError = [FirstRecord, FirstVD, FirstModule,
300 this](ODRVarDifference DiffType) {
301 return Diag(FirstVD->
getLocation(), diag::err_module_odr_violation_variable)
302 << FirstRecord << FirstModule.empty() << FirstModule
305 auto DiagNote = [SecondVD, SecondModule,
this](ODRVarDifference DiffType) {
307 diag::note_module_odr_violation_variable)
313 if (FirstName != SecondName) {
314 DiagError(VarName) << FirstName;
315 DiagNote(VarName) << SecondName;
322 DiagError(VarType) << FirstName << FirstType;
323 DiagNote(VarType) << SecondName << SecondType;
327 if (!LangOpts.CPlusPlus)
332 if ((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
333 DiagError(VarSingleInitializer)
334 << FirstName << (FirstInit ==
nullptr)
335 << (FirstInit ? FirstInit->getSourceRange() :
SourceRange());
336 DiagNote(VarSingleInitializer)
337 << SecondName << (SecondInit ==
nullptr)
338 << (SecondInit ? SecondInit->getSourceRange() :
SourceRange());
342 if (FirstInit && SecondInit &&
344 DiagError(VarDifferentInitializer)
345 << FirstName << FirstInit->getSourceRange();
346 DiagNote(VarDifferentInitializer)
347 << SecondName << SecondInit->getSourceRange();
351 const bool FirstIsConstexpr = FirstVD->
isConstexpr();
352 const bool SecondIsConstexpr = SecondVD->
isConstexpr();
353 if (FirstIsConstexpr != SecondIsConstexpr) {
354 DiagError(VarConstexpr) << FirstName << FirstIsConstexpr;
355 DiagNote(VarConstexpr) << SecondName << SecondIsConstexpr;
361bool ODRDiagsEmitter::diagnoseSubMismatchProtocols(
367 enum ODRReferencedProtocolDifference {
371 auto DiagRefProtocolError = [FirstContainer, FirstModule,
373 ODRReferencedProtocolDifference DiffType) {
374 return Diag(
Loc, diag::err_module_odr_violation_referenced_protocols)
375 << FirstContainer << FirstModule.empty() << FirstModule <<
Range
378 auto DiagRefProtocolNote = [SecondModule,
380 ODRReferencedProtocolDifference DiffType) {
381 return Diag(
Loc, diag::note_module_odr_violation_referenced_protocols)
382 << SecondModule.empty() << SecondModule <<
Range << DiffType;
387 return SourceRange(*PL.loc_begin(), *std::prev(PL.loc_end()));
390 if (FirstProtocols.
size() != SecondProtocols.
size()) {
391 DiagRefProtocolError(FirstContainer->
getLocation(),
392 GetProtoListSourceRange(FirstProtocols), NumProtocols)
393 << FirstProtocols.
size();
394 DiagRefProtocolNote(SecondContainer->
getLocation(),
395 GetProtoListSourceRange(SecondProtocols), NumProtocols)
396 << SecondProtocols.
size();
400 for (
unsigned I = 0, E = FirstProtocols.
size(); I != E; ++I) {
405 if (FirstProtocolName != SecondProtocolName) {
409 DiagRefProtocolError(FirstLoc, EmptyRange, ProtocolType)
410 << (I + 1) << FirstProtocolName;
411 DiagRefProtocolNote(SecondLoc, EmptyRange, ProtocolType)
412 << (I + 1) << SecondProtocolName;
420bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod(
421 const NamedDecl *FirstObjCContainer, StringRef FirstModule,
424 enum ODRMethodDifference {
428 DesignatedInitializer,
433 auto DiagError = [FirstObjCContainer, FirstModule, FirstMethod,
434 this](ODRMethodDifference DiffType) {
436 diag::err_module_odr_violation_objc_method)
437 << FirstObjCContainer << FirstModule.empty() << FirstModule
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;
450 DiagError(ReturnType) << FirstMethod << FirstMethod->
getReturnType();
451 DiagNote(ReturnType) << SecondMethod << SecondMethod->getReturnType();
456 DiagError(InstanceOrClass)
458 DiagNote(InstanceOrClass)
459 << SecondMethod << SecondMethod->isInstanceMethod();
463 SecondMethod->getImplementationControl()) {
464 DiagError(ControlLevel)
466 DiagNote(ControlLevel) << llvm::to_underlying(
467 SecondMethod->getImplementationControl());
471 SecondMethod->isThisDeclarationADesignatedInitializer()) {
472 DiagError(DesignatedInitializer)
475 DiagNote(DesignatedInitializer)
477 << SecondMethod->isThisDeclarationADesignatedInitializer();
480 if (FirstMethod->
isDirectMethod() != SecondMethod->isDirectMethod()) {
481 DiagError(Directness) << FirstMethod << FirstMethod->
isDirectMethod();
482 DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();
486 FirstModule, SecondModule,
487 FirstMethod, SecondMethod))
495 if (FirstName != SecondName) {
496 DiagError(Name) << FirstName;
497 DiagNote(Name) << SecondName;
504bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
505 const NamedDecl *FirstObjCContainer, StringRef FirstModule,
508 enum ODRPropertyDifference {
515 auto DiagError = [FirstObjCContainer, FirstModule, FirstProp,
517 return Diag(
Loc, diag::err_module_odr_violation_objc_property)
518 << FirstObjCContainer << FirstModule.empty() << FirstModule
521 auto DiagNote = [SecondModule, SecondProp,
523 return Diag(
Loc, diag::note_module_odr_violation_objc_property)
524 << SecondModule.empty() << SecondModule
525 << SecondProp->getSourceRange() << DiffType;
531 DiagError(FirstProp->
getLocation(), Name) << FirstII;
532 DiagNote(SecondProp->getLocation(), Name) << SecondII;
538 << FirstII << FirstProp->
getType();
539 DiagNote(SecondProp->getLocation(),
Type)
540 << SecondII << SecondProp->getType();
544 SecondProp->getPropertyImplementation()) {
547 DiagNote(SecondProp->getLocation(), ControlLevel)
548 << SecondProp->getPropertyImplementation();
554 unsigned SecondAttrs = (
unsigned)SecondProp->getPropertyAttributes();
555 if (FirstAttrs != SecondAttrs) {
557 unsigned CheckedAttr = (1 << I);
558 if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))
561 bool IsFirstWritten =
563 bool IsSecondWritten =
564 (
unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;
568 << FirstII << (I + 1) << IsFirstWritten;
569 DiagNote(IsSecondWritten ? SecondProp->getLParenLoc()
570 : SecondProp->getLocation(),
572 << SecondII << (I + 1);
580ODRDiagsEmitter::DiffResult
581ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,
582 DeclHashes &SecondHashes) {
583 auto DifferenceSelector = [](
const Decl *D) {
584 assert(D &&
"valid Decl required");
585 switch (D->getKind()) {
588 case Decl::AccessSpec:
589 switch (D->getAccess()) {
591 return PublicSpecifer;
593 return PrivateSpecifer;
595 return ProtectedSpecifer;
599 llvm_unreachable(
"Invalid access specifier");
600 case Decl::StaticAssert:
604 case Decl::CXXMethod:
605 case Decl::CXXConstructor:
606 case Decl::CXXDestructor:
608 case Decl::TypeAlias:
616 case Decl::FunctionTemplate:
617 return FunctionTemplate;
618 case Decl::ObjCMethod:
622 case Decl::ObjCProperty:
628 auto FirstIt = FirstHashes.begin();
629 auto SecondIt = SecondHashes.begin();
630 while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
631 if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
632 FirstIt->second == SecondIt->second) {
638 DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
639 DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
642 DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;
644 DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;
650void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(
651 DiffResult &DR,
const NamedDecl *FirstRecord, StringRef FirstModule,
652 const NamedDecl *SecondRecord, StringRef SecondModule)
const {
654 diag::err_module_odr_violation_different_definitions)
655 << FirstRecord << FirstModule.empty() << FirstModule;
658 Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
663 diag::note_module_odr_violation_different_definitions)
667 Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
668 << DR.SecondDecl->getSourceRange();
672void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
673 DiffResult &DR,
const NamedDecl *FirstRecord, StringRef FirstModule,
674 const NamedDecl *SecondRecord, StringRef SecondModule)
const {
675 auto GetMismatchedDeclLoc = [](
const NamedDecl *Container,
676 ODRMismatchDecl DiffType,
const Decl *D) {
679 if (DiffType == EndOfClass) {
680 if (
auto *Tag = dyn_cast<TagDecl>(Container))
681 Loc = Tag->getBraceRange().getEnd();
682 else if (
auto *IF = dyn_cast<ObjCInterfaceDecl>(Container))
683 Loc = IF->getAtEndRange().getBegin();
685 Loc = Container->getEndLoc();
687 Loc = D->getLocation();
688 Range = D->getSourceRange();
694 GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
695 Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
696 << FirstRecord << FirstModule.empty() << FirstModule
697 << FirstDiagInfo.second << DR.FirstDiffType;
699 auto SecondDiagInfo =
700 GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
701 Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
702 << SecondModule.empty() << SecondModule << SecondDiagInfo.second
703 << DR.SecondDiffType;
708 const struct CXXRecordDecl::DefinitionData *SecondDD)
const {
711 if (FirstRecord == SecondRecord)
717 const struct CXXRecordDecl::DefinitionData *FirstDD =
718 FirstRecord->DefinitionData;
719 assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
722 if (FirstDD != SecondDD) {
724 enum ODRDefinitionDataDifference {
731 auto DiagBaseError = [FirstRecord, &FirstModule,
733 ODRDefinitionDataDifference DiffType) {
734 return Diag(
Loc, diag::err_module_odr_violation_definition_data)
735 << FirstRecord << FirstModule.empty() << FirstModule <<
Range
738 auto DiagBaseNote = [&SecondModule,
740 ODRDefinitionDataDifference DiffType) {
741 return Diag(
Loc, diag::note_module_odr_violation_definition_data)
742 << SecondModule <<
Range << DiffType;
744 auto GetSourceRange = [](
const struct CXXRecordDecl::DefinitionData *DD) {
745 unsigned NumBases = DD->NumBases;
750 bases[NumBases - 1].getEndLoc());
753 unsigned FirstNumBases = FirstDD->NumBases;
754 unsigned FirstNumVBases = FirstDD->NumVBases;
755 unsigned SecondNumBases = SecondDD->NumBases;
756 unsigned SecondNumVBases = SecondDD->NumVBases;
757 if (FirstNumBases != SecondNumBases) {
758 DiagBaseError(FirstRecord->
getLocation(), GetSourceRange(FirstDD),
761 DiagBaseNote(SecondRecord->
getLocation(), GetSourceRange(SecondDD),
767 if (FirstNumVBases != SecondNumVBases) {
768 DiagBaseError(FirstRecord->
getLocation(), GetSourceRange(FirstDD),
771 DiagBaseNote(SecondRecord->
getLocation(), GetSourceRange(SecondDD),
779 for (
unsigned I = 0; I < FirstNumBases; ++I) {
786 << (I + 1) << FirstBase.
getType();
789 << (I + 1) << SecondBase.
getType();
807 << (I + 1) << FirstBase.
getType()
811 << (I + 1) << SecondBase.
getType()
823 assert(!FirstTemplate == !SecondTemplate &&
824 "Both pointers should be null or non-null");
826 if (FirstTemplate && SecondTemplate) {
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);
840 "Parameter Decl's should be the same kind.");
842 enum ODRTemplateDifference {
845 ParamSingleDefaultArgument,
846 ParamDifferentDefaultArgument,
849 auto hasDefaultArg = [](
const NamedDecl *D) {
850 if (
auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
851 return TTP->hasDefaultArgument() &&
852 !TTP->defaultArgumentWasInherited();
853 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
854 return NTTP->hasDefaultArgument() &&
855 !NTTP->defaultArgumentWasInherited();
856 auto *TTP = cast<TemplateTemplateParmDecl>(D);
857 return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();
859 bool hasFirstArg = hasDefaultArg(FirstDecl);
860 bool hasSecondArg = hasDefaultArg(SecondDecl);
862 ODRTemplateDifference ErrDiffType;
863 ODRTemplateDifference NoteDiffType;
868 if (FirstName != SecondName) {
869 bool FirstNameEmpty =
871 bool SecondNameEmpty =
873 ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;
874 NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;
875 }
else if (hasFirstArg == hasSecondArg)
876 ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
878 ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
881 diag::err_module_odr_violation_template_parameter)
882 << FirstRecord << FirstModule.empty() << FirstModule
886 diag::note_module_odr_violation_template_parameter)
888 << hasSecondArg << SecondName;
905 PopulateHashes(FirstHashes, FirstRecord, DC);
906 PopulateHashes(SecondHashes, SecondRecord, DC);
908 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
909 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
910 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
911 const Decl *FirstDecl = DR.FirstDecl;
912 const Decl *SecondDecl = DR.SecondDecl;
914 if (FirstDiffType ==
Other || SecondDiffType ==
Other) {
915 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
920 if (FirstDiffType != SecondDiffType) {
921 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
922 SecondRecord, SecondModule);
928 enum ODRCXXRecordDifference {
929 StaticAssertCondition,
931 StaticAssertOnlyMessage,
940 MethodParameterSingleDefaultArgument,
941 MethodParameterDifferentDefaultArgument,
942 MethodNoTemplateArguments,
943 MethodDifferentNumberTemplateArguments,
944 MethodDifferentTemplateArgument,
950 FunctionTemplateDifferentNumberParameters,
951 FunctionTemplateParameterDifferentKind,
952 FunctionTemplateParameterName,
953 FunctionTemplateParameterSingleDefaultArgument,
954 FunctionTemplateParameterDifferentDefaultArgument,
955 FunctionTemplateParameterDifferentType,
956 FunctionTemplatePackParameter,
958 auto DiagError = [FirstRecord, &FirstModule,
960 ODRCXXRecordDifference DiffType) {
961 return Diag(
Loc, diag::err_module_odr_violation_record)
962 << FirstRecord << FirstModule.empty() << FirstModule <<
Range
966 ODRCXXRecordDifference DiffType) {
967 return Diag(
Loc, diag::note_module_odr_violation_record)
968 << SecondModule <<
Range << DiffType;
971 assert(FirstDiffType == SecondDiffType);
972 switch (FirstDiffType) {
976 case PrivateSpecifer:
977 case ProtectedSpecifer:
981 llvm_unreachable(
"Invalid diff type");
991 if (FirstODRHash != SecondODRHash) {
993 StaticAssertCondition);
995 StaticAssertCondition);
1001 assert((FirstMessage || SecondMessage) &&
"Both messages cannot be empty");
1002 if ((FirstMessage && !SecondMessage) || (!FirstMessage && SecondMessage)) {
1012 if (SecondMessage) {
1019 DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
1020 << (FirstMessage ==
nullptr);
1021 DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
1022 << (SecondMessage ==
nullptr);
1026 if (FirstMessage && SecondMessage) {
1029 if (FirstMessageODRHash != SecondMessageODRHash) {
1031 StaticAssertMessage);
1033 StaticAssertMessage);
1041 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1042 cast<FieldDecl>(FirstDecl),
1043 cast<FieldDecl>(SecondDecl)))
1055 auto GetMethodTypeForDiagnostics = [](
const CXXMethodDecl *D) {
1056 if (isa<CXXConstructorDecl>(D))
1057 return DiagConstructor;
1058 if (isa<CXXDestructorDecl>(D))
1059 return DiagDestructor;
1062 const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
1063 const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
1064 FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
1065 SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
1068 auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType,
1069 FirstName](ODRCXXRecordDifference DiffType) {
1072 << FirstMethodType << FirstName;
1074 auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,
1075 SecondName](ODRCXXRecordDifference DiffType) {
1078 << SecondMethodType << SecondName;
1081 if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
1082 DiagMethodError(MethodName);
1083 DiagMethodNote(MethodName);
1089 if (FirstDeleted != SecondDeleted) {
1090 DiagMethodError(MethodDeleted) << FirstDeleted;
1091 DiagMethodNote(MethodDeleted) << SecondDeleted;
1097 if (FirstDefaulted != SecondDefaulted) {
1098 DiagMethodError(MethodDefaulted) << FirstDefaulted;
1099 DiagMethodNote(MethodDefaulted) << SecondDefaulted;
1107 if ((FirstVirtual || SecondVirtual) &&
1108 (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
1109 DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
1110 DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
1119 const bool FirstStatic = FirstStorage ==
SC_Static;
1120 const bool SecondStatic = SecondStorage ==
SC_Static;
1121 if (FirstStatic != SecondStatic) {
1122 DiagMethodError(MethodStatic) << FirstStatic;
1123 DiagMethodNote(MethodStatic) << SecondStatic;
1127 const bool FirstVolatile = FirstMethod->
isVolatile();
1128 const bool SecondVolatile = SecondMethod->
isVolatile();
1129 if (FirstVolatile != SecondVolatile) {
1130 DiagMethodError(MethodVolatile) << FirstVolatile;
1131 DiagMethodNote(MethodVolatile) << SecondVolatile;
1135 const bool FirstConst = FirstMethod->
isConst();
1136 const bool SecondConst = SecondMethod->
isConst();
1137 if (FirstConst != SecondConst) {
1138 DiagMethodError(MethodConst) << FirstConst;
1139 DiagMethodNote(MethodConst) << SecondConst;
1145 if (FirstInline != SecondInline) {
1146 DiagMethodError(MethodInline) << FirstInline;
1147 DiagMethodNote(MethodInline) << SecondInline;
1152 FirstModule, SecondModule,
1153 FirstMethod, SecondMethod))
1156 for (
unsigned I = 0, N = FirstMethod->
param_size(); I < N; ++I) {
1162 if ((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
1163 DiagMethodError(MethodParameterSingleDefaultArgument)
1164 << (I + 1) << (FirstInit ==
nullptr)
1166 DiagMethodNote(MethodParameterSingleDefaultArgument)
1167 << (I + 1) << (SecondInit ==
nullptr)
1172 if (FirstInit && SecondInit &&
1174 DiagMethodError(MethodParameterDifferentDefaultArgument)
1176 DiagMethodNote(MethodParameterDifferentDefaultArgument)
1187 if ((FirstTemplateArgs && !SecondTemplateArgs) ||
1188 (!FirstTemplateArgs && SecondTemplateArgs)) {
1189 DiagMethodError(MethodNoTemplateArguments)
1190 << (FirstTemplateArgs !=
nullptr);
1191 DiagMethodNote(MethodNoTemplateArguments)
1192 << (SecondTemplateArgs !=
nullptr);
1196 if (FirstTemplateArgs && SecondTemplateArgs) {
1202 ExpandedList.push_back(&TA);
1205 llvm::append_range(ExpandedList,
1206 llvm::make_pointer_range(TA.getPackAsArray()));
1208 return ExpandedList;
1211 ExpandTemplateArgumentList(FirstTemplateArgs);
1213 ExpandTemplateArgumentList(SecondTemplateArgs);
1215 if (FirstExpandedList.size() != SecondExpandedList.size()) {
1216 DiagMethodError(MethodDifferentNumberTemplateArguments)
1217 << (
unsigned)FirstExpandedList.size();
1218 DiagMethodNote(MethodDifferentNumberTemplateArguments)
1219 << (
unsigned)SecondExpandedList.size();
1223 for (
unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
1225 &SecondTA = *SecondExpandedList[i];
1229 DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;
1230 DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;
1245 const bool HasFirstBody =
1246 ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->
getODRHash();
1247 const bool HasSecondBody =
1248 ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->
getODRHash();
1250 if (HasFirstBody != HasSecondBody) {
1251 DiagMethodError(MethodSingleBody) << HasFirstBody;
1252 DiagMethodNote(MethodSingleBody) << HasSecondBody;
1256 if (HasFirstBody && HasSecondBody) {
1257 DiagMethodError(MethodDifferentBody);
1258 DiagMethodNote(MethodDifferentBody);
1267 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1268 cast<TypedefNameDecl>(FirstDecl),
1269 cast<TypedefNameDecl>(SecondDecl),
1270 FirstDiffType == TypeAlias))
1275 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1276 cast<VarDecl>(FirstDecl),
1277 cast<VarDecl>(SecondDecl)))
1282 const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
1283 const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
1291 if (FirstND && SecondND) {
1301 if (FirstTSI && SecondTSI) {
1311 << SecondFriendType;
1317 << (FirstTSI ==
nullptr);
1320 << (SecondTSI ==
nullptr);
1323 case FunctionTemplate: {
1325 cast<FunctionTemplateDecl>(FirstDecl);
1327 cast<FunctionTemplateDecl>(SecondDecl);
1332 auto DiagTemplateError = [&DiagError,
1333 FirstTemplate](ODRCXXRecordDifference DiffType) {
1338 auto DiagTemplateNote = [&DiagNote,
1339 SecondTemplate](ODRCXXRecordDifference DiffType) {
1345 if (FirstTPL->
size() != SecondTPL->
size()) {
1346 DiagTemplateError(FunctionTemplateDifferentNumberParameters)
1347 << FirstTPL->
size();
1348 DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
1349 << SecondTPL->
size();
1353 for (
unsigned i = 0, e = FirstTPL->
size(); i != e; ++i) {
1359 TemplateTypeParameter,
1360 NonTypeTemplateParameter,
1361 TemplateTemplateParameter,
1364 switch (D->getKind()) {
1366 llvm_unreachable(
"Unexpected template parameter type");
1367 case Decl::TemplateTypeParm:
1368 return TemplateTypeParameter;
1369 case Decl::NonTypeTemplateParm:
1370 return NonTypeTemplateParameter;
1371 case Decl::TemplateTemplateParm:
1372 return TemplateTemplateParameter;
1376 DiagTemplateError(FunctionTemplateParameterDifferentKind)
1377 << (i + 1) << GetParamType(FirstParam);
1378 DiagTemplateNote(FunctionTemplateParameterDifferentKind)
1379 << (i + 1) << GetParamType(SecondParam);
1384 DiagTemplateError(FunctionTemplateParameterName)
1385 << (i + 1) << (
bool)FirstParam->
getIdentifier() << FirstParam;
1386 DiagTemplateNote(FunctionTemplateParameterName)
1387 << (i + 1) << (
bool)SecondParam->
getIdentifier() << SecondParam;
1391 if (isa<TemplateTypeParmDecl>(FirstParam) &&
1392 isa<TemplateTypeParmDecl>(SecondParam)) {
1394 cast<TemplateTypeParmDecl>(FirstParam);
1396 cast<TemplateTypeParmDecl>(SecondParam);
1397 bool HasFirstDefaultArgument =
1400 bool HasSecondDefaultArgument =
1403 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1404 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1405 << (i + 1) << HasFirstDefaultArgument;
1406 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1407 << (i + 1) << HasSecondDefaultArgument;
1411 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1415 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1416 << (i + 1) << FirstType;
1417 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1418 << (i + 1) << SecondType;
1424 DiagTemplateError(FunctionTemplatePackParameter)
1426 DiagTemplateNote(FunctionTemplatePackParameter)
1432 if (isa<TemplateTemplateParmDecl>(FirstParam) &&
1433 isa<TemplateTemplateParmDecl>(SecondParam)) {
1435 cast<TemplateTemplateParmDecl>(FirstParam);
1437 cast<TemplateTemplateParmDecl>(SecondParam);
1442 auto ComputeTemplateParameterListODRHash =
1450 if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1451 ComputeTemplateParameterListODRHash(SecondTPL)) {
1452 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1453 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1457 bool HasFirstDefaultArgument =
1460 bool HasSecondDefaultArgument =
1463 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1464 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1465 << (i + 1) << HasFirstDefaultArgument;
1466 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1467 << (i + 1) << HasSecondDefaultArgument;
1471 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1477 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1478 << (i + 1) << FirstTA;
1479 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1480 << (i + 1) << SecondTA;
1486 DiagTemplateError(FunctionTemplatePackParameter)
1488 DiagTemplateNote(FunctionTemplatePackParameter)
1494 if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
1495 isa<NonTypeTemplateParmDecl>(SecondParam)) {
1497 cast<NonTypeTemplateParmDecl>(FirstParam);
1499 cast<NonTypeTemplateParmDecl>(SecondParam);
1504 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1505 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1509 bool HasFirstDefaultArgument =
1512 bool HasSecondDefaultArgument =
1515 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1516 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1517 << (i + 1) << HasFirstDefaultArgument;
1518 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1519 << (i + 1) << HasSecondDefaultArgument;
1523 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1528 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1529 << (i + 1) << FirstDefaultArgument;
1530 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1531 << (i + 1) << SecondDefaultArgument;
1537 DiagTemplateError(FunctionTemplatePackParameter)
1539 DiagTemplateNote(FunctionTemplatePackParameter)
1550 diag::err_module_odr_violation_mismatch_decl_unknown)
1551 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1554 diag::note_module_odr_violation_mismatch_decl_unknown)
1555 << SecondModule.empty() << SecondModule << FirstDiffType
1562 if (FirstRecord == SecondRecord)
1580 PopulateHashes(FirstHashes, FirstRecord, DC);
1581 PopulateHashes(SecondHashes, SecondRecord, DC);
1583 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1584 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1585 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1586 const Decl *FirstDecl = DR.FirstDecl;
1587 const Decl *SecondDecl = DR.SecondDecl;
1589 if (FirstDiffType ==
Other || SecondDiffType ==
Other) {
1590 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1595 if (FirstDiffType != SecondDiffType) {
1596 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1597 SecondRecord, SecondModule);
1601 assert(FirstDiffType == SecondDiffType);
1602 switch (FirstDiffType) {
1607 case PublicSpecifer:
1608 case PrivateSpecifer:
1609 case ProtectedSpecifer:
1614 case FunctionTemplate:
1619 llvm_unreachable(
"Invalid diff type");
1622 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1623 cast<FieldDecl>(FirstDecl),
1624 cast<FieldDecl>(SecondDecl)))
1629 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1630 cast<TypedefNameDecl>(FirstDecl),
1631 cast<TypedefNameDecl>(SecondDecl),
1637 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1638 cast<VarDecl>(FirstDecl),
1639 cast<VarDecl>(SecondDecl)))
1646 diag::err_module_odr_violation_mismatch_decl_unknown)
1647 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1650 diag::note_module_odr_violation_mismatch_decl_unknown)
1651 << SecondModule.empty() << SecondModule << FirstDiffType
1659 if (FirstFunction == SecondFunction)
1663 enum ODRFunctionDifference {
1667 ParameterSingleDefaultArgument,
1668 ParameterDifferentDefaultArgument,
1675 auto DiagError = [FirstFunction, &FirstModule,
1677 ODRFunctionDifference DiffType) {
1678 return Diag(
Loc, diag::err_module_odr_violation_function)
1679 << FirstFunction << FirstModule.empty() << FirstModule <<
Range
1683 ODRFunctionDifference DiffType) {
1684 return Diag(
Loc, diag::note_module_odr_violation_function)
1685 << SecondModule <<
Range << DiffType;
1700 "Merged functions with different number of parameters");
1702 size_t ParamSize = FirstFunction->
param_size();
1703 for (
unsigned I = 0; I < ParamSize; ++I) {
1708 "Merged function has different parameter types.");
1722 if (FirstParamType != SecondParamType &&
1728 << (I + 1) << FirstParamType <<
true
1729 << ParamDecayedType->getOriginalType();
1733 << (I + 1) << FirstParamType <<
false;
1740 << (I + 1) << SecondParamType <<
true
1741 << ParamDecayedType->getOriginalType();
1745 << (I + 1) << SecondParamType <<
false;
1753 if ((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
1755 ParameterSingleDefaultArgument)
1756 << (I + 1) << (FirstInit ==
nullptr)
1759 ParameterSingleDefaultArgument)
1760 << (I + 1) << (SecondInit ==
nullptr)
1765 if (FirstInit && SecondInit &&
1768 ParameterDifferentDefaultArgument)
1771 ParameterDifferentDefaultArgument)
1777 "Undiagnosed parameter difference.");
1790 const EnumDecl *SecondEnum)
const {
1791 if (FirstEnum == SecondEnum)
1795 enum ODREnumDifference {
1797 EnumTagKeywordMismatch,
1798 SingleSpecifiedType,
1799 DifferentSpecifiedTypes,
1800 DifferentNumberEnumConstants,
1802 EnumConstantSingleInitializer,
1803 EnumConstantDifferentInitializer,
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
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;
1822 DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->
isScoped();
1823 DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->
isScoped();
1830 DiagError(FirstEnum, EnumTagKeywordMismatch)
1832 DiagNote(SecondEnum, EnumTagKeywordMismatch)
1846 if (FirstUnderlyingType.
isNull() != SecondUnderlyingType.
isNull()) {
1847 DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.
isNull();
1848 DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.
isNull();
1852 if (!FirstUnderlyingType.
isNull() && !SecondUnderlyingType.
isNull()) {
1855 DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1856 DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1865 for (
const Decl *D :
Enum->decls()) {
1870 assert(isa<EnumConstantDecl>(D) &&
"Unexpected Decl kind");
1871 Hashes.emplace_back(cast<EnumConstantDecl>(D),
computeODRHash(D));
1875 PopulateHashes(FirstHashes, FirstEnum);
1877 PopulateHashes(SecondHashes, SecondEnum);
1879 if (FirstHashes.size() != SecondHashes.size()) {
1880 DiagError(FirstEnum, DifferentNumberEnumConstants)
1881 << (
int)FirstHashes.size();
1882 DiagNote(SecondEnum, DifferentNumberEnumConstants)
1883 << (
int)SecondHashes.size();
1887 for (
unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {
1888 if (FirstHashes[I].second == SecondHashes[I].second)
1894 DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1895 DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1901 if (!FirstInit && !SecondInit)
1904 if (!FirstInit || !SecondInit) {
1905 DiagError(FirstConstant, EnumConstantSingleInitializer)
1906 << I + 1 << FirstConstant << (FirstInit !=
nullptr);
1907 DiagNote(SecondConstant, EnumConstantSingleInitializer)
1908 << I + 1 << SecondConstant << (SecondInit !=
nullptr);
1913 DiagError(FirstConstant, EnumConstantDifferentInitializer)
1914 << I + 1 << FirstConstant;
1915 DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1916 << I + 1 << SecondConstant;
1925 const struct ObjCInterfaceDecl::DefinitionData *SecondDD)
const {
1928 if (FirstID == SecondID)
1935 enum ODRInterfaceDifference {
1940 auto DiagError = [FirstID, &FirstModule,
1942 ODRInterfaceDifference DiffType) {
1943 return Diag(
Loc, diag::err_module_odr_violation_objc_interface)
1944 << FirstID << FirstModule.empty() << FirstModule <<
Range
1948 ODRInterfaceDifference DiffType) {
1949 return Diag(
Loc, diag::note_module_odr_violation_objc_interface)
1950 << SecondModule.empty() << SecondModule <<
Range << DiffType;
1953 const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1954 assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
1955 if (FirstDD != SecondDD) {
1957 auto GetSuperClassSourceRange = [](
const TypeSourceInfo *SuperInfo,
1960 return ID->getSourceRange();
1968 const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;
1969 if (SecondSuperInfo)
1973 if ((FirstSuperClass && SecondSuperClass &&
1975 (FirstSuperClass && !SecondSuperClass) ||
1976 (!FirstSuperClass && SecondSuperClass)) {
1979 FirstType = FirstSuperInfo->
getType();
1982 GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1984 << (
bool)FirstSuperInfo << FirstType;
1987 if (SecondSuperInfo)
1988 SecondType = SecondSuperInfo->
getType();
1991 GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1993 << (
bool)SecondSuperInfo << SecondType;
1999 auto &SecondProtos = SecondDD->ReferencedProtocols;
2000 if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
2001 SecondProtos, SecondID, SecondModule))
2007 for (
auto *D :
ID->decls()) {
2018 PopulateHashes(FirstHashes, FirstID, FirstID->
getDefinition());
2019 PopulateHashes(SecondHashes, SecondID, SecondID->
getDefinition());
2021 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2022 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2023 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2024 const Decl *FirstDecl = DR.FirstDecl;
2025 const Decl *SecondDecl = DR.SecondDecl;
2027 if (FirstDiffType ==
Other || SecondDiffType ==
Other) {
2028 diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2033 if (FirstDiffType != SecondDiffType) {
2034 diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2039 assert(FirstDiffType == SecondDiffType);
2040 switch (FirstDiffType) {
2049 case PublicSpecifer:
2050 case PrivateSpecifer:
2051 case ProtectedSpecifer:
2056 case FunctionTemplate:
2057 llvm_unreachable(
"Invalid diff type");
2060 if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2061 cast<ObjCMethodDecl>(FirstDecl),
2062 cast<ObjCMethodDecl>(SecondDecl)))
2067 if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2068 cast<FieldDecl>(FirstDecl),
2069 cast<FieldDecl>(SecondDecl)))
2073 const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl);
2074 const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl);
2089 case ObjCProperty: {
2090 if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2091 cast<ObjCPropertyDecl>(FirstDecl),
2092 cast<ObjCPropertyDecl>(SecondDecl)))
2099 diag::err_module_odr_violation_mismatch_decl_unknown)
2100 << FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2103 diag::note_module_odr_violation_mismatch_decl_unknown)
2104 << SecondModule.empty() << SecondModule << FirstDiffType
2112 const struct ObjCProtocolDecl::DefinitionData *SecondDD)
const {
2113 if (FirstProtocol == SecondProtocol)
2119 const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2120 assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
2122 if (FirstDD != SecondDD) {
2127 if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2128 SecondProtocols, SecondProtocol,
2135 for (
const Decl *D :
ID->decls()) {
2146 PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->
getDefinition());
2147 PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->
getDefinition());
2149 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2150 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2151 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2152 const Decl *FirstDecl = DR.FirstDecl;
2153 const Decl *SecondDecl = DR.SecondDecl;
2155 if (FirstDiffType ==
Other || SecondDiffType ==
Other) {
2156 diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2157 SecondProtocol, SecondModule);
2161 if (FirstDiffType != SecondDiffType) {
2162 diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2163 SecondProtocol, SecondModule);
2167 assert(FirstDiffType == SecondDiffType);
2168 switch (FirstDiffType) {
2178 case PublicSpecifer:
2179 case PrivateSpecifer:
2180 case ProtectedSpecifer:
2185 case FunctionTemplate:
2186 llvm_unreachable(
"Invalid diff type");
2188 if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2189 cast<ObjCMethodDecl>(FirstDecl),
2190 cast<ObjCMethodDecl>(SecondDecl)))
2194 case ObjCProperty: {
2195 if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2197 cast<ObjCPropertyDecl>(FirstDecl),
2198 cast<ObjCPropertyDecl>(SecondDecl)))
2205 diag::err_module_odr_violation_mismatch_decl_unknown)
2206 << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2209 diag::note_module_odr_violation_mismatch_decl_unknown)
2210 << SecondModule.empty() << SecondModule << FirstDiffType
Defines the C++ template declaration subclasses.
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.
llvm::MachO::Record Record
Defines the clang::Module class, which describes a module in the source code.
static unsigned computeODRHash(QualType Ty)
static bool diagnoseSubMismatchMethodParameters(DiagnosticsEngine &Diags, const NamedDecl *FirstContainer, StringRef FirstModule, StringRef SecondModule, const MethodT *FirstMethod, const MethodT *SecondMethod)
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Represents a base class of a C++ class.
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
Declaration of a class template.
Represents a pointer type decayed from an array or function type.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isIdentifier() const
Predicate functions for querying what type of name this is.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
An instance of this object exists for each enum constant that is defined.
const Expr * getInitExpr() const
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
bool isScopedUsingClassTag() const
Returns true if this is a C++11 scoped enumeration.
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
SourceRange getSourceRange() const override LLVM_READONLY
Overrides to provide correct range when there's an enum-base specifier with forward declarations.
This represents one expression.
Represents a member of a struct/union/class.
bool isMutable() const
Determines whether this field is mutable (C++ only).
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
bool isBitField() const
Determines whether this field is a bitfield.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
SourceLocation getFriendLoc() const
Retrieves the location of the 'friend' keyword.
SourceRange getSourceRange() const override LLVM_READONLY
Retrieves the source range for the friend declaration.
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
QualType getReturnType() const
bool isExplicitlyDefaulted() const
Whether this function is explicitly defaulted.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
unsigned getODRHash()
Returns ODRHash of the function.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
bool isDeletedAsWritten() const
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isVirtualAsWritten() const
Whether this function is marked as virtual explicitly.
size_t param_size() const
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Declaration of a template function.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Describes a module or submodule.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
bool diagnoseMismatch(const FunctionDecl *FirstFunction, const FunctionDecl *SecondFunction) const
Diagnose ODR mismatch between 2 FunctionDecl.
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...
void AddStmt(const Stmt *S)
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
void AddSubDecl(const Decl *D)
void AddQualType(QualType T)
void AddTemplateParameterList(const TemplateParameterList *TPL)
void AddTemplateArgument(TemplateArgument TA)
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent)
ObjCContainerDecl - Represents a container for method declarations.
Represents an ObjC class declaration.
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
const ObjCProtocolList & getReferencedProtocols() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
TypeSourceInfo * getSuperClassTInfo() const
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getCanonicalAccessControl() const
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isInstanceMethod() const
bool isThisDeclarationADesignatedInitializer() const
Returns true if this specific method declaration is marked with the designated initializer attribute.
QualType getReturnType() const
ObjCImplementationControl getImplementationControl() const
Represents a class type in Objective C.
Represents one property declaration in an Objective-C interface.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getLParenLoc() const
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
PropertyControl getPropertyImplementation() const
Represents an Objective-C protocol declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
A list of Objective-C protocols, along with the source locations at which they were referenced.
loc_iterator loc_begin() const
Represents a parameter to a function.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Represents a struct/union/class.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Represents a C++11 static_assert declaration.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
A template argument list.
const TemplateArgument & getArgument() const
Represents a template argument.
@ Pack
The template argument is actually a parameter pack.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
ArrayRef< NamedDecl * > asArray()
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
QualType getDefaultArgument() const
Retrieve the default argument, if any.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Returns whether this is a parameter pack.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Base wrapper for a particular "section" of type source info.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
const T * castAs() const
Member-template castAs<specific type>.
const T * getAs() const
Member-template getAs<specific type>'.
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
const Expr * getInit() const
The JSON file list parser is used to communicate input to InstallAPI.
StorageClass
Storage classes.
@ NumObjCPropertyAttrsBits
Number of bits fitting all the property attributes.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.