;
46 returnM->getFullModuleName();
52template<
typenameMethodT>
55StringRef FirstModule,
56StringRef SecondModule,
57 constMethodT *FirstMethod,
58 constMethodT *SecondMethod) {
64 autoGetDiagMethodType = [](
const NamedDecl*
D) {
65 if(isa<CXXConstructorDecl>(
D))
66 returnDiagConstructor;
67 if(isa<CXXDestructorDecl>(
D))
68 returnDiagDestructor;
72 enumODRMethodParametersDifference {
77 autoDiagError = [&Diags, &GetDiagMethodType, FirstContainer, FirstModule,
78FirstMethod](ODRMethodParametersDifference DiffType) {
80DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);
81 returnDiags.
Report(FirstMethod->getLocation(),
82diag::err_module_odr_violation_method_params)
83<< FirstContainer << FirstModule.empty() << FirstModule
87 autoDiagNote = [&Diags, &GetDiagMethodType, SecondModule,
88SecondMethod](ODRMethodParametersDifference DiffType) {
90DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);
91 returnDiags.
Report(SecondMethod->getLocation(),
92diag::note_module_odr_violation_method_params)
93<< SecondModule.empty() << SecondModule
94<< SecondMethod->getSourceRange() << DiffType << SecondMethodType
98 const unsignedFirstNumParameters = FirstMethod->param_size();
99 const unsignedSecondNumParameters = SecondMethod->param_size();
100 if(FirstNumParameters != SecondNumParameters) {
101DiagError(NumberParameters) << FirstNumParameters;
102DiagNote(NumberParameters) << SecondNumParameters;
106 for(
unsignedI = 0; I < FirstNumParameters; ++I) {
107 const ParmVarDecl*FirstParam = FirstMethod->getParamDecl(I);
108 const ParmVarDecl*SecondParam = SecondMethod->getParamDecl(I);
112 if(FirstParamType != SecondParamType &&
116DiagError(ParameterType) << (I + 1) << FirstParamType <<
true 117<< ParamDecayedType->getOriginalType();
119DiagError(ParameterType) << (I + 1) << FirstParamType <<
false;
124DiagNote(ParameterType) << (I + 1) << SecondParamType <<
true 125<< ParamDecayedType->getOriginalType();
127DiagNote(ParameterType) << (I + 1) << SecondParamType <<
false;
134 if(FirstParamName != SecondParamName) {
135DiagError(ParameterName) << (I + 1) << FirstParamName;
136DiagNote(ParameterName) << (I + 1) << SecondParamName;
144boolODRDiagsEmitter::diagnoseSubMismatchField(
145 const NamedDecl*FirstRecord, StringRef FirstModule, StringRef SecondModule,
147 enumODRFieldDifference {
151FieldDifferentWidthBitField,
153FieldSingleInitializer,
154FieldDifferentInitializers,
157 autoDiagError = [FirstRecord, FirstField, FirstModule,
158 this](ODRFieldDifference DiffType) {
159 returnDiag(FirstField->
getLocation(), diag::err_module_odr_violation_field)
160<< FirstRecord << FirstModule.empty() << FirstModule
163 autoDiagNote = [SecondField, SecondModule,
164 this](ODRFieldDifference DiffType) {
166diag::note_module_odr_violation_field)
167<< SecondModule.empty() << SecondModule << SecondField->
getSourceRange() << DiffType;
173DiagError(FieldName) << FirstII;
174DiagNote(FieldName) << SecondII;
181DiagError(FieldTypeName) << FirstII << FirstType;
182DiagNote(FieldTypeName) << SecondII << SecondType;
189 const boolIsFirstBitField = FirstField->
isBitField();
190 const boolIsSecondBitField = SecondField->
isBitField();
191 if(IsFirstBitField != IsSecondBitField) {
192DiagError(FieldSingleBitField) << FirstII << IsFirstBitField;
193DiagNote(FieldSingleBitField) << SecondII << IsSecondBitField;
197 if(IsFirstBitField && IsSecondBitField) {
200 if(FirstBitWidthHash != SecondBitWidthHash) {
201DiagError(FieldDifferentWidthBitField)
203DiagNote(FieldDifferentWidthBitField)
209 if(!LangOpts.CPlusPlus)
212 const boolIsFirstMutable = FirstField->
isMutable();
213 const boolIsSecondMutable = SecondField->
isMutable();
214 if(IsFirstMutable != IsSecondMutable) {
215DiagError(FieldSingleMutable) << FirstII << IsFirstMutable;
216DiagNote(FieldSingleMutable) << SecondII << IsSecondMutable;
222 if((!FirstInitializer && SecondInitializer) ||
223(FirstInitializer && !SecondInitializer)) {
224DiagError(FieldSingleInitializer)
225<< FirstII << (FirstInitializer !=
nullptr);
226DiagNote(FieldSingleInitializer)
227<< SecondII << (SecondInitializer !=
nullptr);
231 if(FirstInitializer && SecondInitializer) {
234 if(FirstInitHash != SecondInitHash) {
235DiagError(FieldDifferentInitializers)
237DiagNote(FieldDifferentInitializers)
246boolODRDiagsEmitter::diagnoseSubMismatchTypedef(
247 const NamedDecl*FirstRecord, StringRef FirstModule, StringRef SecondModule,
249 boolIsTypeAlias)
const{
250 enumODRTypedefDifference {
255 autoDiagError = [FirstRecord, FirstTD, FirstModule,
256 this](ODRTypedefDifference DiffType) {
257 returnDiag(FirstTD->
getLocation(), diag::err_module_odr_violation_typedef)
258<< FirstRecord << FirstModule.empty() << FirstModule
261 autoDiagNote = [SecondTD, SecondModule,
262 this](ODRTypedefDifference DiffType) {
264diag::note_module_odr_violation_typedef)
270 if(FirstName != SecondName) {
271DiagError(TypedefName) << IsTypeAlias << FirstName;
272DiagNote(TypedefName) << IsTypeAlias << SecondName;
279DiagError(
TypedefType) << IsTypeAlias << FirstName << FirstType;
280DiagNote(
TypedefType) << IsTypeAlias << SecondName << SecondType;
286boolODRDiagsEmitter::diagnoseSubMismatchVar(
const NamedDecl*FirstRecord,
287StringRef FirstModule,
288StringRef SecondModule,
290 const VarDecl*SecondVD)
const{
291 enumODRVarDifference {
294VarSingleInitializer,
295VarDifferentInitializer,
299 autoDiagError = [FirstRecord, FirstVD, FirstModule,
300 this](ODRVarDifference DiffType) {
301 returnDiag(FirstVD->
getLocation(), diag::err_module_odr_violation_variable)
302<< FirstRecord << FirstModule.empty() << FirstModule
305 autoDiagNote = [SecondVD, SecondModule,
this](ODRVarDifference DiffType) {
307diag::note_module_odr_violation_variable)
313 if(FirstName != SecondName) {
314DiagError(VarName) << FirstName;
315DiagNote(VarName) << SecondName;
322DiagError(VarType) << FirstName << FirstType;
323DiagNote(VarType) << SecondName << SecondType;
327 if(!LangOpts.CPlusPlus)
332 if((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
333DiagError(VarSingleInitializer)
334<< FirstName << (FirstInit ==
nullptr)
335<< (FirstInit ? FirstInit->getSourceRange() :
SourceRange());
336DiagNote(VarSingleInitializer)
337<< SecondName << (SecondInit ==
nullptr)
338<< (SecondInit ? SecondInit->getSourceRange() :
SourceRange());
342 if(FirstInit && SecondInit &&
344DiagError(VarDifferentInitializer)
345<< FirstName << FirstInit->getSourceRange();
346DiagNote(VarDifferentInitializer)
347<< SecondName << SecondInit->getSourceRange();
351 const boolFirstIsConstexpr = FirstVD->
isConstexpr();
352 const boolSecondIsConstexpr = SecondVD->
isConstexpr();
353 if(FirstIsConstexpr != SecondIsConstexpr) {
354DiagError(VarConstexpr) << FirstName << FirstIsConstexpr;
355DiagNote(VarConstexpr) << SecondName << SecondIsConstexpr;
361boolODRDiagsEmitter::diagnoseSubMismatchProtocols(
367 enumODRReferencedProtocolDifference {
371 autoDiagRefProtocolError = [FirstContainer, FirstModule,
373ODRReferencedProtocolDifference DiffType) {
374 returnDiag(
Loc, diag::err_module_odr_violation_referenced_protocols)
375<< FirstContainer << FirstModule.empty() << FirstModule <<
Range 378 autoDiagRefProtocolNote = [SecondModule,
380ODRReferencedProtocolDifference DiffType) {
381 returnDiag(
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()) {
391DiagRefProtocolError(FirstContainer->
getLocation(),
392GetProtoListSourceRange(FirstProtocols), NumProtocols)
393<< FirstProtocols.
size();
394DiagRefProtocolNote(SecondContainer->
getLocation(),
395GetProtoListSourceRange(SecondProtocols), NumProtocols)
396<< SecondProtocols.
size();
400 for(
unsignedI = 0,
E= FirstProtocols.
size(); I !=
E; ++I) {
405 if(FirstProtocolName != SecondProtocolName) {
409DiagRefProtocolError(FirstLoc, EmptyRange, ProtocolType)
410<< (I + 1) << FirstProtocolName;
411DiagRefProtocolNote(SecondLoc, EmptyRange, ProtocolType)
412<< (I + 1) << SecondProtocolName;
420boolODRDiagsEmitter::diagnoseSubMismatchObjCMethod(
421 const NamedDecl*FirstObjCContainer, StringRef FirstModule,
424 enumODRMethodDifference {
428DesignatedInitializer,
433 autoDiagError = [FirstObjCContainer, FirstModule, FirstMethod,
434 this](ODRMethodDifference DiffType) {
436diag::err_module_odr_violation_objc_method)
437<< FirstObjCContainer << FirstModule.empty() << FirstModule
440 autoDiagNote = [SecondModule, SecondMethod,
441 this](ODRMethodDifference DiffType) {
442 returnDiag(SecondMethod->getLocation(),
443diag::note_module_odr_violation_objc_method)
444<< SecondModule.empty() << SecondModule
445<< SecondMethod->getSourceRange() << DiffType;
450DiagError(ReturnType) << FirstMethod << FirstMethod->
getReturnType();
451DiagNote(ReturnType) << SecondMethod << SecondMethod->getReturnType();
455 if(FirstMethod->
isInstanceMethod() != SecondMethod->isInstanceMethod()) {
456DiagError(InstanceOrClass)
458DiagNote(InstanceOrClass)
459<< SecondMethod << SecondMethod->isInstanceMethod();
463SecondMethod->getImplementationControl()) {
464DiagError(ControlLevel)
466DiagNote(ControlLevel) << llvm::to_underlying(
467SecondMethod->getImplementationControl());
471SecondMethod->isThisDeclarationADesignatedInitializer()) {
472DiagError(DesignatedInitializer)
475DiagNote(DesignatedInitializer)
477<< SecondMethod->isThisDeclarationADesignatedInitializer();
480 if(FirstMethod->
isDirectMethod() != SecondMethod->isDirectMethod()) {
481DiagError(Directness) << FirstMethod << FirstMethod->
isDirectMethod();
482DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();
486FirstModule, SecondModule,
487FirstMethod, SecondMethod))
495 if(FirstName != SecondName) {
496DiagError(Name) << FirstName;
497DiagNote(Name) << SecondName;
504boolODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
505 const NamedDecl*FirstObjCContainer, StringRef FirstModule,
508 enumODRPropertyDifference {
515 autoDiagError = [FirstObjCContainer, FirstModule, FirstProp,
517 returnDiag(
Loc, diag::err_module_odr_violation_objc_property)
518<< FirstObjCContainer << FirstModule.empty() << FirstModule
521 autoDiagNote = [SecondModule, SecondProp,
523 returnDiag(
Loc, diag::note_module_odr_violation_objc_property)
524<< SecondModule.empty() << SecondModule
525<< SecondProp->getSourceRange() << DiffType;
531DiagError(FirstProp->
getLocation(), Name) << FirstII;
532DiagNote(SecondProp->getLocation(), Name) << SecondII;
538<< FirstII << FirstProp->
getType();
539DiagNote(SecondProp->getLocation(),
Type)
540<< SecondII << SecondProp->getType();
544SecondProp->getPropertyImplementation()) {
545DiagError(FirstProp->
getLocation(), ControlLevel)
547DiagNote(SecondProp->getLocation(), ControlLevel)
548<< SecondProp->getPropertyImplementation();
554 unsignedSecondAttrs = (
unsigned)SecondProp->getPropertyAttributes();
555 if(FirstAttrs != SecondAttrs) {
557 unsignedCheckedAttr = (1 << I);
558 if((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))
561 boolIsFirstWritten =
563 boolIsSecondWritten =
564(
unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;
568<< FirstII << (I + 1) << IsFirstWritten;
569DiagNote(IsSecondWritten ? SecondProp->getLParenLoc()
570: SecondProp->getLocation(),
572<< SecondII << (I + 1);
580ODRDiagsEmitter::DiffResult
581ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,
582DeclHashes &SecondHashes) {
583 autoDifferenceSelector = [](
const Decl*
D) {
584assert(
D&&
"valid Decl required");
588 caseDecl::AccessSpec:
591 returnPublicSpecifer;
593 returnPrivateSpecifer;
595 returnProtectedSpecifer;
599llvm_unreachable(
"Invalid access specifier");
600 caseDecl::StaticAssert:
604 caseDecl::CXXMethod:
605 caseDecl::CXXConstructor:
606 caseDecl::CXXDestructor:
608 caseDecl::TypeAlias:
616 caseDecl::FunctionTemplate:
617 returnFunctionTemplate;
618 caseDecl::ObjCMethod:
622 caseDecl::ObjCProperty:
628 autoFirstIt = FirstHashes.begin();
629 autoSecondIt = SecondHashes.begin();
630 while(FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
631 if(FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
632FirstIt->second == SecondIt->second) {
638DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
639DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
642DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;
644DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;
650voidODRDiagsEmitter::diagnoseSubMismatchUnexpected(
651DiffResult &DR,
const NamedDecl*FirstRecord, StringRef FirstModule,
652 const NamedDecl*SecondRecord, StringRef SecondModule)
const{
654diag::err_module_odr_violation_different_definitions)
655<< FirstRecord << FirstModule.empty() << FirstModule;
658Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
663diag::note_module_odr_violation_different_definitions)
667Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
668<< DR.SecondDecl->getSourceRange();
672voidODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
673DiffResult &DR,
const NamedDecl*FirstRecord, StringRef FirstModule,
674 const NamedDecl*SecondRecord, StringRef SecondModule)
const{
675 autoGetMismatchedDeclLoc = [](
const NamedDecl*Container,
676ODRMismatchDecl 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();
690 returnstd::make_pair(
Loc,
Range);
694GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
695Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
696<< FirstRecord << FirstModule.empty() << FirstModule
697<< FirstDiagInfo.second << DR.FirstDiffType;
699 autoSecondDiagInfo =
700GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
701Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
702<< SecondModule.empty() << SecondModule << SecondDiagInfo.second
703<< DR.SecondDiffType;
708 const structCXXRecordDecl::DefinitionData *SecondDD)
const{
711 if(FirstRecord == SecondRecord)
717 const structCXXRecordDecl::DefinitionData *FirstDD =
718FirstRecord->DefinitionData;
719assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
722 if(FirstDD != SecondDD) {
724 enumODRDefinitionDataDifference {
731 autoDiagBaseError = [FirstRecord, &FirstModule,
733ODRDefinitionDataDifference DiffType) {
734 return Diag(
Loc, diag::err_module_odr_violation_definition_data)
735<< FirstRecord << FirstModule.empty() << FirstModule <<
Range 738 autoDiagBaseNote = [&SecondModule,
740ODRDefinitionDataDifference DiffType) {
741 return Diag(
Loc, diag::note_module_odr_violation_definition_data)
742<< SecondModule <<
Range<< DiffType;
744 autoGetSourceRange = [](
const structCXXRecordDecl::DefinitionData *DD) {
745 unsignedNumBases = DD->NumBases;
750bases[NumBases - 1].getEndLoc());
753 unsignedFirstNumBases = FirstDD->NumBases;
754 unsignedFirstNumVBases = FirstDD->NumVBases;
755 unsignedSecondNumBases = SecondDD->NumBases;
756 unsignedSecondNumVBases = SecondDD->NumVBases;
757 if(FirstNumBases != SecondNumBases) {
758DiagBaseError(FirstRecord->
getLocation(), GetSourceRange(FirstDD),
761DiagBaseNote(SecondRecord->
getLocation(), GetSourceRange(SecondDD),
767 if(FirstNumVBases != SecondNumVBases) {
768DiagBaseError(FirstRecord->
getLocation(), GetSourceRange(FirstDD),
771DiagBaseNote(SecondRecord->
getLocation(), GetSourceRange(SecondDD),
779 for(
unsignedI = 0; I < FirstNumBases; ++I) {
786<< (I + 1) << FirstBase.
getType();
789<< (I + 1) << SecondBase.
getType();
807<< (I + 1) << FirstBase.
getType()
811<< (I + 1) << SecondBase.
getType()
823assert(!FirstTemplate == !SecondTemplate &&
824 "Both pointers should be null or non-null");
826 if(FirstTemplate && SecondTemplate) {
831assert(FirstTemplateParams.size() == SecondTemplateParams.size() &&
832 "Number of template parameters should be equal.");
833 for(
autoPair : 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 enumODRTemplateDifference {
845ParamSingleDefaultArgument,
846ParamDifferentDefaultArgument,
849 autohasDefaultArg = [](
const NamedDecl*
D) {
850 if(
auto*TTP = dyn_cast<TemplateTypeParmDecl>(
D))
851 returnTTP->hasDefaultArgument() &&
852!TTP->defaultArgumentWasInherited();
853 if(
auto*NTTP = dyn_cast<NonTypeTemplateParmDecl>(
D))
854 returnNTTP->hasDefaultArgument() &&
855!NTTP->defaultArgumentWasInherited();
856 auto*TTP = cast<TemplateTemplateParmDecl>(
D);
857 returnTTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();
859 boolhasFirstArg = hasDefaultArg(FirstDecl);
860 boolhasSecondArg = hasDefaultArg(SecondDecl);
862ODRTemplateDifference ErrDiffType;
863ODRTemplateDifference NoteDiffType;
868 if(FirstName != SecondName) {
869 boolFirstNameEmpty =
871 boolSecondNameEmpty =
873ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;
874NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;
875}
else if(hasFirstArg == hasSecondArg)
876ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
878ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
881diag::err_module_odr_violation_template_parameter)
882<< FirstRecord << FirstModule.empty() << FirstModule
886diag::note_module_odr_violation_template_parameter)
888<< hasSecondArg << SecondName;
905PopulateHashes(FirstHashes, FirstRecord, DC);
906PopulateHashes(SecondHashes, SecondRecord, DC);
908DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
909ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
910ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
911 const Decl*FirstDecl = DR.FirstDecl;
912 const Decl*SecondDecl = DR.SecondDecl;
914 if(FirstDiffType ==
Other|| SecondDiffType ==
Other) {
915diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
920 if(FirstDiffType != SecondDiffType) {
921diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
922SecondRecord, SecondModule);
928 enumODRCXXRecordDifference {
929StaticAssertCondition,
931StaticAssertOnlyMessage,
940MethodParameterSingleDefaultArgument,
941MethodParameterDifferentDefaultArgument,
942MethodNoTemplateArguments,
943MethodDifferentNumberTemplateArguments,
944MethodDifferentTemplateArgument,
950FunctionTemplateDifferentNumberParameters,
951FunctionTemplateParameterDifferentKind,
952FunctionTemplateParameterName,
953FunctionTemplateParameterSingleDefaultArgument,
954FunctionTemplateParameterDifferentDefaultArgument,
955FunctionTemplateParameterDifferentType,
956FunctionTemplatePackParameter,
958 autoDiagError = [FirstRecord, &FirstModule,
960ODRCXXRecordDifference DiffType) {
961 return Diag(
Loc, diag::err_module_odr_violation_record)
962<< FirstRecord << FirstModule.empty() << FirstModule <<
Range 966ODRCXXRecordDifference DiffType) {
967 return Diag(
Loc, diag::note_module_odr_violation_record)
968<< SecondModule <<
Range<< DiffType;
971assert(FirstDiffType == SecondDiffType);
972 switch(FirstDiffType) {
976 casePrivateSpecifer:
977 caseProtectedSpecifer:
981llvm_unreachable(
"Invalid diff type");
991 if(FirstODRHash != SecondODRHash) {
993StaticAssertCondition);
995StaticAssertCondition);
1001assert((FirstMessage || SecondMessage) &&
"Both messages cannot be empty");
1002 if((FirstMessage && !SecondMessage) || (!FirstMessage && SecondMessage)) {
1012 if(SecondMessage) {
1019DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
1020<< (FirstMessage ==
nullptr);
1021DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
1022<< (SecondMessage ==
nullptr);
1026 if(FirstMessage && SecondMessage) {
1029 if(FirstMessageODRHash != SecondMessageODRHash) {
1031StaticAssertMessage);
1033StaticAssertMessage);
1041 if(diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1042cast<FieldDecl>(FirstDecl),
1043cast<FieldDecl>(SecondDecl)))
1055 autoGetMethodTypeForDiagnostics = [](
const CXXMethodDecl*
D) {
1056 if(isa<CXXConstructorDecl>(
D))
1057 returnDiagConstructor;
1058 if(isa<CXXDestructorDecl>(
D))
1059 returnDiagDestructor;
1062 const CXXMethodDecl*FirstMethod = cast<CXXMethodDecl>(FirstDecl);
1063 const CXXMethodDecl*SecondMethod = cast<CXXMethodDecl>(SecondDecl);
1064FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
1065SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
1068 autoDiagMethodError = [&DiagError, FirstMethod, FirstMethodType,
1069FirstName](ODRCXXRecordDifference DiffType) {
1072<< FirstMethodType << FirstName;
1074 autoDiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,
1075SecondName](ODRCXXRecordDifference DiffType) {
1078<< SecondMethodType << SecondName;
1081 if(FirstMethodType != SecondMethodType || FirstName != SecondName) {
1082DiagMethodError(MethodName);
1083DiagMethodNote(MethodName);
1089 if(FirstDeleted != SecondDeleted) {
1090DiagMethodError(MethodDeleted) << FirstDeleted;
1091DiagMethodNote(MethodDeleted) << SecondDeleted;
1097 if(FirstDefaulted != SecondDefaulted) {
1098DiagMethodError(MethodDefaulted) << FirstDefaulted;
1099DiagMethodNote(MethodDefaulted) << SecondDefaulted;
1107 if((FirstVirtual || SecondVirtual) &&
1108(FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
1109DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
1110DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
1119 const boolFirstStatic = FirstStorage ==
SC_Static;
1120 const boolSecondStatic = SecondStorage ==
SC_Static;
1121 if(FirstStatic != SecondStatic) {
1122DiagMethodError(MethodStatic) << FirstStatic;
1123DiagMethodNote(MethodStatic) << SecondStatic;
1127 const boolFirstVolatile = FirstMethod->
isVolatile();
1128 const boolSecondVolatile = SecondMethod->
isVolatile();
1129 if(FirstVolatile != SecondVolatile) {
1130DiagMethodError(MethodVolatile) << FirstVolatile;
1131DiagMethodNote(MethodVolatile) << SecondVolatile;
1135 const boolFirstConst = FirstMethod->
isConst();
1136 const boolSecondConst = SecondMethod->
isConst();
1137 if(FirstConst != SecondConst) {
1138DiagMethodError(MethodConst) << FirstConst;
1139DiagMethodNote(MethodConst) << SecondConst;
1145 if(FirstInline != SecondInline) {
1146DiagMethodError(MethodInline) << FirstInline;
1147DiagMethodNote(MethodInline) << SecondInline;
1152FirstModule, SecondModule,
1153FirstMethod, SecondMethod))
1156 for(
unsignedI = 0, N = FirstMethod->
param_size(); I < N; ++I) {
1161 const Expr*SecondInit = SecondParam->
getInit();
1162 if((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
1163DiagMethodError(MethodParameterSingleDefaultArgument)
1164<< (I + 1) << (FirstInit ==
nullptr)
1166DiagMethodNote(MethodParameterSingleDefaultArgument)
1167<< (I + 1) << (SecondInit ==
nullptr)
1172 if(FirstInit && SecondInit &&
1174DiagMethodError(MethodParameterDifferentDefaultArgument)
1176DiagMethodNote(MethodParameterDifferentDefaultArgument)
1187 if((FirstTemplateArgs && !SecondTemplateArgs) ||
1188(!FirstTemplateArgs && SecondTemplateArgs)) {
1189DiagMethodError(MethodNoTemplateArguments)
1190<< (FirstTemplateArgs !=
nullptr);
1191DiagMethodNote(MethodNoTemplateArguments)
1192<< (SecondTemplateArgs !=
nullptr);
1196 if(FirstTemplateArgs && SecondTemplateArgs) {
1202ExpandedList.push_back(&TA);
1205llvm::append_range(ExpandedList,
1206llvm::make_pointer_range(TA.getPackAsArray()));
1208 returnExpandedList;
1211ExpandTemplateArgumentList(FirstTemplateArgs);
1213ExpandTemplateArgumentList(SecondTemplateArgs);
1215 if(FirstExpandedList.size() != SecondExpandedList.size()) {
1216DiagMethodError(MethodDifferentNumberTemplateArguments)
1217<< (
unsigned)FirstExpandedList.size();
1218DiagMethodNote(MethodDifferentNumberTemplateArguments)
1219<< (
unsigned)SecondExpandedList.size();
1223 for(
unsignedi = 0, e = FirstExpandedList.size(); i != e; ++i) {
1225&SecondTA = *SecondExpandedList[i];
1229DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;
1230DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;
1245 const boolHasFirstBody =
1246ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->
getODRHash();
1247 const boolHasSecondBody =
1248ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->
getODRHash();
1250 if(HasFirstBody != HasSecondBody) {
1251DiagMethodError(MethodSingleBody) << HasFirstBody;
1252DiagMethodNote(MethodSingleBody) << HasSecondBody;
1256 if(HasFirstBody && HasSecondBody) {
1257DiagMethodError(MethodDifferentBody);
1258DiagMethodNote(MethodDifferentBody);
1267 if(diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1268cast<TypedefNameDecl>(FirstDecl),
1269cast<TypedefNameDecl>(SecondDecl),
1270FirstDiffType == TypeAlias))
1275 if(diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1276cast<VarDecl>(FirstDecl),
1277cast<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 caseFunctionTemplate: {
1325cast<FunctionTemplateDecl>(FirstDecl);
1327cast<FunctionTemplateDecl>(SecondDecl);
1332 autoDiagTemplateError = [&DiagError,
1333FirstTemplate](ODRCXXRecordDifference DiffType) {
1338 autoDiagTemplateNote = [&DiagNote,
1339SecondTemplate](ODRCXXRecordDifference DiffType) {
1345 if(FirstTPL->
size() != SecondTPL->
size()) {
1346DiagTemplateError(FunctionTemplateDifferentNumberParameters)
1347<< FirstTPL->
size();
1348DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
1349<< SecondTPL->
size();
1353 for(
unsignedi = 0, e = FirstTPL->
size(); i != e; ++i) {
1359TemplateTypeParameter,
1360NonTypeTemplateParameter,
1361TemplateTemplateParameter,
1366llvm_unreachable(
"Unexpected template parameter type");
1367 caseDecl::TemplateTypeParm:
1368 returnTemplateTypeParameter;
1369 caseDecl::NonTypeTemplateParm:
1370 returnNonTypeTemplateParameter;
1371 caseDecl::TemplateTemplateParm:
1372 returnTemplateTemplateParameter;
1376DiagTemplateError(FunctionTemplateParameterDifferentKind)
1377<< (i + 1) << GetParamType(FirstParam);
1378DiagTemplateNote(FunctionTemplateParameterDifferentKind)
1379<< (i + 1) << GetParamType(SecondParam);
1384DiagTemplateError(FunctionTemplateParameterName)
1385<< (i + 1) << (
bool)FirstParam->
getIdentifier() << FirstParam;
1386DiagTemplateNote(FunctionTemplateParameterName)
1387<< (i + 1) << (
bool)SecondParam->
getIdentifier() << SecondParam;
1391 if(isa<TemplateTypeParmDecl>(FirstParam) &&
1392isa<TemplateTypeParmDecl>(SecondParam)) {
1394cast<TemplateTypeParmDecl>(FirstParam);
1396cast<TemplateTypeParmDecl>(SecondParam);
1397 boolHasFirstDefaultArgument =
1400 boolHasSecondDefaultArgument =
1403 if(HasFirstDefaultArgument != HasSecondDefaultArgument) {
1404DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1405<< (i + 1) << HasFirstDefaultArgument;
1406DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1407<< (i + 1) << HasSecondDefaultArgument;
1411 if(HasFirstDefaultArgument && HasSecondDefaultArgument) {
1417DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1418<< (i + 1) << FirstTA;
1419DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1420<< (i + 1) << SecondTA;
1426DiagTemplateError(FunctionTemplatePackParameter)
1428DiagTemplateNote(FunctionTemplatePackParameter)
1434 if(isa<TemplateTemplateParmDecl>(FirstParam) &&
1435isa<TemplateTemplateParmDecl>(SecondParam)) {
1437cast<TemplateTemplateParmDecl>(FirstParam);
1439cast<TemplateTemplateParmDecl>(SecondParam);
1444 autoComputeTemplateParameterListODRHash =
1452 if(ComputeTemplateParameterListODRHash(FirstTPL) !=
1453ComputeTemplateParameterListODRHash(SecondTPL)) {
1454DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1455DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1459 boolHasFirstDefaultArgument =
1462 boolHasSecondDefaultArgument =
1465 if(HasFirstDefaultArgument != HasSecondDefaultArgument) {
1466DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1467<< (i + 1) << HasFirstDefaultArgument;
1468DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1469<< (i + 1) << HasSecondDefaultArgument;
1473 if(HasFirstDefaultArgument && HasSecondDefaultArgument) {
1479DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1480<< (i + 1) << FirstTA;
1481DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1482<< (i + 1) << SecondTA;
1488DiagTemplateError(FunctionTemplatePackParameter)
1490DiagTemplateNote(FunctionTemplatePackParameter)
1496 if(isa<NonTypeTemplateParmDecl>(FirstParam) &&
1497isa<NonTypeTemplateParmDecl>(SecondParam)) {
1499cast<NonTypeTemplateParmDecl>(FirstParam);
1501cast<NonTypeTemplateParmDecl>(SecondParam);
1506DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1507DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1511 boolHasFirstDefaultArgument =
1514 boolHasSecondDefaultArgument =
1517 if(HasFirstDefaultArgument != HasSecondDefaultArgument) {
1518DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1519<< (i + 1) << HasFirstDefaultArgument;
1520DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1521<< (i + 1) << HasSecondDefaultArgument;
1525 if(HasFirstDefaultArgument && HasSecondDefaultArgument) {
1533DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1534<< (i + 1) << FirstDefaultArgument;
1535DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1536<< (i + 1) << SecondDefaultArgument;
1542DiagTemplateError(FunctionTemplatePackParameter)
1544DiagTemplateNote(FunctionTemplatePackParameter)
1555diag::err_module_odr_violation_mismatch_decl_unknown)
1556<< FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1559diag::note_module_odr_violation_mismatch_decl_unknown)
1560<< SecondModule.empty() << SecondModule << FirstDiffType
1567 if(FirstRecord == SecondRecord)
1585PopulateHashes(FirstHashes, FirstRecord, DC);
1586PopulateHashes(SecondHashes, SecondRecord, DC);
1588DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1589ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1590ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1591 const Decl*FirstDecl = DR.FirstDecl;
1592 const Decl*SecondDecl = DR.SecondDecl;
1594 if(FirstDiffType ==
Other|| SecondDiffType ==
Other) {
1595diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1600 if(FirstDiffType != SecondDiffType) {
1601diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1602SecondRecord, SecondModule);
1606assert(FirstDiffType == SecondDiffType);
1607 switch(FirstDiffType) {
1612 casePublicSpecifer:
1613 casePrivateSpecifer:
1614 caseProtectedSpecifer:
1619 caseFunctionTemplate:
1624llvm_unreachable(
"Invalid diff type");
1627 if(diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1628cast<FieldDecl>(FirstDecl),
1629cast<FieldDecl>(SecondDecl)))
1634 if(diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1635cast<TypedefNameDecl>(FirstDecl),
1636cast<TypedefNameDecl>(SecondDecl),
1642 if(diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1643cast<VarDecl>(FirstDecl),
1644cast<VarDecl>(SecondDecl)))
1651diag::err_module_odr_violation_mismatch_decl_unknown)
1652<< FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1655diag::note_module_odr_violation_mismatch_decl_unknown)
1656<< SecondModule.empty() << SecondModule << FirstDiffType
1664 if(FirstFunction == SecondFunction)
1668 enumODRFunctionDifference {
1672ParameterSingleDefaultArgument,
1673ParameterDifferentDefaultArgument,
1680 autoDiagError = [FirstFunction, &FirstModule,
1682ODRFunctionDifference DiffType) {
1683 return Diag(
Loc, diag::err_module_odr_violation_function)
1684<< FirstFunction << FirstModule.empty() << FirstModule <<
Range 1688ODRFunctionDifference 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_tParamSize = FirstFunction->
param_size();
1708 for(
unsignedI = 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;
1757 const Expr*SecondInit = SecondParam->
getInit();
1758 if((FirstInit ==
nullptr) != (SecondInit ==
nullptr)) {
1760ParameterSingleDefaultArgument)
1761<< (I + 1) << (FirstInit ==
nullptr)
1764ParameterSingleDefaultArgument)
1765<< (I + 1) << (SecondInit ==
nullptr)
1770 if(FirstInit && SecondInit &&
1773ParameterDifferentDefaultArgument)
1776ParameterDifferentDefaultArgument)
1782 "Undiagnosed parameter difference.");
1795 const EnumDecl*SecondEnum)
const{
1796 if(FirstEnum == SecondEnum)
1800 enumODREnumDifference {
1802EnumTagKeywordMismatch,
1803SingleSpecifiedType,
1804DifferentSpecifiedTypes,
1805DifferentNumberEnumConstants,
1807EnumConstantSingleInitializer,
1808EnumConstantDifferentInitializer,
1814 autoDiagError = [FirstEnum, &FirstModule,
this](
const auto*DiagAnchor,
1815ODREnumDifference DiffType) {
1816 return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1817<< FirstEnum << FirstModule.empty() << FirstModule
1820 autoDiagNote = [&SecondModule,
this](
const auto*DiagAnchor,
1821ODREnumDifference DiffType) {
1822 return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1823<< SecondModule << DiagAnchor->getSourceRange() << DiffType;
1827DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->
isScoped();
1828DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->
isScoped();
1835DiagError(FirstEnum, EnumTagKeywordMismatch)
1837DiagNote(SecondEnum, EnumTagKeywordMismatch)
1851 if(FirstUnderlyingType.
isNull() != SecondUnderlyingType.
isNull()) {
1852DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.
isNull();
1853DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.
isNull();
1857 if(!FirstUnderlyingType.
isNull() && !SecondUnderlyingType.
isNull()) {
1860DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1861DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1870 for(
const Decl*
D:
Enum->decls()) {
1875assert(isa<EnumConstantDecl>(
D) &&
"Unexpected Decl kind");
1880PopulateHashes(FirstHashes, FirstEnum);
1882PopulateHashes(SecondHashes, SecondEnum);
1884 if(FirstHashes.size() != SecondHashes.size()) {
1885DiagError(FirstEnum, DifferentNumberEnumConstants)
1886<< (
int)FirstHashes.size();
1887DiagNote(SecondEnum, DifferentNumberEnumConstants)
1888<< (
int)SecondHashes.size();
1892 for(
unsignedI = 0, N = FirstHashes.size(); I < N; ++I) {
1893 if(FirstHashes[I].second == SecondHashes[I].second)
1899DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1900DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1906 if(!FirstInit && !SecondInit)
1909 if(!FirstInit || !SecondInit) {
1910DiagError(FirstConstant, EnumConstantSingleInitializer)
1911<< I + 1 << FirstConstant << (FirstInit !=
nullptr);
1912DiagNote(SecondConstant, EnumConstantSingleInitializer)
1913<< I + 1 << SecondConstant << (SecondInit !=
nullptr);
1918DiagError(FirstConstant, EnumConstantDifferentInitializer)
1919<< I + 1 << FirstConstant;
1920DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1921<< I + 1 << SecondConstant;
1930 const structObjCInterfaceDecl::DefinitionData *SecondDD)
const{
1933 if(FirstID == SecondID)
1940 enumODRInterfaceDifference {
1945 autoDiagError = [FirstID, &FirstModule,
1947ODRInterfaceDifference DiffType) {
1948 return Diag(
Loc, diag::err_module_odr_violation_objc_interface)
1949<< FirstID << FirstModule.empty() << FirstModule <<
Range 1953ODRInterfaceDifference DiffType) {
1954 return Diag(
Loc, diag::note_module_odr_violation_objc_interface)
1955<< SecondModule.empty() << SecondModule <<
Range<< DiffType;
1958 const structObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1959assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
1960 if(FirstDD != SecondDD) {
1962 autoGetSuperClassSourceRange = [](
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)) {
1984FirstType = FirstSuperInfo->
getType();
1987GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1989<< (
bool)FirstSuperInfo << FirstType;
1992 if(SecondSuperInfo)
1993SecondType = SecondSuperInfo->
getType();
1996GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1998<< (
bool)SecondSuperInfo << SecondType;
2004 auto&SecondProtos = SecondDD->ReferencedProtocols;
2005 if(diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
2006SecondProtos, SecondID, SecondModule))
2012 for(
auto*
D:
ID->decls()) {
2023PopulateHashes(FirstHashes, FirstID, FirstID->
getDefinition());
2024PopulateHashes(SecondHashes, SecondID, SecondID->
getDefinition());
2026DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2027ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2028ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2029 const Decl*FirstDecl = DR.FirstDecl;
2030 const Decl*SecondDecl = DR.SecondDecl;
2032 if(FirstDiffType ==
Other|| SecondDiffType ==
Other) {
2033diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2038 if(FirstDiffType != SecondDiffType) {
2039diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2044assert(FirstDiffType == SecondDiffType);
2045 switch(FirstDiffType) {
2054 casePublicSpecifer:
2055 casePrivateSpecifer:
2056 caseProtectedSpecifer:
2061 caseFunctionTemplate:
2062llvm_unreachable(
"Invalid diff type");
2065 if(diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2066cast<ObjCMethodDecl>(FirstDecl),
2067cast<ObjCMethodDecl>(SecondDecl)))
2072 if(diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2073cast<FieldDecl>(FirstDecl),
2074cast<FieldDecl>(SecondDecl)))
2078 const ObjCIvarDecl*FirstIvar = cast<ObjCIvarDecl>(FirstDecl);
2079 const ObjCIvarDecl*SecondIvar = cast<ObjCIvarDecl>(SecondDecl);
2094 caseObjCProperty: {
2095 if(diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2096cast<ObjCPropertyDecl>(FirstDecl),
2097cast<ObjCPropertyDecl>(SecondDecl)))
2104diag::err_module_odr_violation_mismatch_decl_unknown)
2105<< FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2108diag::note_module_odr_violation_mismatch_decl_unknown)
2109<< SecondModule.empty() << SecondModule << FirstDiffType
2117 const structObjCProtocolDecl::DefinitionData *SecondDD)
const{
2118 if(FirstProtocol == SecondProtocol)
2124 constObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2125assert(FirstDD && SecondDD &&
"Definitions without DefinitionData");
2127 if(FirstDD != SecondDD) {
2132 if(diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2133SecondProtocols, SecondProtocol,
2140 for(
const Decl*
D:
ID->decls()) {
2151PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->
getDefinition());
2152PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->
getDefinition());
2154DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2155ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2156ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2157 const Decl*FirstDecl = DR.FirstDecl;
2158 const Decl*SecondDecl = DR.SecondDecl;
2160 if(FirstDiffType ==
Other|| SecondDiffType ==
Other) {
2161diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2162SecondProtocol, SecondModule);
2166 if(FirstDiffType != SecondDiffType) {
2167diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2168SecondProtocol, SecondModule);
2172assert(FirstDiffType == SecondDiffType);
2173 switch(FirstDiffType) {
2183 casePublicSpecifer:
2184 casePrivateSpecifer:
2185 caseProtectedSpecifer:
2190 caseFunctionTemplate:
2191llvm_unreachable(
"Invalid diff type");
2193 if(diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2194cast<ObjCMethodDecl>(FirstDecl),
2195cast<ObjCMethodDecl>(SecondDecl)))
2199 caseObjCProperty: {
2200 if(diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2202cast<ObjCPropertyDecl>(FirstDecl),
2203cast<ObjCPropertyDecl>(SecondDecl)))
2210diag::err_module_odr_violation_mismatch_decl_unknown)
2211<< FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2214diag::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.
@ NumObjCPropertyAttrsBits
Number of bits fitting all the property attributes.
StorageClass
Storage classes.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4