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");
588 case Decl::AccessSpec:
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();
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,
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)))
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,
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) {
1417 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1418 << (i + 1) << FirstTA;
1419 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1420 << (i + 1) << SecondTA;
1426 DiagTemplateError(FunctionTemplatePackParameter)
1428 DiagTemplateNote(FunctionTemplatePackParameter)
1434 if (isa<TemplateTemplateParmDecl>(FirstParam) &&
1435 isa<TemplateTemplateParmDecl>(SecondParam)) {
1437 cast<TemplateTemplateParmDecl>(FirstParam);
1439 cast<TemplateTemplateParmDecl>(SecondParam);
1444 auto ComputeTemplateParameterListODRHash =
1452 if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1453 ComputeTemplateParameterListODRHash(SecondTPL)) {
1454 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1455 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1459 bool HasFirstDefaultArgument =
1462 bool HasSecondDefaultArgument =
1465 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1466 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1467 << (i + 1) << HasFirstDefaultArgument;
1468 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1469 << (i + 1) << HasSecondDefaultArgument;
1473 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1479 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1480 << (i + 1) << FirstTA;
1481 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1482 << (i + 1) << SecondTA;
1488 DiagTemplateError(FunctionTemplatePackParameter)
1490 DiagTemplateNote(FunctionTemplatePackParameter)
1496 if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
1497 isa<NonTypeTemplateParmDecl>(SecondParam)) {
1499 cast<NonTypeTemplateParmDecl>(FirstParam);
1501 cast<NonTypeTemplateParmDecl>(SecondParam);
1506 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1507 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1511 bool HasFirstDefaultArgument =
1514 bool HasSecondDefaultArgument =
1517 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1518 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1519 << (i + 1) << HasFirstDefaultArgument;
1520 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1521 << (i + 1) << HasSecondDefaultArgument;
1525 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1533 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1534 << (i + 1) << FirstDefaultArgument;
1535 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1536 << (i + 1) << SecondDefaultArgument;
1542 DiagTemplateError(FunctionTemplatePackParameter)
1544 DiagTemplateNote(FunctionTemplatePackParameter)
1555 diag::err_module_odr_violation_mismatch_decl_unknown)
1556 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1559 diag::note_module_odr_violation_mismatch_decl_unknown)
1560 << SecondModule.empty() << SecondModule << FirstDiffType
1567 if (FirstRecord == SecondRecord)
1585 PopulateHashes(FirstHashes, FirstRecord, DC);
1586 PopulateHashes(SecondHashes, SecondRecord, DC);
1588 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1589 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1590 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1591 const Decl *FirstDecl = DR.FirstDecl;
1592 const Decl *SecondDecl = DR.SecondDecl;
1594 if (FirstDiffType ==
Other || SecondDiffType ==
Other) {
1595 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1600 if (FirstDiffType != SecondDiffType) {
1601 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1602 SecondRecord, SecondModule);
1606 assert(FirstDiffType == SecondDiffType);
1607 switch (FirstDiffType) {
1612 case PublicSpecifer:
1613 case PrivateSpecifer:
1614 case ProtectedSpecifer:
1619 case FunctionTemplate:
1624 llvm_unreachable(
"Invalid diff type");
1627 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1628 cast<FieldDecl>(FirstDecl),
1629 cast<FieldDecl>(SecondDecl)))
1634 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1635 cast<TypedefNameDecl>(FirstDecl),
1636 cast<TypedefNameDecl>(SecondDecl),
1642 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1643 cast<VarDecl>(FirstDecl),
1644 cast<VarDecl>(SecondDecl)))
1651 diag::err_module_odr_violation_mismatch_decl_unknown)
1652 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1655 diag::note_module_odr_violation_mismatch_decl_unknown)
1656 << SecondModule.empty() << SecondModule << FirstDiffType
1664 if (FirstFunction == SecondFunction)
1668 enum ODRFunctionDifference {
1672 ParameterSingleDefaultArgument,
1673 ParameterDifferentDefaultArgument,
1680 auto DiagError = [FirstFunction, &FirstModule,
1682 ODRFunctionDifference DiffType) {
1683 return Diag(
Loc, diag::err_module_odr_violation_function)
1684 << FirstFunction << FirstModule.empty() << FirstModule <<
Range
1688 ODRFunctionDifference DiffType) {
1689 return Diag(
Loc, diag::note_module_odr_violation_function)
1690 << SecondModule <<
Range << DiffType;
1705 "Merged functions with different number of parameters");
1707 size_t ParamSize = FirstFunction->
param_size();
1708 for (
unsigned I = 0; I < ParamSize; ++I) {
1713 "Merged function has different parameter types.");
1727 if (FirstParamType != SecondParamType &&
1733 << (I + 1) << FirstParamType <<
true
1734 << ParamDecayedType->getOriginalType();
1738 << (I + 1) << FirstParamType <<
false;
1745 << (I + 1) << SecondParamType <<
true
1746 << ParamDecayedType->getOriginalType();
1750 << (I + 1) << SecondParamType <<
false;
1758 if ((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
1760 ParameterSingleDefaultArgument)
1761 << (I + 1) << (FirstInit ==
nullptr)
1764 ParameterSingleDefaultArgument)
1765 << (I + 1) << (SecondInit ==
nullptr)
1770 if (FirstInit && SecondInit &&
1773 ParameterDifferentDefaultArgument)
1776 ParameterDifferentDefaultArgument)
1782 "Undiagnosed parameter difference.");
1795 const EnumDecl *SecondEnum)
const {
1796 if (FirstEnum == SecondEnum)
1800 enum ODREnumDifference {
1802 EnumTagKeywordMismatch,
1803 SingleSpecifiedType,
1804 DifferentSpecifiedTypes,
1805 DifferentNumberEnumConstants,
1807 EnumConstantSingleInitializer,
1808 EnumConstantDifferentInitializer,
1814 auto DiagError = [FirstEnum, &FirstModule,
this](
const auto *DiagAnchor,
1815 ODREnumDifference DiffType) {
1816 return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1817 << FirstEnum << FirstModule.empty() << FirstModule
1820 auto DiagNote = [&SecondModule,
this](
const auto *DiagAnchor,
1821 ODREnumDifference DiffType) {
1822 return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1823 << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1827 DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->
isScoped();
1828 DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->
isScoped();
1835 DiagError(FirstEnum, EnumTagKeywordMismatch)
1837 DiagNote(SecondEnum, EnumTagKeywordMismatch)
1851 if (FirstUnderlyingType.
isNull() != SecondUnderlyingType.
isNull()) {
1852 DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.
isNull();
1853 DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.
isNull();
1857 if (!FirstUnderlyingType.
isNull() && !SecondUnderlyingType.
isNull()) {
1860 DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1861 DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1875 assert(isa<EnumConstantDecl>(
D) &&
"Unexpected Decl kind");
1880 PopulateHashes(FirstHashes, FirstEnum);
1882 PopulateHashes(SecondHashes, SecondEnum);
1884 if (FirstHashes.size() != SecondHashes.size()) {
1885 DiagError(FirstEnum, DifferentNumberEnumConstants)
1886 << (
int)FirstHashes.size();
1887 DiagNote(SecondEnum, DifferentNumberEnumConstants)
1888 << (
int)SecondHashes.size();
1892 for (
unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {
1893 if (FirstHashes[I].second == SecondHashes[I].second)
1899 DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1900 DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1906 if (!FirstInit && !SecondInit)
1909 if (!FirstInit || !SecondInit) {
1910 DiagError(FirstConstant, EnumConstantSingleInitializer)
1911 << I + 1 << FirstConstant << (FirstInit !=
nullptr);
1912 DiagNote(SecondConstant, EnumConstantSingleInitializer)
1913 << I + 1 << SecondConstant << (SecondInit !=
nullptr);
1918 DiagError(FirstConstant, EnumConstantDifferentInitializer)
1919 << I + 1 << FirstConstant;
1920 DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1921 << I + 1 << SecondConstant;
1930 const struct ObjCInterfaceDecl::DefinitionData *SecondDD)
const {
1933 if (FirstID == SecondID)
1940 enum ODRInterfaceDifference {
1945 auto DiagError = [FirstID, &FirstModule,
1947 ODRInterfaceDifference DiffType) {
1948 return Diag(
Loc, diag::err_module_odr_violation_objc_interface)
1949 << FirstID << FirstModule.empty() << FirstModule <<
Range
1953 ODRInterfaceDifference DiffType) {
1954 return Diag(
Loc, diag::note_module_odr_violation_objc_interface)
1955 << SecondModule.empty() << SecondModule <<
Range << DiffType;
1958 const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1959 assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
1960 if (FirstDD != SecondDD) {
1962 auto GetSuperClassSourceRange = [](
const TypeSourceInfo *SuperInfo,
1965 return ID->getSourceRange();
1973 const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;
1974 if (SecondSuperInfo)
1978 if ((FirstSuperClass && SecondSuperClass &&
1980 (FirstSuperClass && !SecondSuperClass) ||
1981 (!FirstSuperClass && SecondSuperClass)) {
1984 FirstType = FirstSuperInfo->
getType();
1987 GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1989 << (
bool)FirstSuperInfo << FirstType;
1992 if (SecondSuperInfo)
1993 SecondType = SecondSuperInfo->
getType();
1996 GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1998 << (
bool)SecondSuperInfo << SecondType;
2004 auto &SecondProtos = SecondDD->ReferencedProtocols;
2005 if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
2006 SecondProtos, SecondID, SecondModule))
2012 for (
auto *
D :
ID->decls()) {
2023 PopulateHashes(FirstHashes, FirstID, FirstID->
getDefinition());
2024 PopulateHashes(SecondHashes, SecondID, SecondID->
getDefinition());
2026 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2027 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2028 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2029 const Decl *FirstDecl = DR.FirstDecl;
2030 const Decl *SecondDecl = DR.SecondDecl;
2032 if (FirstDiffType ==
Other || SecondDiffType ==
Other) {
2033 diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2038 if (FirstDiffType != SecondDiffType) {
2039 diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2044 assert(FirstDiffType == SecondDiffType);
2045 switch (FirstDiffType) {
2054 case PublicSpecifer:
2055 case PrivateSpecifer:
2056 case ProtectedSpecifer:
2061 case FunctionTemplate:
2062 llvm_unreachable(
"Invalid diff type");
2065 if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2066 cast<ObjCMethodDecl>(FirstDecl),
2067 cast<ObjCMethodDecl>(SecondDecl)))
2072 if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2073 cast<FieldDecl>(FirstDecl),
2074 cast<FieldDecl>(SecondDecl)))
2078 const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl);
2079 const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl);
2094 case ObjCProperty: {
2095 if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2096 cast<ObjCPropertyDecl>(FirstDecl),
2097 cast<ObjCPropertyDecl>(SecondDecl)))
2104 diag::err_module_odr_violation_mismatch_decl_unknown)
2105 << FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2108 diag::note_module_odr_violation_mismatch_decl_unknown)
2109 << SecondModule.empty() << SecondModule << FirstDiffType
2117 const struct ObjCProtocolDecl::DefinitionData *SecondDD)
const {
2118 if (FirstProtocol == SecondProtocol)
2124 const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2125 assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
2127 if (FirstDD != SecondDD) {
2132 if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2133 SecondProtocols, SecondProtocol,
2140 for (
const Decl *
D :
ID->decls()) {
2151 PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->
getDefinition());
2152 PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->
getDefinition());
2154 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2155 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2156 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2157 const Decl *FirstDecl = DR.FirstDecl;
2158 const Decl *SecondDecl = DR.SecondDecl;
2160 if (FirstDiffType ==
Other || SecondDiffType ==
Other) {
2161 diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2162 SecondProtocol, SecondModule);
2166 if (FirstDiffType != SecondDiffType) {
2167 diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2168 SecondProtocol, SecondModule);
2172 assert(FirstDiffType == SecondDiffType);
2173 switch (FirstDiffType) {
2183 case PublicSpecifer:
2184 case PrivateSpecifer:
2185 case ProtectedSpecifer:
2190 case FunctionTemplate:
2191 llvm_unreachable(
"Invalid diff type");
2193 if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2194 cast<ObjCMethodDecl>(FirstDecl),
2195 cast<ObjCMethodDecl>(SecondDecl)))
2199 case ObjCProperty: {
2200 if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2202 cast<ObjCPropertyDecl>(FirstDecl),
2203 cast<ObjCPropertyDecl>(SecondDecl)))
2210 diag::err_module_odr_violation_mismatch_decl_unknown)
2211 << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2214 diag::note_module_odr_violation_mismatch_decl_unknown)
2215 << 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
AccessSpecifier getAccess() 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.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
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.
const TemplateArgumentLoc & 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.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ NumObjCPropertyAttrsBits
Number of bits fitting all the property attributes.
@ Other
Other implicit parameter.