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()) {
465 DiagNote(ControlLevel) << SecondMethod->getImplementationControl();
469 SecondMethod->isThisDeclarationADesignatedInitializer()) {
470 DiagError(DesignatedInitializer)
473 DiagNote(DesignatedInitializer)
475 << SecondMethod->isThisDeclarationADesignatedInitializer();
478 if (FirstMethod->
isDirectMethod() != SecondMethod->isDirectMethod()) {
479 DiagError(Directness) << FirstMethod << FirstMethod->
isDirectMethod();
480 DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();
484 FirstModule, SecondModule,
485 FirstMethod, SecondMethod))
493 if (FirstName != SecondName) {
494 DiagError(Name) << FirstName;
495 DiagNote(Name) << SecondName;
502bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
503 const NamedDecl *FirstObjCContainer, StringRef FirstModule,
506 enum ODRPropertyDifference {
513 auto DiagError = [FirstObjCContainer, FirstModule, FirstProp,
515 return Diag(Loc, diag::err_module_odr_violation_objc_property)
516 << FirstObjCContainer << FirstModule.empty() << FirstModule
519 auto DiagNote = [SecondModule, SecondProp,
521 return Diag(Loc, diag::note_module_odr_violation_objc_property)
522 << SecondModule.empty() << SecondModule
523 << SecondProp->getSourceRange() << DiffType;
529 DiagError(FirstProp->
getLocation(), Name) << FirstII;
530 DiagNote(SecondProp->getLocation(), Name) << SecondII;
536 << FirstII << FirstProp->
getType();
537 DiagNote(SecondProp->getLocation(),
Type)
538 << SecondII << SecondProp->getType();
542 SecondProp->getPropertyImplementation()) {
545 DiagNote(SecondProp->getLocation(), ControlLevel)
546 << SecondProp->getPropertyImplementation();
552 unsigned SecondAttrs = (
unsigned)SecondProp->getPropertyAttributes();
553 if (FirstAttrs != SecondAttrs) {
555 unsigned CheckedAttr = (1 << I);
556 if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))
559 bool IsFirstWritten =
561 bool IsSecondWritten =
562 (
unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;
566 << FirstII << (I + 1) << IsFirstWritten;
567 DiagNote(IsSecondWritten ? SecondProp->getLParenLoc()
568 : SecondProp->getLocation(),
570 << SecondII << (I + 1);
578ODRDiagsEmitter::DiffResult
579ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,
580 DeclHashes &SecondHashes) {
581 auto DifferenceSelector = [](
const Decl *D) {
582 assert(D &&
"valid Decl required");
583 switch (D->getKind()) {
586 case Decl::AccessSpec:
587 switch (D->getAccess()) {
589 return PublicSpecifer;
591 return PrivateSpecifer;
593 return ProtectedSpecifer;
597 llvm_unreachable(
"Invalid access specifier");
598 case Decl::StaticAssert:
602 case Decl::CXXMethod:
603 case Decl::CXXConstructor:
604 case Decl::CXXDestructor:
606 case Decl::TypeAlias:
614 case Decl::FunctionTemplate:
615 return FunctionTemplate;
616 case Decl::ObjCMethod:
620 case Decl::ObjCProperty:
626 auto FirstIt = FirstHashes.begin();
627 auto SecondIt = SecondHashes.begin();
628 while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
629 if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
630 FirstIt->second == SecondIt->second) {
636 DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
637 DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
640 DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;
642 DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;
648void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(
649 DiffResult &DR,
const NamedDecl *FirstRecord, StringRef FirstModule,
650 const NamedDecl *SecondRecord, StringRef SecondModule)
const {
652 diag::err_module_odr_violation_different_definitions)
653 << FirstRecord << FirstModule.empty() << FirstModule;
656 Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
661 diag::note_module_odr_violation_different_definitions)
665 Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
666 << DR.SecondDecl->getSourceRange();
670void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
671 DiffResult &DR,
const NamedDecl *FirstRecord, StringRef FirstModule,
672 const NamedDecl *SecondRecord, StringRef SecondModule)
const {
673 auto GetMismatchedDeclLoc = [](
const NamedDecl *Container,
674 ODRMismatchDecl DiffType,
const Decl *D) {
677 if (DiffType == EndOfClass) {
678 if (
auto *Tag = dyn_cast<TagDecl>(Container))
679 Loc = Tag->getBraceRange().getEnd();
680 else if (
auto *IF = dyn_cast<ObjCInterfaceDecl>(Container))
681 Loc = IF->getAtEndRange().getBegin();
683 Loc = Container->getEndLoc();
685 Loc = D->getLocation();
686 Range = D->getSourceRange();
688 return std::make_pair(Loc, Range);
692 GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
693 Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
694 << FirstRecord << FirstModule.empty() << FirstModule
695 << FirstDiagInfo.second << DR.FirstDiffType;
697 auto SecondDiagInfo =
698 GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
699 Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
700 << SecondModule.empty() << SecondModule << SecondDiagInfo.second
701 << DR.SecondDiffType;
706 const struct CXXRecordDecl::DefinitionData *SecondDD)
const {
709 if (FirstRecord == SecondRecord)
715 const struct CXXRecordDecl::DefinitionData *FirstDD =
716 FirstRecord->DefinitionData;
717 assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
720 if (FirstDD != SecondDD) {
722 enum ODRDefinitionDataDifference {
729 auto DiagBaseError = [FirstRecord, &FirstModule,
731 ODRDefinitionDataDifference DiffType) {
732 return Diag(Loc, diag::err_module_odr_violation_definition_data)
733 << FirstRecord << FirstModule.empty() << FirstModule << Range
736 auto DiagBaseNote = [&SecondModule,
738 ODRDefinitionDataDifference DiffType) {
739 return Diag(Loc, diag::note_module_odr_violation_definition_data)
740 << SecondModule << Range << DiffType;
742 auto GetSourceRange = [](
const struct CXXRecordDecl::DefinitionData *DD) {
743 unsigned NumBases = DD->NumBases;
748 bases[NumBases - 1].getEndLoc());
751 unsigned FirstNumBases = FirstDD->NumBases;
752 unsigned FirstNumVBases = FirstDD->NumVBases;
753 unsigned SecondNumBases = SecondDD->NumBases;
754 unsigned SecondNumVBases = SecondDD->NumVBases;
755 if (FirstNumBases != SecondNumBases) {
756 DiagBaseError(FirstRecord->
getLocation(), GetSourceRange(FirstDD),
759 DiagBaseNote(SecondRecord->
getLocation(), GetSourceRange(SecondDD),
765 if (FirstNumVBases != SecondNumVBases) {
766 DiagBaseError(FirstRecord->
getLocation(), GetSourceRange(FirstDD),
769 DiagBaseNote(SecondRecord->
getLocation(), GetSourceRange(SecondDD),
777 for (
unsigned I = 0; I < FirstNumBases; ++I) {
784 << (I + 1) << FirstBase.
getType();
787 << (I + 1) << SecondBase.
getType();
805 << (I + 1) << FirstBase.
getType()
809 << (I + 1) << SecondBase.
getType()
821 assert(!FirstTemplate == !SecondTemplate &&
822 "Both pointers should be null or non-null");
824 if (FirstTemplate && SecondTemplate) {
829 assert(FirstTemplateParams.size() == SecondTemplateParams.size() &&
830 "Number of template parameters should be equal.");
831 for (
auto Pair : llvm::zip(FirstTemplateParams, SecondTemplateParams)) {
832 const NamedDecl *FirstDecl = std::get<0>(Pair);
833 const NamedDecl *SecondDecl = std::get<1>(Pair);
838 "Parameter Decl's should be the same kind.");
840 enum ODRTemplateDifference {
843 ParamSingleDefaultArgument,
844 ParamDifferentDefaultArgument,
847 auto hasDefaultArg = [](
const NamedDecl *D) {
848 if (
auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
849 return TTP->hasDefaultArgument() &&
850 !TTP->defaultArgumentWasInherited();
851 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
852 return NTTP->hasDefaultArgument() &&
853 !NTTP->defaultArgumentWasInherited();
854 auto *TTP = cast<TemplateTemplateParmDecl>(D);
855 return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();
857 bool hasFirstArg = hasDefaultArg(FirstDecl);
858 bool hasSecondArg = hasDefaultArg(SecondDecl);
860 ODRTemplateDifference ErrDiffType;
861 ODRTemplateDifference NoteDiffType;
866 if (FirstName != SecondName) {
867 bool FirstNameEmpty =
869 bool SecondNameEmpty =
871 ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;
872 NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;
873 }
else if (hasFirstArg == hasSecondArg)
874 ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
876 ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
879 diag::err_module_odr_violation_template_parameter)
880 << FirstRecord << FirstModule.empty() << FirstModule
884 diag::note_module_odr_violation_template_parameter)
886 << hasSecondArg << SecondName;
893 for (
const Decl *D : Record->decls()) {
903 PopulateHashes(FirstHashes, FirstRecord, DC);
904 PopulateHashes(SecondHashes, SecondRecord, DC);
906 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
907 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
908 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
909 const Decl *FirstDecl = DR.FirstDecl;
910 const Decl *SecondDecl = DR.SecondDecl;
912 if (FirstDiffType == Other || SecondDiffType == Other) {
913 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
918 if (FirstDiffType != SecondDiffType) {
919 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
920 SecondRecord, SecondModule);
926 enum ODRCXXRecordDifference {
927 StaticAssertCondition,
929 StaticAssertOnlyMessage,
938 MethodParameterSingleDefaultArgument,
939 MethodParameterDifferentDefaultArgument,
940 MethodNoTemplateArguments,
941 MethodDifferentNumberTemplateArguments,
942 MethodDifferentTemplateArgument,
948 FunctionTemplateDifferentNumberParameters,
949 FunctionTemplateParameterDifferentKind,
950 FunctionTemplateParameterName,
951 FunctionTemplateParameterSingleDefaultArgument,
952 FunctionTemplateParameterDifferentDefaultArgument,
953 FunctionTemplateParameterDifferentType,
954 FunctionTemplatePackParameter,
956 auto DiagError = [FirstRecord, &FirstModule,
958 ODRCXXRecordDifference DiffType) {
959 return Diag(Loc, diag::err_module_odr_violation_record)
960 << FirstRecord << FirstModule.empty() << FirstModule << Range
964 ODRCXXRecordDifference DiffType) {
965 return Diag(Loc, diag::note_module_odr_violation_record)
966 << SecondModule << Range << DiffType;
969 assert(FirstDiffType == SecondDiffType);
970 switch (FirstDiffType) {
974 case PrivateSpecifer:
975 case ProtectedSpecifer:
979 llvm_unreachable(
"Invalid diff type");
989 if (FirstODRHash != SecondODRHash) {
991 StaticAssertCondition);
993 StaticAssertCondition);
999 assert((FirstMessage || SecondMessage) &&
"Both messages cannot be empty");
1000 if ((FirstMessage && !SecondMessage) || (!FirstMessage && SecondMessage)) {
1010 if (SecondMessage) {
1017 DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
1018 << (FirstMessage ==
nullptr);
1019 DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
1020 << (SecondMessage ==
nullptr);
1024 if (FirstMessage && SecondMessage) {
1027 if (FirstMessageODRHash != SecondMessageODRHash) {
1029 StaticAssertMessage);
1031 StaticAssertMessage);
1039 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1040 cast<FieldDecl>(FirstDecl),
1041 cast<FieldDecl>(SecondDecl)))
1053 auto GetMethodTypeForDiagnostics = [](
const CXXMethodDecl *D) {
1054 if (isa<CXXConstructorDecl>(D))
1055 return DiagConstructor;
1056 if (isa<CXXDestructorDecl>(D))
1057 return DiagDestructor;
1060 const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
1061 const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
1062 FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
1063 SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
1066 auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType,
1067 FirstName](ODRCXXRecordDifference DiffType) {
1070 << FirstMethodType << FirstName;
1072 auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,
1073 SecondName](ODRCXXRecordDifference DiffType) {
1076 << SecondMethodType << SecondName;
1079 if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
1080 DiagMethodError(MethodName);
1081 DiagMethodNote(MethodName);
1087 if (FirstDeleted != SecondDeleted) {
1088 DiagMethodError(MethodDeleted) << FirstDeleted;
1089 DiagMethodNote(MethodDeleted) << SecondDeleted;
1095 if (FirstDefaulted != SecondDefaulted) {
1096 DiagMethodError(MethodDefaulted) << FirstDefaulted;
1097 DiagMethodNote(MethodDefaulted) << SecondDefaulted;
1103 const bool FirstPure = FirstMethod->
isPure();
1104 const bool SecondPure = SecondMethod->
isPure();
1105 if ((FirstVirtual || SecondVirtual) &&
1106 (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
1107 DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
1108 DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
1117 const bool FirstStatic = FirstStorage ==
SC_Static;
1118 const bool SecondStatic = SecondStorage ==
SC_Static;
1119 if (FirstStatic != SecondStatic) {
1120 DiagMethodError(MethodStatic) << FirstStatic;
1121 DiagMethodNote(MethodStatic) << SecondStatic;
1125 const bool FirstVolatile = FirstMethod->
isVolatile();
1126 const bool SecondVolatile = SecondMethod->
isVolatile();
1127 if (FirstVolatile != SecondVolatile) {
1128 DiagMethodError(MethodVolatile) << FirstVolatile;
1129 DiagMethodNote(MethodVolatile) << SecondVolatile;
1133 const bool FirstConst = FirstMethod->
isConst();
1134 const bool SecondConst = SecondMethod->
isConst();
1135 if (FirstConst != SecondConst) {
1136 DiagMethodError(MethodConst) << FirstConst;
1137 DiagMethodNote(MethodConst) << SecondConst;
1143 if (FirstInline != SecondInline) {
1144 DiagMethodError(MethodInline) << FirstInline;
1145 DiagMethodNote(MethodInline) << SecondInline;
1150 FirstModule, SecondModule,
1151 FirstMethod, SecondMethod))
1154 for (
unsigned I = 0, N = FirstMethod->
param_size(); I < N; ++I) {
1160 if ((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
1161 DiagMethodError(MethodParameterSingleDefaultArgument)
1162 << (I + 1) << (FirstInit ==
nullptr)
1164 DiagMethodNote(MethodParameterSingleDefaultArgument)
1165 << (I + 1) << (SecondInit ==
nullptr)
1170 if (FirstInit && SecondInit &&
1172 DiagMethodError(MethodParameterDifferentDefaultArgument)
1174 DiagMethodNote(MethodParameterDifferentDefaultArgument)
1185 if ((FirstTemplateArgs && !SecondTemplateArgs) ||
1186 (!FirstTemplateArgs && SecondTemplateArgs)) {
1187 DiagMethodError(MethodNoTemplateArguments)
1188 << (FirstTemplateArgs !=
nullptr);
1189 DiagMethodNote(MethodNoTemplateArguments)
1190 << (SecondTemplateArgs !=
nullptr);
1194 if (FirstTemplateArgs && SecondTemplateArgs) {
1200 ExpandedList.push_back(&TA);
1203 llvm::append_range(ExpandedList,
1204 llvm::make_pointer_range(TA.getPackAsArray()));
1206 return ExpandedList;
1209 ExpandTemplateArgumentList(FirstTemplateArgs);
1211 ExpandTemplateArgumentList(SecondTemplateArgs);
1213 if (FirstExpandedList.size() != SecondExpandedList.size()) {
1214 DiagMethodError(MethodDifferentNumberTemplateArguments)
1215 << (
unsigned)FirstExpandedList.size();
1216 DiagMethodNote(MethodDifferentNumberTemplateArguments)
1217 << (
unsigned)SecondExpandedList.size();
1221 for (
unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
1223 &SecondTA = *SecondExpandedList[i];
1227 DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;
1228 DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;
1243 const bool HasFirstBody =
1244 ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->
getODRHash();
1245 const bool HasSecondBody =
1246 ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->
getODRHash();
1248 if (HasFirstBody != HasSecondBody) {
1249 DiagMethodError(MethodSingleBody) << HasFirstBody;
1250 DiagMethodNote(MethodSingleBody) << HasSecondBody;
1254 if (HasFirstBody && HasSecondBody) {
1255 DiagMethodError(MethodDifferentBody);
1256 DiagMethodNote(MethodDifferentBody);
1265 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1266 cast<TypedefNameDecl>(FirstDecl),
1267 cast<TypedefNameDecl>(SecondDecl),
1268 FirstDiffType == TypeAlias))
1273 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1274 cast<VarDecl>(FirstDecl),
1275 cast<VarDecl>(SecondDecl)))
1280 const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
1281 const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
1289 if (FirstND && SecondND) {
1299 if (FirstTSI && SecondTSI) {
1309 << SecondFriendType;
1315 << (FirstTSI ==
nullptr);
1318 << (SecondTSI ==
nullptr);
1321 case FunctionTemplate: {
1323 cast<FunctionTemplateDecl>(FirstDecl);
1325 cast<FunctionTemplateDecl>(SecondDecl);
1330 auto DiagTemplateError = [&DiagError,
1331 FirstTemplate](ODRCXXRecordDifference DiffType) {
1336 auto DiagTemplateNote = [&DiagNote,
1337 SecondTemplate](ODRCXXRecordDifference DiffType) {
1343 if (FirstTPL->
size() != SecondTPL->
size()) {
1344 DiagTemplateError(FunctionTemplateDifferentNumberParameters)
1345 << FirstTPL->
size();
1346 DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
1347 << SecondTPL->
size();
1351 for (
unsigned i = 0, e = FirstTPL->
size(); i != e; ++i) {
1357 TemplateTypeParameter,
1358 NonTypeTemplateParameter,
1359 TemplateTemplateParameter,
1362 switch (D->getKind()) {
1364 llvm_unreachable(
"Unexpected template parameter type");
1365 case Decl::TemplateTypeParm:
1366 return TemplateTypeParameter;
1367 case Decl::NonTypeTemplateParm:
1368 return NonTypeTemplateParameter;
1369 case Decl::TemplateTemplateParm:
1370 return TemplateTemplateParameter;
1374 DiagTemplateError(FunctionTemplateParameterDifferentKind)
1375 << (i + 1) << GetParamType(FirstParam);
1376 DiagTemplateNote(FunctionTemplateParameterDifferentKind)
1377 << (i + 1) << GetParamType(SecondParam);
1382 DiagTemplateError(FunctionTemplateParameterName)
1383 << (i + 1) << (
bool)FirstParam->
getIdentifier() << FirstParam;
1384 DiagTemplateNote(FunctionTemplateParameterName)
1385 << (i + 1) << (
bool)SecondParam->
getIdentifier() << SecondParam;
1389 if (isa<TemplateTypeParmDecl>(FirstParam) &&
1390 isa<TemplateTypeParmDecl>(SecondParam)) {
1392 cast<TemplateTypeParmDecl>(FirstParam);
1394 cast<TemplateTypeParmDecl>(SecondParam);
1395 bool HasFirstDefaultArgument =
1398 bool HasSecondDefaultArgument =
1401 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1402 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1403 << (i + 1) << HasFirstDefaultArgument;
1404 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1405 << (i + 1) << HasSecondDefaultArgument;
1409 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1413 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1414 << (i + 1) << FirstType;
1415 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1416 << (i + 1) << SecondType;
1422 DiagTemplateError(FunctionTemplatePackParameter)
1424 DiagTemplateNote(FunctionTemplatePackParameter)
1430 if (isa<TemplateTemplateParmDecl>(FirstParam) &&
1431 isa<TemplateTemplateParmDecl>(SecondParam)) {
1433 cast<TemplateTemplateParmDecl>(FirstParam);
1435 cast<TemplateTemplateParmDecl>(SecondParam);
1440 auto ComputeTemplateParameterListODRHash =
1448 if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1449 ComputeTemplateParameterListODRHash(SecondTPL)) {
1450 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1451 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1455 bool HasFirstDefaultArgument =
1458 bool HasSecondDefaultArgument =
1461 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1462 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1463 << (i + 1) << HasFirstDefaultArgument;
1464 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1465 << (i + 1) << HasSecondDefaultArgument;
1469 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1475 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1476 << (i + 1) << FirstTA;
1477 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1478 << (i + 1) << SecondTA;
1484 DiagTemplateError(FunctionTemplatePackParameter)
1486 DiagTemplateNote(FunctionTemplatePackParameter)
1492 if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
1493 isa<NonTypeTemplateParmDecl>(SecondParam)) {
1495 cast<NonTypeTemplateParmDecl>(FirstParam);
1497 cast<NonTypeTemplateParmDecl>(SecondParam);
1502 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1503 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1507 bool HasFirstDefaultArgument =
1510 bool HasSecondDefaultArgument =
1513 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1514 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1515 << (i + 1) << HasFirstDefaultArgument;
1516 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1517 << (i + 1) << HasSecondDefaultArgument;
1521 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1526 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1527 << (i + 1) << FirstDefaultArgument;
1528 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1529 << (i + 1) << SecondDefaultArgument;
1535 DiagTemplateError(FunctionTemplatePackParameter)
1537 DiagTemplateNote(FunctionTemplatePackParameter)
1548 diag::err_module_odr_violation_mismatch_decl_unknown)
1549 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1552 diag::note_module_odr_violation_mismatch_decl_unknown)
1553 << SecondModule.empty() << SecondModule << FirstDiffType
1560 if (FirstRecord == SecondRecord)
1568 for (
const Decl *D : Record->decls()) {
1578 PopulateHashes(FirstHashes, FirstRecord, DC);
1579 PopulateHashes(SecondHashes, SecondRecord, DC);
1581 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1582 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1583 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1584 const Decl *FirstDecl = DR.FirstDecl;
1585 const Decl *SecondDecl = DR.SecondDecl;
1587 if (FirstDiffType == Other || SecondDiffType == Other) {
1588 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1593 if (FirstDiffType != SecondDiffType) {
1594 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1595 SecondRecord, SecondModule);
1599 assert(FirstDiffType == SecondDiffType);
1600 switch (FirstDiffType) {
1605 case PublicSpecifer:
1606 case PrivateSpecifer:
1607 case ProtectedSpecifer:
1612 case FunctionTemplate:
1617 llvm_unreachable(
"Invalid diff type");
1620 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1621 cast<FieldDecl>(FirstDecl),
1622 cast<FieldDecl>(SecondDecl)))
1627 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1628 cast<TypedefNameDecl>(FirstDecl),
1629 cast<TypedefNameDecl>(SecondDecl),
1635 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1636 cast<VarDecl>(FirstDecl),
1637 cast<VarDecl>(SecondDecl)))
1644 diag::err_module_odr_violation_mismatch_decl_unknown)
1645 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1648 diag::note_module_odr_violation_mismatch_decl_unknown)
1649 << SecondModule.empty() << SecondModule << FirstDiffType
1657 if (FirstFunction == SecondFunction)
1661 enum ODRFunctionDifference {
1665 ParameterSingleDefaultArgument,
1666 ParameterDifferentDefaultArgument,
1673 auto DiagError = [FirstFunction, &FirstModule,
1675 ODRFunctionDifference DiffType) {
1676 return Diag(Loc, diag::err_module_odr_violation_function)
1677 << FirstFunction << FirstModule.empty() << FirstModule << Range
1681 ODRFunctionDifference DiffType) {
1682 return Diag(Loc, diag::note_module_odr_violation_function)
1683 << SecondModule << Range << DiffType;
1698 "Merged functions with different number of parameters");
1700 size_t ParamSize = FirstFunction->
param_size();
1701 for (
unsigned I = 0; I < ParamSize; ++I) {
1706 "Merged function has different parameter types.");
1720 if (FirstParamType != SecondParamType &&
1726 << (I + 1) << FirstParamType <<
true
1727 << ParamDecayedType->getOriginalType();
1731 << (I + 1) << FirstParamType <<
false;
1738 << (I + 1) << SecondParamType <<
true
1739 << ParamDecayedType->getOriginalType();
1743 << (I + 1) << SecondParamType <<
false;
1751 if ((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
1753 ParameterSingleDefaultArgument)
1754 << (I + 1) << (FirstInit ==
nullptr)
1757 ParameterSingleDefaultArgument)
1758 << (I + 1) << (SecondInit ==
nullptr)
1763 if (FirstInit && SecondInit &&
1766 ParameterDifferentDefaultArgument)
1769 ParameterDifferentDefaultArgument)
1775 "Undiagnosed parameter difference.");
1788 const EnumDecl *SecondEnum)
const {
1789 if (FirstEnum == SecondEnum)
1793 enum ODREnumDifference {
1795 EnumTagKeywordMismatch,
1796 SingleSpecifiedType,
1797 DifferentSpecifiedTypes,
1798 DifferentNumberEnumConstants,
1800 EnumConstantSingleInitializer,
1801 EnumConstantDifferentInitializer,
1807 auto DiagError = [FirstEnum, &FirstModule,
this](
const auto *DiagAnchor,
1808 ODREnumDifference DiffType) {
1809 return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1810 << FirstEnum << FirstModule.empty() << FirstModule
1813 auto DiagNote = [&SecondModule,
this](
const auto *DiagAnchor,
1814 ODREnumDifference DiffType) {
1815 return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1816 << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1820 DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->
isScoped();
1821 DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->
isScoped();
1828 DiagError(FirstEnum, EnumTagKeywordMismatch)
1830 DiagNote(SecondEnum, EnumTagKeywordMismatch)
1844 if (FirstUnderlyingType.
isNull() != SecondUnderlyingType.
isNull()) {
1845 DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.
isNull();
1846 DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.
isNull();
1850 if (!FirstUnderlyingType.
isNull() && !SecondUnderlyingType.
isNull()) {
1853 DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1854 DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1863 for (
const Decl *D :
Enum->decls()) {
1868 assert(isa<EnumConstantDecl>(D) &&
"Unexpected Decl kind");
1869 Hashes.emplace_back(cast<EnumConstantDecl>(D),
computeODRHash(D));
1873 PopulateHashes(FirstHashes, FirstEnum);
1875 PopulateHashes(SecondHashes, SecondEnum);
1877 if (FirstHashes.size() != SecondHashes.size()) {
1878 DiagError(FirstEnum, DifferentNumberEnumConstants)
1879 << (
int)FirstHashes.size();
1880 DiagNote(SecondEnum, DifferentNumberEnumConstants)
1881 << (
int)SecondHashes.size();
1885 for (
unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {
1886 if (FirstHashes[I].second == SecondHashes[I].second)
1892 DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1893 DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1899 if (!FirstInit && !SecondInit)
1902 if (!FirstInit || !SecondInit) {
1903 DiagError(FirstConstant, EnumConstantSingleInitializer)
1904 << I + 1 << FirstConstant << (FirstInit !=
nullptr);
1905 DiagNote(SecondConstant, EnumConstantSingleInitializer)
1906 << I + 1 << SecondConstant << (SecondInit !=
nullptr);
1911 DiagError(FirstConstant, EnumConstantDifferentInitializer)
1912 << I + 1 << FirstConstant;
1913 DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1914 << I + 1 << SecondConstant;
1923 const struct ObjCInterfaceDecl::DefinitionData *SecondDD)
const {
1926 if (FirstID == SecondID)
1933 enum ODRInterfaceDifference {
1938 auto DiagError = [FirstID, &FirstModule,
1940 ODRInterfaceDifference DiffType) {
1941 return Diag(Loc, diag::err_module_odr_violation_objc_interface)
1942 << FirstID << FirstModule.empty() << FirstModule << Range
1946 ODRInterfaceDifference DiffType) {
1947 return Diag(Loc, diag::note_module_odr_violation_objc_interface)
1948 << SecondModule.empty() << SecondModule << Range << DiffType;
1951 const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1952 assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
1953 if (FirstDD != SecondDD) {
1955 auto GetSuperClassSourceRange = [](
const TypeSourceInfo *SuperInfo,
1958 return ID->getSourceRange();
1966 const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;
1967 if (SecondSuperInfo)
1971 if ((FirstSuperClass && SecondSuperClass &&
1973 (FirstSuperClass && !SecondSuperClass) ||
1974 (!FirstSuperClass && SecondSuperClass)) {
1977 FirstType = FirstSuperInfo->
getType();
1980 GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1982 << (
bool)FirstSuperInfo << FirstType;
1985 if (SecondSuperInfo)
1986 SecondType = SecondSuperInfo->
getType();
1989 GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1991 << (
bool)SecondSuperInfo << SecondType;
1997 auto &SecondProtos = SecondDD->ReferencedProtocols;
1998 if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
1999 SecondProtos, SecondID, SecondModule))
2005 for (
auto *D :
ID->decls()) {
2016 PopulateHashes(FirstHashes, FirstID, FirstID->
getDefinition());
2017 PopulateHashes(SecondHashes, SecondID, SecondID->
getDefinition());
2019 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2020 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2021 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2022 const Decl *FirstDecl = DR.FirstDecl;
2023 const Decl *SecondDecl = DR.SecondDecl;
2025 if (FirstDiffType == Other || SecondDiffType == Other) {
2026 diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2031 if (FirstDiffType != SecondDiffType) {
2032 diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2037 assert(FirstDiffType == SecondDiffType);
2038 switch (FirstDiffType) {
2047 case PublicSpecifer:
2048 case PrivateSpecifer:
2049 case ProtectedSpecifer:
2054 case FunctionTemplate:
2055 llvm_unreachable(
"Invalid diff type");
2058 if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2059 cast<ObjCMethodDecl>(FirstDecl),
2060 cast<ObjCMethodDecl>(SecondDecl)))
2065 if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2066 cast<FieldDecl>(FirstDecl),
2067 cast<FieldDecl>(SecondDecl)))
2071 const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl);
2072 const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl);
2087 case ObjCProperty: {
2088 if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2089 cast<ObjCPropertyDecl>(FirstDecl),
2090 cast<ObjCPropertyDecl>(SecondDecl)))
2097 diag::err_module_odr_violation_mismatch_decl_unknown)
2098 << FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2101 diag::note_module_odr_violation_mismatch_decl_unknown)
2102 << SecondModule.empty() << SecondModule << FirstDiffType
2110 const struct ObjCProtocolDecl::DefinitionData *SecondDD)
const {
2111 if (FirstProtocol == SecondProtocol)
2117 const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2118 assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
2120 if (FirstDD != SecondDD) {
2125 if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2126 SecondProtocols, SecondProtocol,
2133 for (
const Decl *D :
ID->decls()) {
2144 PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->
getDefinition());
2145 PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->
getDefinition());
2147 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2148 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2149 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2150 const Decl *FirstDecl = DR.FirstDecl;
2151 const Decl *SecondDecl = DR.SecondDecl;
2153 if (FirstDiffType == Other || SecondDiffType == Other) {
2154 diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2155 SecondProtocol, SecondModule);
2159 if (FirstDiffType != SecondDiffType) {
2160 diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2161 SecondProtocol, SecondModule);
2165 assert(FirstDiffType == SecondDiffType);
2166 switch (FirstDiffType) {
2176 case PublicSpecifer:
2177 case PrivateSpecifer:
2178 case ProtectedSpecifer:
2183 case FunctionTemplate:
2184 llvm_unreachable(
"Invalid diff type");
2186 if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2187 cast<ObjCMethodDecl>(FirstDecl),
2188 cast<ObjCMethodDecl>(SecondDecl)))
2192 case ObjCProperty: {
2193 if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2195 cast<ObjCPropertyDecl>(FirstDecl),
2196 cast<ObjCPropertyDecl>(SecondDecl)))
2203 diag::err_module_odr_violation_mismatch_decl_unknown)
2204 << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2207 diag::note_module_odr_violation_mismatch_decl_unknown)
2208 << 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.
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
bool isPure() const
Whether this virtual function is pure, i.e.
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
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.
ImplementationControl getImplementationControl() const
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
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.
SourceLocation getEndLoc() const
Get the end source location.
SourceLocation getBeginLoc() const
Get the begin source location.
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
@ NumObjCPropertyAttrsBits
Number of bits fitting all the property attributes.
StorageClass
Storage classes.