1 //===-- ODRDiagsEmitter.cpp - Diagnostics for ODR mismatches ----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "clang/AST/ODRDiagsEmitter.h" 10 #include "clang/AST/DeclFriend.h" 11 #include "clang/AST/DeclTemplate.h" 12 #include "clang/AST/ODRHash.h" 13 #include "clang/Basic/DiagnosticAST.h" 14 #include "clang/Basic/Module.h" 15 16 using namespace clang; 17 18 static unsigned computeODRHash(QualType Ty) { 19 ODRHash Hasher; 20 Hasher.AddQualType(Ty); 21 return Hasher.CalculateHash(); 22 } 23 24 static unsigned computeODRHash(const Stmt *S) { 25 ODRHash Hasher; 26 Hasher.AddStmt(S); 27 return Hasher.CalculateHash(); 28 } 29 30 static unsigned computeODRHash(const Decl *D) { 31 assert(D); 32 ODRHash Hasher; 33 Hasher.AddSubDecl(D); 34 return Hasher.CalculateHash(); 35 } 36 37 static unsigned computeODRHash(const TemplateArgument &TA) { 38 ODRHash Hasher; 39 Hasher.AddTemplateArgument(TA); 40 return Hasher.CalculateHash(); 41 } 42 43 std::string ODRDiagsEmitter::getOwningModuleNameForDiagnostic(const Decl *D) { 44 // If we know the owning module, use it. 45 if (Module *M = D->getImportedOwningModule()) 46 return M->getFullModuleName(); 47 48 // Not from a module. 49 return {}; 50 } 51 52 template <typename MethodT> 53 static bool diagnoseSubMismatchMethodParameters(DiagnosticsEngine &Diags, 54 const NamedDecl *FirstContainer, 55 StringRef FirstModule, 56 StringRef SecondModule, 57 const MethodT *FirstMethod, 58 const MethodT *SecondMethod) { 59 enum DiagMethodType { 60 DiagMethod, 61 DiagConstructor, 62 DiagDestructor, 63 }; 64 auto GetDiagMethodType = [](const NamedDecl *D) { 65 if (isa<CXXConstructorDecl>(D)) 66 return DiagConstructor; 67 if (isa<CXXDestructorDecl>(D)) 68 return DiagDestructor; 69 return DiagMethod; 70 }; 71 72 enum ODRMethodParametersDifference { 73 NumberParameters, 74 ParameterType, 75 ParameterName, 76 }; 77 auto DiagError = [&Diags, &GetDiagMethodType, FirstContainer, FirstModule, 78 FirstMethod](ODRMethodParametersDifference DiffType) { 79 DeclarationName FirstName = FirstMethod->getDeclName(); 80 DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod); 81 return Diags.Report(FirstMethod->getLocation(), 82 diag::err_module_odr_violation_method_params) 83 << FirstContainer << FirstModule.empty() << FirstModule 84 << FirstMethod->getSourceRange() << DiffType << FirstMethodType 85 << FirstName; 86 }; 87 auto DiagNote = [&Diags, &GetDiagMethodType, SecondModule, 88 SecondMethod](ODRMethodParametersDifference DiffType) { 89 DeclarationName SecondName = SecondMethod->getDeclName(); 90 DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod); 91 return Diags.Report(SecondMethod->getLocation(), 92 diag::note_module_odr_violation_method_params) 93 << SecondModule.empty() << SecondModule 94 << SecondMethod->getSourceRange() << DiffType << SecondMethodType 95 << SecondName; 96 }; 97 98 const unsigned FirstNumParameters = FirstMethod->param_size(); 99 const unsigned SecondNumParameters = SecondMethod->param_size(); 100 if (FirstNumParameters != SecondNumParameters) { 101 DiagError(NumberParameters) << FirstNumParameters; 102 DiagNote(NumberParameters) << SecondNumParameters; 103 return true; 104 } 105 106 for (unsigned I = 0; I < FirstNumParameters; ++I) { 107 const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I); 108 const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I); 109 110 QualType FirstParamType = FirstParam->getType(); 111 QualType SecondParamType = SecondParam->getType(); 112 if (FirstParamType != SecondParamType && 113 computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) { 114 if (const DecayedType *ParamDecayedType = 115 FirstParamType->getAs<DecayedType>()) { 116 DiagError(ParameterType) << (I + 1) << FirstParamType << true 117 << ParamDecayedType->getOriginalType(); 118 } else { 119 DiagError(ParameterType) << (I + 1) << FirstParamType << false; 120 } 121 122 if (const DecayedType *ParamDecayedType = 123 SecondParamType->getAs<DecayedType>()) { 124 DiagNote(ParameterType) << (I + 1) << SecondParamType << true 125 << ParamDecayedType->getOriginalType(); 126 } else { 127 DiagNote(ParameterType) << (I + 1) << SecondParamType << false; 128 } 129 return true; 130 } 131 132 DeclarationName FirstParamName = FirstParam->getDeclName(); 133 DeclarationName SecondParamName = SecondParam->getDeclName(); 134 if (FirstParamName != SecondParamName) { 135 DiagError(ParameterName) << (I + 1) << FirstParamName; 136 DiagNote(ParameterName) << (I + 1) << SecondParamName; 137 return true; 138 } 139 } 140 141 return false; 142 } 143 144 bool ODRDiagsEmitter::diagnoseSubMismatchField( 145 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule, 146 const FieldDecl *FirstField, const FieldDecl *SecondField) const { 147 enum ODRFieldDifference { 148 FieldName, 149 FieldTypeName, 150 FieldSingleBitField, 151 FieldDifferentWidthBitField, 152 FieldSingleMutable, 153 FieldSingleInitializer, 154 FieldDifferentInitializers, 155 }; 156 157 auto DiagError = [FirstRecord, FirstField, FirstModule, 158 this](ODRFieldDifference DiffType) { 159 return Diag(FirstField->getLocation(), diag::err_module_odr_violation_field) 160 << FirstRecord << FirstModule.empty() << FirstModule 161 << FirstField->getSourceRange() << DiffType; 162 }; 163 auto DiagNote = [SecondField, SecondModule, 164 this](ODRFieldDifference DiffType) { 165 return Diag(SecondField->getLocation(), 166 diag::note_module_odr_violation_field) 167 << SecondModule.empty() << SecondModule << SecondField->getSourceRange() << DiffType; 168 }; 169 170 IdentifierInfo *FirstII = FirstField->getIdentifier(); 171 IdentifierInfo *SecondII = SecondField->getIdentifier(); 172 if (FirstII->getName() != SecondII->getName()) { 173 DiagError(FieldName) << FirstII; 174 DiagNote(FieldName) << SecondII; 175 return true; 176 } 177 178 QualType FirstType = FirstField->getType(); 179 QualType SecondType = SecondField->getType(); 180 if (computeODRHash(FirstType) != computeODRHash(SecondType)) { 181 DiagError(FieldTypeName) << FirstII << FirstType; 182 DiagNote(FieldTypeName) << SecondII << SecondType; 183 return true; 184 } 185 186 assert(Context.hasSameType(FirstField->getType(), SecondField->getType())); 187 (void)Context; 188 189 const bool IsFirstBitField = FirstField->isBitField(); 190 const bool IsSecondBitField = SecondField->isBitField(); 191 if (IsFirstBitField != IsSecondBitField) { 192 DiagError(FieldSingleBitField) << FirstII << IsFirstBitField; 193 DiagNote(FieldSingleBitField) << SecondII << IsSecondBitField; 194 return true; 195 } 196 197 if (IsFirstBitField && IsSecondBitField) { 198 unsigned FirstBitWidthHash = computeODRHash(FirstField->getBitWidth()); 199 unsigned SecondBitWidthHash = computeODRHash(SecondField->getBitWidth()); 200 if (FirstBitWidthHash != SecondBitWidthHash) { 201 DiagError(FieldDifferentWidthBitField) 202 << FirstII << FirstField->getBitWidth()->getSourceRange(); 203 DiagNote(FieldDifferentWidthBitField) 204 << SecondII << SecondField->getBitWidth()->getSourceRange(); 205 return true; 206 } 207 } 208 209 if (!LangOpts.CPlusPlus) 210 return false; 211 212 const bool IsFirstMutable = FirstField->isMutable(); 213 const bool IsSecondMutable = SecondField->isMutable(); 214 if (IsFirstMutable != IsSecondMutable) { 215 DiagError(FieldSingleMutable) << FirstII << IsFirstMutable; 216 DiagNote(FieldSingleMutable) << SecondII << IsSecondMutable; 217 return true; 218 } 219 220 const Expr *FirstInitializer = FirstField->getInClassInitializer(); 221 const Expr *SecondInitializer = SecondField->getInClassInitializer(); 222 if ((!FirstInitializer && SecondInitializer) || 223 (FirstInitializer && !SecondInitializer)) { 224 DiagError(FieldSingleInitializer) 225 << FirstII << (FirstInitializer != nullptr); 226 DiagNote(FieldSingleInitializer) 227 << SecondII << (SecondInitializer != nullptr); 228 return true; 229 } 230 231 if (FirstInitializer && SecondInitializer) { 232 unsigned FirstInitHash = computeODRHash(FirstInitializer); 233 unsigned SecondInitHash = computeODRHash(SecondInitializer); 234 if (FirstInitHash != SecondInitHash) { 235 DiagError(FieldDifferentInitializers) 236 << FirstII << FirstInitializer->getSourceRange(); 237 DiagNote(FieldDifferentInitializers) 238 << SecondII << SecondInitializer->getSourceRange(); 239 return true; 240 } 241 } 242 243 return false; 244 } 245 246 bool ODRDiagsEmitter::diagnoseSubMismatchTypedef( 247 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule, 248 const TypedefNameDecl *FirstTD, const TypedefNameDecl *SecondTD, 249 bool IsTypeAlias) const { 250 enum ODRTypedefDifference { 251 TypedefName, 252 TypedefType, 253 }; 254 255 auto DiagError = [FirstRecord, FirstTD, FirstModule, 256 this](ODRTypedefDifference DiffType) { 257 return Diag(FirstTD->getLocation(), diag::err_module_odr_violation_typedef) 258 << FirstRecord << FirstModule.empty() << FirstModule 259 << FirstTD->getSourceRange() << DiffType; 260 }; 261 auto DiagNote = [SecondTD, SecondModule, 262 this](ODRTypedefDifference DiffType) { 263 return Diag(SecondTD->getLocation(), 264 diag::note_module_odr_violation_typedef) 265 << SecondModule << SecondTD->getSourceRange() << DiffType; 266 }; 267 268 DeclarationName FirstName = FirstTD->getDeclName(); 269 DeclarationName SecondName = SecondTD->getDeclName(); 270 if (FirstName != SecondName) { 271 DiagError(TypedefName) << IsTypeAlias << FirstName; 272 DiagNote(TypedefName) << IsTypeAlias << SecondName; 273 return true; 274 } 275 276 QualType FirstType = FirstTD->getUnderlyingType(); 277 QualType SecondType = SecondTD->getUnderlyingType(); 278 if (computeODRHash(FirstType) != computeODRHash(SecondType)) { 279 DiagError(TypedefType) << IsTypeAlias << FirstName << FirstType; 280 DiagNote(TypedefType) << IsTypeAlias << SecondName << SecondType; 281 return true; 282 } 283 return false; 284 } 285 286 bool ODRDiagsEmitter::diagnoseSubMismatchVar(const NamedDecl *FirstRecord, 287 StringRef FirstModule, 288 StringRef SecondModule, 289 const VarDecl *FirstVD, 290 const VarDecl *SecondVD) const { 291 enum ODRVarDifference { 292 VarName, 293 VarType, 294 VarSingleInitializer, 295 VarDifferentInitializer, 296 VarConstexpr, 297 }; 298 299 auto DiagError = [FirstRecord, FirstVD, FirstModule, 300 this](ODRVarDifference DiffType) { 301 return Diag(FirstVD->getLocation(), diag::err_module_odr_violation_variable) 302 << FirstRecord << FirstModule.empty() << FirstModule 303 << FirstVD->getSourceRange() << DiffType; 304 }; 305 auto DiagNote = [SecondVD, SecondModule, this](ODRVarDifference DiffType) { 306 return Diag(SecondVD->getLocation(), 307 diag::note_module_odr_violation_variable) 308 << SecondModule << SecondVD->getSourceRange() << DiffType; 309 }; 310 311 DeclarationName FirstName = FirstVD->getDeclName(); 312 DeclarationName SecondName = SecondVD->getDeclName(); 313 if (FirstName != SecondName) { 314 DiagError(VarName) << FirstName; 315 DiagNote(VarName) << SecondName; 316 return true; 317 } 318 319 QualType FirstType = FirstVD->getType(); 320 QualType SecondType = SecondVD->getType(); 321 if (computeODRHash(FirstType) != computeODRHash(SecondType)) { 322 DiagError(VarType) << FirstName << FirstType; 323 DiagNote(VarType) << SecondName << SecondType; 324 return true; 325 } 326 327 if (!LangOpts.CPlusPlus) 328 return false; 329 330 const Expr *FirstInit = FirstVD->getInit(); 331 const Expr *SecondInit = SecondVD->getInit(); 332 if ((FirstInit == nullptr) != (SecondInit == nullptr)) { 333 DiagError(VarSingleInitializer) 334 << FirstName << (FirstInit == nullptr) 335 << (FirstInit ? FirstInit->getSourceRange() : SourceRange()); 336 DiagNote(VarSingleInitializer) 337 << SecondName << (SecondInit == nullptr) 338 << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); 339 return true; 340 } 341 342 if (FirstInit && SecondInit && 343 computeODRHash(FirstInit) != computeODRHash(SecondInit)) { 344 DiagError(VarDifferentInitializer) 345 << FirstName << FirstInit->getSourceRange(); 346 DiagNote(VarDifferentInitializer) 347 << SecondName << SecondInit->getSourceRange(); 348 return true; 349 } 350 351 const bool FirstIsConstexpr = FirstVD->isConstexpr(); 352 const bool SecondIsConstexpr = SecondVD->isConstexpr(); 353 if (FirstIsConstexpr != SecondIsConstexpr) { 354 DiagError(VarConstexpr) << FirstName << FirstIsConstexpr; 355 DiagNote(VarConstexpr) << SecondName << SecondIsConstexpr; 356 return true; 357 } 358 return false; 359 } 360 361 bool ODRDiagsEmitter::diagnoseSubMismatchProtocols( 362 const ObjCProtocolList &FirstProtocols, 363 const ObjCContainerDecl *FirstContainer, StringRef FirstModule, 364 const ObjCProtocolList &SecondProtocols, 365 const ObjCContainerDecl *SecondContainer, StringRef SecondModule) const { 366 // Keep in sync with err_module_odr_violation_referenced_protocols. 367 enum ODRReferencedProtocolDifference { 368 NumProtocols, 369 ProtocolType, 370 }; 371 auto DiagRefProtocolError = [FirstContainer, FirstModule, 372 this](SourceLocation Loc, SourceRange Range, 373 ODRReferencedProtocolDifference DiffType) { 374 return Diag(Loc, diag::err_module_odr_violation_referenced_protocols) 375 << FirstContainer << FirstModule.empty() << FirstModule << Range 376 << DiffType; 377 }; 378 auto DiagRefProtocolNote = [SecondModule, 379 this](SourceLocation Loc, SourceRange Range, 380 ODRReferencedProtocolDifference DiffType) { 381 return Diag(Loc, diag::note_module_odr_violation_referenced_protocols) 382 << SecondModule.empty() << SecondModule << Range << DiffType; 383 }; 384 auto GetProtoListSourceRange = [](const ObjCProtocolList &PL) { 385 if (PL.empty()) 386 return SourceRange(); 387 return SourceRange(*PL.loc_begin(), *std::prev(PL.loc_end())); 388 }; 389 390 if (FirstProtocols.size() != SecondProtocols.size()) { 391 DiagRefProtocolError(FirstContainer->getLocation(), 392 GetProtoListSourceRange(FirstProtocols), NumProtocols) 393 << FirstProtocols.size(); 394 DiagRefProtocolNote(SecondContainer->getLocation(), 395 GetProtoListSourceRange(SecondProtocols), NumProtocols) 396 << SecondProtocols.size(); 397 return true; 398 } 399 400 for (unsigned I = 0, E = FirstProtocols.size(); I != E; ++I) { 401 const ObjCProtocolDecl *FirstProtocol = FirstProtocols[I]; 402 const ObjCProtocolDecl *SecondProtocol = SecondProtocols[I]; 403 DeclarationName FirstProtocolName = FirstProtocol->getDeclName(); 404 DeclarationName SecondProtocolName = SecondProtocol->getDeclName(); 405 if (FirstProtocolName != SecondProtocolName) { 406 SourceLocation FirstLoc = *(FirstProtocols.loc_begin() + I); 407 SourceLocation SecondLoc = *(SecondProtocols.loc_begin() + I); 408 SourceRange EmptyRange; 409 DiagRefProtocolError(FirstLoc, EmptyRange, ProtocolType) 410 << (I + 1) << FirstProtocolName; 411 DiagRefProtocolNote(SecondLoc, EmptyRange, ProtocolType) 412 << (I + 1) << SecondProtocolName; 413 return true; 414 } 415 } 416 417 return false; 418 } 419 420 bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod( 421 const NamedDecl *FirstObjCContainer, StringRef FirstModule, 422 StringRef SecondModule, const ObjCMethodDecl *FirstMethod, 423 const ObjCMethodDecl *SecondMethod) const { 424 enum ODRMethodDifference { 425 ReturnType, 426 InstanceOrClass, 427 ControlLevel, // optional/required 428 DesignatedInitializer, 429 Directness, 430 Name, 431 }; 432 433 auto DiagError = [FirstObjCContainer, FirstModule, FirstMethod, 434 this](ODRMethodDifference DiffType) { 435 return Diag(FirstMethod->getLocation(), 436 diag::err_module_odr_violation_objc_method) 437 << FirstObjCContainer << FirstModule.empty() << FirstModule 438 << FirstMethod->getSourceRange() << DiffType; 439 }; 440 auto DiagNote = [SecondModule, SecondMethod, 441 this](ODRMethodDifference DiffType) { 442 return Diag(SecondMethod->getLocation(), 443 diag::note_module_odr_violation_objc_method) 444 << SecondModule.empty() << SecondModule 445 << SecondMethod->getSourceRange() << DiffType; 446 }; 447 448 if (computeODRHash(FirstMethod->getReturnType()) != 449 computeODRHash(SecondMethod->getReturnType())) { 450 DiagError(ReturnType) << FirstMethod << FirstMethod->getReturnType(); 451 DiagNote(ReturnType) << SecondMethod << SecondMethod->getReturnType(); 452 return true; 453 } 454 455 if (FirstMethod->isInstanceMethod() != SecondMethod->isInstanceMethod()) { 456 DiagError(InstanceOrClass) 457 << FirstMethod << FirstMethod->isInstanceMethod(); 458 DiagNote(InstanceOrClass) 459 << SecondMethod << SecondMethod->isInstanceMethod(); 460 return true; 461 } 462 if (FirstMethod->getImplementationControl() != 463 SecondMethod->getImplementationControl()) { 464 DiagError(ControlLevel) << FirstMethod->getImplementationControl(); 465 DiagNote(ControlLevel) << SecondMethod->getImplementationControl(); 466 return true; 467 } 468 if (FirstMethod->isThisDeclarationADesignatedInitializer() != 469 SecondMethod->isThisDeclarationADesignatedInitializer()) { 470 DiagError(DesignatedInitializer) 471 << FirstMethod 472 << FirstMethod->isThisDeclarationADesignatedInitializer(); 473 DiagNote(DesignatedInitializer) 474 << SecondMethod 475 << SecondMethod->isThisDeclarationADesignatedInitializer(); 476 return true; 477 } 478 if (FirstMethod->isDirectMethod() != SecondMethod->isDirectMethod()) { 479 DiagError(Directness) << FirstMethod << FirstMethod->isDirectMethod(); 480 DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod(); 481 return true; 482 } 483 if (diagnoseSubMismatchMethodParameters(Diags, FirstObjCContainer, 484 FirstModule, SecondModule, 485 FirstMethod, SecondMethod)) 486 return true; 487 488 // Check method name *after* looking at the parameters otherwise we get a 489 // less ideal diagnostics: a ObjCMethodName mismatch given that selectors 490 // for different parameters are likely to be different. 491 DeclarationName FirstName = FirstMethod->getDeclName(); 492 DeclarationName SecondName = SecondMethod->getDeclName(); 493 if (FirstName != SecondName) { 494 DiagError(Name) << FirstName; 495 DiagNote(Name) << SecondName; 496 return true; 497 } 498 499 return false; 500 } 501 502 bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty( 503 const NamedDecl *FirstObjCContainer, StringRef FirstModule, 504 StringRef SecondModule, const ObjCPropertyDecl *FirstProp, 505 const ObjCPropertyDecl *SecondProp) const { 506 enum ODRPropertyDifference { 507 Name, 508 Type, 509 ControlLevel, // optional/required 510 Attribute, 511 }; 512 513 auto DiagError = [FirstObjCContainer, FirstModule, FirstProp, 514 this](SourceLocation Loc, ODRPropertyDifference DiffType) { 515 return Diag(Loc, diag::err_module_odr_violation_objc_property) 516 << FirstObjCContainer << FirstModule.empty() << FirstModule 517 << FirstProp->getSourceRange() << DiffType; 518 }; 519 auto DiagNote = [SecondModule, SecondProp, 520 this](SourceLocation Loc, ODRPropertyDifference DiffType) { 521 return Diag(Loc, diag::note_module_odr_violation_objc_property) 522 << SecondModule.empty() << SecondModule 523 << SecondProp->getSourceRange() << DiffType; 524 }; 525 526 IdentifierInfo *FirstII = FirstProp->getIdentifier(); 527 IdentifierInfo *SecondII = SecondProp->getIdentifier(); 528 if (FirstII->getName() != SecondII->getName()) { 529 DiagError(FirstProp->getLocation(), Name) << FirstII; 530 DiagNote(SecondProp->getLocation(), Name) << SecondII; 531 return true; 532 } 533 if (computeODRHash(FirstProp->getType()) != 534 computeODRHash(SecondProp->getType())) { 535 DiagError(FirstProp->getLocation(), Type) 536 << FirstII << FirstProp->getType(); 537 DiagNote(SecondProp->getLocation(), Type) 538 << SecondII << SecondProp->getType(); 539 return true; 540 } 541 if (FirstProp->getPropertyImplementation() != 542 SecondProp->getPropertyImplementation()) { 543 DiagError(FirstProp->getLocation(), ControlLevel) 544 << FirstProp->getPropertyImplementation(); 545 DiagNote(SecondProp->getLocation(), ControlLevel) 546 << SecondProp->getPropertyImplementation(); 547 return true; 548 } 549 550 // Go over the property attributes and stop at the first mismatch. 551 unsigned FirstAttrs = (unsigned)FirstProp->getPropertyAttributes(); 552 unsigned SecondAttrs = (unsigned)SecondProp->getPropertyAttributes(); 553 if (FirstAttrs != SecondAttrs) { 554 for (unsigned I = 0; I < NumObjCPropertyAttrsBits; ++I) { 555 unsigned CheckedAttr = (1 << I); 556 if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr)) 557 continue; 558 559 bool IsFirstWritten = 560 (unsigned)FirstProp->getPropertyAttributesAsWritten() & CheckedAttr; 561 bool IsSecondWritten = 562 (unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr; 563 DiagError(IsFirstWritten ? FirstProp->getLParenLoc() 564 : FirstProp->getLocation(), 565 Attribute) 566 << FirstII << (I + 1) << IsFirstWritten; 567 DiagNote(IsSecondWritten ? SecondProp->getLParenLoc() 568 : SecondProp->getLocation(), 569 Attribute) 570 << SecondII << (I + 1); 571 return true; 572 } 573 } 574 575 return false; 576 } 577 578 ODRDiagsEmitter::DiffResult 579 ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes, 580 DeclHashes &SecondHashes) { 581 auto DifferenceSelector = [](const Decl *D) { 582 assert(D && "valid Decl required"); 583 switch (D->getKind()) { 584 default: 585 return Other; 586 case Decl::AccessSpec: 587 switch (D->getAccess()) { 588 case AS_public: 589 return PublicSpecifer; 590 case AS_private: 591 return PrivateSpecifer; 592 case AS_protected: 593 return ProtectedSpecifer; 594 case AS_none: 595 break; 596 } 597 llvm_unreachable("Invalid access specifier"); 598 case Decl::StaticAssert: 599 return StaticAssert; 600 case Decl::Field: 601 return Field; 602 case Decl::CXXMethod: 603 case Decl::CXXConstructor: 604 case Decl::CXXDestructor: 605 return CXXMethod; 606 case Decl::TypeAlias: 607 return TypeAlias; 608 case Decl::Typedef: 609 return TypeDef; 610 case Decl::Var: 611 return Var; 612 case Decl::Friend: 613 return Friend; 614 case Decl::FunctionTemplate: 615 return FunctionTemplate; 616 case Decl::ObjCMethod: 617 return ObjCMethod; 618 case Decl::ObjCIvar: 619 return ObjCIvar; 620 case Decl::ObjCProperty: 621 return ObjCProperty; 622 } 623 }; 624 625 DiffResult DR; 626 auto FirstIt = FirstHashes.begin(); 627 auto SecondIt = SecondHashes.begin(); 628 while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) { 629 if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() && 630 FirstIt->second == SecondIt->second) { 631 ++FirstIt; 632 ++SecondIt; 633 continue; 634 } 635 636 DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first; 637 DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first; 638 639 DR.FirstDiffType = 640 DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass; 641 DR.SecondDiffType = 642 DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass; 643 return DR; 644 } 645 return DR; 646 } 647 648 void ODRDiagsEmitter::diagnoseSubMismatchUnexpected( 649 DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule, 650 const NamedDecl *SecondRecord, StringRef SecondModule) const { 651 Diag(FirstRecord->getLocation(), 652 diag::err_module_odr_violation_different_definitions) 653 << FirstRecord << FirstModule.empty() << FirstModule; 654 655 if (DR.FirstDecl) { 656 Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference) 657 << FirstRecord << DR.FirstDecl->getSourceRange(); 658 } 659 660 Diag(SecondRecord->getLocation(), 661 diag::note_module_odr_violation_different_definitions) 662 << SecondModule; 663 664 if (DR.SecondDecl) { 665 Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference) 666 << DR.SecondDecl->getSourceRange(); 667 } 668 } 669 670 void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds( 671 DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule, 672 const NamedDecl *SecondRecord, StringRef SecondModule) const { 673 auto GetMismatchedDeclLoc = [](const NamedDecl *Container, 674 ODRMismatchDecl DiffType, const Decl *D) { 675 SourceLocation Loc; 676 SourceRange Range; 677 if (DiffType == EndOfClass) { 678 if (auto *Tag = dyn_cast<TagDecl>(Container)) 679 Loc = Tag->getBraceRange().getEnd(); 680 else if (auto *IF = dyn_cast<ObjCInterfaceDecl>(Container)) 681 Loc = IF->getAtEndRange().getBegin(); 682 else 683 Loc = Container->getEndLoc(); 684 } else { 685 Loc = D->getLocation(); 686 Range = D->getSourceRange(); 687 } 688 return std::make_pair(Loc, Range); 689 }; 690 691 auto FirstDiagInfo = 692 GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl); 693 Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl) 694 << FirstRecord << FirstModule.empty() << FirstModule 695 << FirstDiagInfo.second << DR.FirstDiffType; 696 697 auto SecondDiagInfo = 698 GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl); 699 Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl) 700 << SecondModule.empty() << SecondModule << SecondDiagInfo.second 701 << DR.SecondDiffType; 702 } 703 704 bool ODRDiagsEmitter::diagnoseMismatch( 705 const CXXRecordDecl *FirstRecord, const CXXRecordDecl *SecondRecord, 706 const struct CXXRecordDecl::DefinitionData *SecondDD) const { 707 // Multiple different declarations got merged together; tell the user 708 // where they came from. 709 if (FirstRecord == SecondRecord) 710 return false; 711 712 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord); 713 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord); 714 715 const struct CXXRecordDecl::DefinitionData *FirstDD = 716 FirstRecord->DefinitionData; 717 assert(FirstDD && SecondDD && "Definitions without DefinitionData"); 718 719 // Diagnostics from DefinitionData are emitted here. 720 if (FirstDD != SecondDD) { 721 // Keep in sync with err_module_odr_violation_definition_data. 722 enum ODRDefinitionDataDifference { 723 NumBases, 724 NumVBases, 725 BaseType, 726 BaseVirtual, 727 BaseAccess, 728 }; 729 auto DiagBaseError = [FirstRecord, &FirstModule, 730 this](SourceLocation Loc, SourceRange Range, 731 ODRDefinitionDataDifference DiffType) { 732 return Diag(Loc, diag::err_module_odr_violation_definition_data) 733 << FirstRecord << FirstModule.empty() << FirstModule << Range 734 << DiffType; 735 }; 736 auto DiagBaseNote = [&SecondModule, 737 this](SourceLocation Loc, SourceRange Range, 738 ODRDefinitionDataDifference DiffType) { 739 return Diag(Loc, diag::note_module_odr_violation_definition_data) 740 << SecondModule << Range << DiffType; 741 }; 742 auto GetSourceRange = [](const struct CXXRecordDecl::DefinitionData *DD) { 743 unsigned NumBases = DD->NumBases; 744 if (NumBases == 0) 745 return SourceRange(); 746 ArrayRef<CXXBaseSpecifier> bases = DD->bases(); 747 return SourceRange(bases[0].getBeginLoc(), 748 bases[NumBases - 1].getEndLoc()); 749 }; 750 751 unsigned FirstNumBases = FirstDD->NumBases; 752 unsigned FirstNumVBases = FirstDD->NumVBases; 753 unsigned SecondNumBases = SecondDD->NumBases; 754 unsigned SecondNumVBases = SecondDD->NumVBases; 755 if (FirstNumBases != SecondNumBases) { 756 DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD), 757 NumBases) 758 << FirstNumBases; 759 DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), 760 NumBases) 761 << SecondNumBases; 762 return true; 763 } 764 765 if (FirstNumVBases != SecondNumVBases) { 766 DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD), 767 NumVBases) 768 << FirstNumVBases; 769 DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), 770 NumVBases) 771 << SecondNumVBases; 772 return true; 773 } 774 775 ArrayRef<CXXBaseSpecifier> FirstBases = FirstDD->bases(); 776 ArrayRef<CXXBaseSpecifier> SecondBases = SecondDD->bases(); 777 for (unsigned I = 0; I < FirstNumBases; ++I) { 778 const CXXBaseSpecifier FirstBase = FirstBases[I]; 779 const CXXBaseSpecifier SecondBase = SecondBases[I]; 780 if (computeODRHash(FirstBase.getType()) != 781 computeODRHash(SecondBase.getType())) { 782 DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(), 783 BaseType) 784 << (I + 1) << FirstBase.getType(); 785 DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(), 786 BaseType) 787 << (I + 1) << SecondBase.getType(); 788 return true; 789 } 790 791 if (FirstBase.isVirtual() != SecondBase.isVirtual()) { 792 DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(), 793 BaseVirtual) 794 << (I + 1) << FirstBase.isVirtual() << FirstBase.getType(); 795 DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(), 796 BaseVirtual) 797 << (I + 1) << SecondBase.isVirtual() << SecondBase.getType(); 798 return true; 799 } 800 801 if (FirstBase.getAccessSpecifierAsWritten() != 802 SecondBase.getAccessSpecifierAsWritten()) { 803 DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(), 804 BaseAccess) 805 << (I + 1) << FirstBase.getType() 806 << (int)FirstBase.getAccessSpecifierAsWritten(); 807 DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(), 808 BaseAccess) 809 << (I + 1) << SecondBase.getType() 810 << (int)SecondBase.getAccessSpecifierAsWritten(); 811 return true; 812 } 813 } 814 } 815 816 const ClassTemplateDecl *FirstTemplate = 817 FirstRecord->getDescribedClassTemplate(); 818 const ClassTemplateDecl *SecondTemplate = 819 SecondRecord->getDescribedClassTemplate(); 820 821 assert(!FirstTemplate == !SecondTemplate && 822 "Both pointers should be null or non-null"); 823 824 if (FirstTemplate && SecondTemplate) { 825 ArrayRef<const NamedDecl *> FirstTemplateParams = 826 FirstTemplate->getTemplateParameters()->asArray(); 827 ArrayRef<const NamedDecl *> SecondTemplateParams = 828 SecondTemplate->getTemplateParameters()->asArray(); 829 assert(FirstTemplateParams.size() == SecondTemplateParams.size() && 830 "Number of template parameters should be equal."); 831 for (auto Pair : llvm::zip(FirstTemplateParams, SecondTemplateParams)) { 832 const NamedDecl *FirstDecl = std::get<0>(Pair); 833 const NamedDecl *SecondDecl = std::get<1>(Pair); 834 if (computeODRHash(FirstDecl) == computeODRHash(SecondDecl)) 835 continue; 836 837 assert(FirstDecl->getKind() == SecondDecl->getKind() && 838 "Parameter Decl's should be the same kind."); 839 840 enum ODRTemplateDifference { 841 ParamEmptyName, 842 ParamName, 843 ParamSingleDefaultArgument, 844 ParamDifferentDefaultArgument, 845 }; 846 847 auto hasDefaultArg = [](const NamedDecl *D) { 848 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) 849 return TTP->hasDefaultArgument() && 850 !TTP->defaultArgumentWasInherited(); 851 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) 852 return NTTP->hasDefaultArgument() && 853 !NTTP->defaultArgumentWasInherited(); 854 auto *TTP = cast<TemplateTemplateParmDecl>(D); 855 return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited(); 856 }; 857 bool hasFirstArg = hasDefaultArg(FirstDecl); 858 bool hasSecondArg = hasDefaultArg(SecondDecl); 859 860 ODRTemplateDifference ErrDiffType; 861 ODRTemplateDifference NoteDiffType; 862 863 DeclarationName FirstName = FirstDecl->getDeclName(); 864 DeclarationName SecondName = SecondDecl->getDeclName(); 865 866 if (FirstName != SecondName) { 867 bool FirstNameEmpty = 868 FirstName.isIdentifier() && !FirstName.getAsIdentifierInfo(); 869 bool SecondNameEmpty = 870 SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo(); 871 ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName; 872 NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName; 873 } else if (hasFirstArg == hasSecondArg) 874 ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument; 875 else 876 ErrDiffType = NoteDiffType = ParamSingleDefaultArgument; 877 878 Diag(FirstDecl->getLocation(), 879 diag::err_module_odr_violation_template_parameter) 880 << FirstRecord << FirstModule.empty() << FirstModule 881 << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg 882 << FirstName; 883 Diag(SecondDecl->getLocation(), 884 diag::note_module_odr_violation_template_parameter) 885 << SecondModule << SecondDecl->getSourceRange() << NoteDiffType 886 << hasSecondArg << SecondName; 887 return true; 888 } 889 } 890 891 auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record, 892 const DeclContext *DC) { 893 for (const Decl *D : Record->decls()) { 894 if (!ODRHash::isSubDeclToBeProcessed(D, DC)) 895 continue; 896 Hashes.emplace_back(D, computeODRHash(D)); 897 } 898 }; 899 900 DeclHashes FirstHashes; 901 DeclHashes SecondHashes; 902 const DeclContext *DC = FirstRecord; 903 PopulateHashes(FirstHashes, FirstRecord, DC); 904 PopulateHashes(SecondHashes, SecondRecord, DC); 905 906 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes); 907 ODRMismatchDecl FirstDiffType = DR.FirstDiffType; 908 ODRMismatchDecl SecondDiffType = DR.SecondDiffType; 909 const Decl *FirstDecl = DR.FirstDecl; 910 const Decl *SecondDecl = DR.SecondDecl; 911 912 if (FirstDiffType == Other || SecondDiffType == Other) { 913 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord, 914 SecondModule); 915 return true; 916 } 917 918 if (FirstDiffType != SecondDiffType) { 919 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule, 920 SecondRecord, SecondModule); 921 return true; 922 } 923 924 // Used with err_module_odr_violation_record and 925 // note_module_odr_violation_record 926 enum ODRCXXRecordDifference { 927 StaticAssertCondition, 928 StaticAssertMessage, 929 StaticAssertOnlyMessage, 930 MethodName, 931 MethodDeleted, 932 MethodDefaulted, 933 MethodVirtual, 934 MethodStatic, 935 MethodVolatile, 936 MethodConst, 937 MethodInline, 938 MethodParameterSingleDefaultArgument, 939 MethodParameterDifferentDefaultArgument, 940 MethodNoTemplateArguments, 941 MethodDifferentNumberTemplateArguments, 942 MethodDifferentTemplateArgument, 943 MethodSingleBody, 944 MethodDifferentBody, 945 FriendTypeFunction, 946 FriendType, 947 FriendFunction, 948 FunctionTemplateDifferentNumberParameters, 949 FunctionTemplateParameterDifferentKind, 950 FunctionTemplateParameterName, 951 FunctionTemplateParameterSingleDefaultArgument, 952 FunctionTemplateParameterDifferentDefaultArgument, 953 FunctionTemplateParameterDifferentType, 954 FunctionTemplatePackParameter, 955 }; 956 auto DiagError = [FirstRecord, &FirstModule, 957 this](SourceLocation Loc, SourceRange Range, 958 ODRCXXRecordDifference DiffType) { 959 return Diag(Loc, diag::err_module_odr_violation_record) 960 << FirstRecord << FirstModule.empty() << FirstModule << Range 961 << DiffType; 962 }; 963 auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range, 964 ODRCXXRecordDifference DiffType) { 965 return Diag(Loc, diag::note_module_odr_violation_record) 966 << SecondModule << Range << DiffType; 967 }; 968 969 assert(FirstDiffType == SecondDiffType); 970 switch (FirstDiffType) { 971 case Other: 972 case EndOfClass: 973 case PublicSpecifer: 974 case PrivateSpecifer: 975 case ProtectedSpecifer: 976 case ObjCMethod: 977 case ObjCIvar: 978 case ObjCProperty: 979 llvm_unreachable("Invalid diff type"); 980 981 case StaticAssert: { 982 const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl); 983 const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl); 984 985 const Expr *FirstExpr = FirstSA->getAssertExpr(); 986 const Expr *SecondExpr = SecondSA->getAssertExpr(); 987 unsigned FirstODRHash = computeODRHash(FirstExpr); 988 unsigned SecondODRHash = computeODRHash(SecondExpr); 989 if (FirstODRHash != SecondODRHash) { 990 DiagError(FirstExpr->getBeginLoc(), FirstExpr->getSourceRange(), 991 StaticAssertCondition); 992 DiagNote(SecondExpr->getBeginLoc(), SecondExpr->getSourceRange(), 993 StaticAssertCondition); 994 return true; 995 } 996 997 const Expr *FirstMessage = FirstSA->getMessage(); 998 const Expr *SecondMessage = SecondSA->getMessage(); 999 assert((FirstMessage || SecondMessage) && "Both messages cannot be empty"); 1000 if ((FirstMessage && !SecondMessage) || (!FirstMessage && SecondMessage)) { 1001 SourceLocation FirstLoc, SecondLoc; 1002 SourceRange FirstRange, SecondRange; 1003 if (FirstMessage) { 1004 FirstLoc = FirstMessage->getBeginLoc(); 1005 FirstRange = FirstMessage->getSourceRange(); 1006 } else { 1007 FirstLoc = FirstSA->getBeginLoc(); 1008 FirstRange = FirstSA->getSourceRange(); 1009 } 1010 if (SecondMessage) { 1011 SecondLoc = SecondMessage->getBeginLoc(); 1012 SecondRange = SecondMessage->getSourceRange(); 1013 } else { 1014 SecondLoc = SecondSA->getBeginLoc(); 1015 SecondRange = SecondSA->getSourceRange(); 1016 } 1017 DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage) 1018 << (FirstMessage == nullptr); 1019 DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage) 1020 << (SecondMessage == nullptr); 1021 return true; 1022 } 1023 1024 if (FirstMessage && SecondMessage) { 1025 unsigned FirstMessageODRHash = computeODRHash(FirstMessage); 1026 unsigned SecondMessageODRHash = computeODRHash(SecondMessage); 1027 if (FirstMessageODRHash != SecondMessageODRHash) { 1028 DiagError(FirstMessage->getBeginLoc(), FirstMessage->getSourceRange(), 1029 StaticAssertMessage); 1030 DiagNote(SecondMessage->getBeginLoc(), SecondMessage->getSourceRange(), 1031 StaticAssertMessage); 1032 return true; 1033 } 1034 } 1035 break; 1036 } 1037 1038 case Field: { 1039 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule, 1040 cast<FieldDecl>(FirstDecl), 1041 cast<FieldDecl>(SecondDecl))) 1042 return true; 1043 break; 1044 } 1045 1046 case CXXMethod: { 1047 enum { 1048 DiagMethod, 1049 DiagConstructor, 1050 DiagDestructor, 1051 } FirstMethodType, 1052 SecondMethodType; 1053 auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl *D) { 1054 if (isa<CXXConstructorDecl>(D)) 1055 return DiagConstructor; 1056 if (isa<CXXDestructorDecl>(D)) 1057 return DiagDestructor; 1058 return DiagMethod; 1059 }; 1060 const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl); 1061 const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl); 1062 FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod); 1063 SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod); 1064 DeclarationName FirstName = FirstMethod->getDeclName(); 1065 DeclarationName SecondName = SecondMethod->getDeclName(); 1066 auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType, 1067 FirstName](ODRCXXRecordDifference DiffType) { 1068 return DiagError(FirstMethod->getLocation(), 1069 FirstMethod->getSourceRange(), DiffType) 1070 << FirstMethodType << FirstName; 1071 }; 1072 auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType, 1073 SecondName](ODRCXXRecordDifference DiffType) { 1074 return DiagNote(SecondMethod->getLocation(), 1075 SecondMethod->getSourceRange(), DiffType) 1076 << SecondMethodType << SecondName; 1077 }; 1078 1079 if (FirstMethodType != SecondMethodType || FirstName != SecondName) { 1080 DiagMethodError(MethodName); 1081 DiagMethodNote(MethodName); 1082 return true; 1083 } 1084 1085 const bool FirstDeleted = FirstMethod->isDeletedAsWritten(); 1086 const bool SecondDeleted = SecondMethod->isDeletedAsWritten(); 1087 if (FirstDeleted != SecondDeleted) { 1088 DiagMethodError(MethodDeleted) << FirstDeleted; 1089 DiagMethodNote(MethodDeleted) << SecondDeleted; 1090 return true; 1091 } 1092 1093 const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted(); 1094 const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted(); 1095 if (FirstDefaulted != SecondDefaulted) { 1096 DiagMethodError(MethodDefaulted) << FirstDefaulted; 1097 DiagMethodNote(MethodDefaulted) << SecondDefaulted; 1098 return true; 1099 } 1100 1101 const bool FirstVirtual = FirstMethod->isVirtualAsWritten(); 1102 const bool SecondVirtual = SecondMethod->isVirtualAsWritten(); 1103 const bool FirstPure = FirstMethod->isPure(); 1104 const bool SecondPure = SecondMethod->isPure(); 1105 if ((FirstVirtual || SecondVirtual) && 1106 (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) { 1107 DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual; 1108 DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual; 1109 return true; 1110 } 1111 1112 // CXXMethodDecl::isStatic uses the canonical Decl. With Decl merging, 1113 // FirstDecl is the canonical Decl of SecondDecl, so the storage 1114 // class needs to be checked instead. 1115 StorageClass FirstStorage = FirstMethod->getStorageClass(); 1116 StorageClass SecondStorage = SecondMethod->getStorageClass(); 1117 const bool FirstStatic = FirstStorage == SC_Static; 1118 const bool SecondStatic = SecondStorage == SC_Static; 1119 if (FirstStatic != SecondStatic) { 1120 DiagMethodError(MethodStatic) << FirstStatic; 1121 DiagMethodNote(MethodStatic) << SecondStatic; 1122 return true; 1123 } 1124 1125 const bool FirstVolatile = FirstMethod->isVolatile(); 1126 const bool SecondVolatile = SecondMethod->isVolatile(); 1127 if (FirstVolatile != SecondVolatile) { 1128 DiagMethodError(MethodVolatile) << FirstVolatile; 1129 DiagMethodNote(MethodVolatile) << SecondVolatile; 1130 return true; 1131 } 1132 1133 const bool FirstConst = FirstMethod->isConst(); 1134 const bool SecondConst = SecondMethod->isConst(); 1135 if (FirstConst != SecondConst) { 1136 DiagMethodError(MethodConst) << FirstConst; 1137 DiagMethodNote(MethodConst) << SecondConst; 1138 return true; 1139 } 1140 1141 const bool FirstInline = FirstMethod->isInlineSpecified(); 1142 const bool SecondInline = SecondMethod->isInlineSpecified(); 1143 if (FirstInline != SecondInline) { 1144 DiagMethodError(MethodInline) << FirstInline; 1145 DiagMethodNote(MethodInline) << SecondInline; 1146 return true; 1147 } 1148 1149 if (diagnoseSubMismatchMethodParameters(Diags, FirstRecord, 1150 FirstModule, SecondModule, 1151 FirstMethod, SecondMethod)) 1152 return true; 1153 1154 for (unsigned I = 0, N = FirstMethod->param_size(); I < N; ++I) { 1155 const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I); 1156 const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I); 1157 1158 const Expr *FirstInit = FirstParam->getInit(); 1159 const Expr *SecondInit = SecondParam->getInit(); 1160 if ((FirstInit == nullptr) != (SecondInit == nullptr)) { 1161 DiagMethodError(MethodParameterSingleDefaultArgument) 1162 << (I + 1) << (FirstInit == nullptr) 1163 << (FirstInit ? FirstInit->getSourceRange() : SourceRange()); 1164 DiagMethodNote(MethodParameterSingleDefaultArgument) 1165 << (I + 1) << (SecondInit == nullptr) 1166 << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); 1167 return true; 1168 } 1169 1170 if (FirstInit && SecondInit && 1171 computeODRHash(FirstInit) != computeODRHash(SecondInit)) { 1172 DiagMethodError(MethodParameterDifferentDefaultArgument) 1173 << (I + 1) << FirstInit->getSourceRange(); 1174 DiagMethodNote(MethodParameterDifferentDefaultArgument) 1175 << (I + 1) << SecondInit->getSourceRange(); 1176 return true; 1177 } 1178 } 1179 1180 const TemplateArgumentList *FirstTemplateArgs = 1181 FirstMethod->getTemplateSpecializationArgs(); 1182 const TemplateArgumentList *SecondTemplateArgs = 1183 SecondMethod->getTemplateSpecializationArgs(); 1184 1185 if ((FirstTemplateArgs && !SecondTemplateArgs) || 1186 (!FirstTemplateArgs && SecondTemplateArgs)) { 1187 DiagMethodError(MethodNoTemplateArguments) 1188 << (FirstTemplateArgs != nullptr); 1189 DiagMethodNote(MethodNoTemplateArguments) 1190 << (SecondTemplateArgs != nullptr); 1191 return true; 1192 } 1193 1194 if (FirstTemplateArgs && SecondTemplateArgs) { 1195 // Remove pack expansions from argument list. 1196 auto ExpandTemplateArgumentList = [](const TemplateArgumentList *TAL) { 1197 llvm::SmallVector<const TemplateArgument *, 8> ExpandedList; 1198 for (const TemplateArgument &TA : TAL->asArray()) { 1199 if (TA.getKind() != TemplateArgument::Pack) { 1200 ExpandedList.push_back(&TA); 1201 continue; 1202 } 1203 llvm::append_range(ExpandedList, 1204 llvm::make_pointer_range(TA.getPackAsArray())); 1205 } 1206 return ExpandedList; 1207 }; 1208 llvm::SmallVector<const TemplateArgument *, 8> FirstExpandedList = 1209 ExpandTemplateArgumentList(FirstTemplateArgs); 1210 llvm::SmallVector<const TemplateArgument *, 8> SecondExpandedList = 1211 ExpandTemplateArgumentList(SecondTemplateArgs); 1212 1213 if (FirstExpandedList.size() != SecondExpandedList.size()) { 1214 DiagMethodError(MethodDifferentNumberTemplateArguments) 1215 << (unsigned)FirstExpandedList.size(); 1216 DiagMethodNote(MethodDifferentNumberTemplateArguments) 1217 << (unsigned)SecondExpandedList.size(); 1218 return true; 1219 } 1220 1221 for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) { 1222 const TemplateArgument &FirstTA = *FirstExpandedList[i], 1223 &SecondTA = *SecondExpandedList[i]; 1224 if (computeODRHash(FirstTA) == computeODRHash(SecondTA)) 1225 continue; 1226 1227 DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1; 1228 DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1; 1229 return true; 1230 } 1231 } 1232 1233 // Compute the hash of the method as if it has no body. 1234 auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) { 1235 ODRHash Hasher; 1236 Hasher.AddFunctionDecl(D, true /*SkipBody*/); 1237 return Hasher.CalculateHash(); 1238 }; 1239 1240 // Compare the hash generated to the hash stored. A difference means 1241 // that a body was present in the original source. Due to merging, 1242 // the standard way of detecting a body will not work. 1243 const bool HasFirstBody = 1244 ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash(); 1245 const bool HasSecondBody = 1246 ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash(); 1247 1248 if (HasFirstBody != HasSecondBody) { 1249 DiagMethodError(MethodSingleBody) << HasFirstBody; 1250 DiagMethodNote(MethodSingleBody) << HasSecondBody; 1251 return true; 1252 } 1253 1254 if (HasFirstBody && HasSecondBody) { 1255 DiagMethodError(MethodDifferentBody); 1256 DiagMethodNote(MethodDifferentBody); 1257 return true; 1258 } 1259 1260 break; 1261 } 1262 1263 case TypeAlias: 1264 case TypeDef: { 1265 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule, 1266 cast<TypedefNameDecl>(FirstDecl), 1267 cast<TypedefNameDecl>(SecondDecl), 1268 FirstDiffType == TypeAlias)) 1269 return true; 1270 break; 1271 } 1272 case Var: { 1273 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule, 1274 cast<VarDecl>(FirstDecl), 1275 cast<VarDecl>(SecondDecl))) 1276 return true; 1277 break; 1278 } 1279 case Friend: { 1280 const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl); 1281 const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl); 1282 1283 const NamedDecl *FirstND = FirstFriend->getFriendDecl(); 1284 const NamedDecl *SecondND = SecondFriend->getFriendDecl(); 1285 1286 TypeSourceInfo *FirstTSI = FirstFriend->getFriendType(); 1287 TypeSourceInfo *SecondTSI = SecondFriend->getFriendType(); 1288 1289 if (FirstND && SecondND) { 1290 DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(), 1291 FriendFunction) 1292 << FirstND; 1293 DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(), 1294 FriendFunction) 1295 << SecondND; 1296 return true; 1297 } 1298 1299 if (FirstTSI && SecondTSI) { 1300 QualType FirstFriendType = FirstTSI->getType(); 1301 QualType SecondFriendType = SecondTSI->getType(); 1302 assert(computeODRHash(FirstFriendType) != 1303 computeODRHash(SecondFriendType)); 1304 DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(), 1305 FriendType) 1306 << FirstFriendType; 1307 DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(), 1308 FriendType) 1309 << SecondFriendType; 1310 return true; 1311 } 1312 1313 DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(), 1314 FriendTypeFunction) 1315 << (FirstTSI == nullptr); 1316 DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(), 1317 FriendTypeFunction) 1318 << (SecondTSI == nullptr); 1319 return true; 1320 } 1321 case FunctionTemplate: { 1322 const FunctionTemplateDecl *FirstTemplate = 1323 cast<FunctionTemplateDecl>(FirstDecl); 1324 const FunctionTemplateDecl *SecondTemplate = 1325 cast<FunctionTemplateDecl>(SecondDecl); 1326 1327 TemplateParameterList *FirstTPL = FirstTemplate->getTemplateParameters(); 1328 TemplateParameterList *SecondTPL = SecondTemplate->getTemplateParameters(); 1329 1330 auto DiagTemplateError = [&DiagError, 1331 FirstTemplate](ODRCXXRecordDifference DiffType) { 1332 return DiagError(FirstTemplate->getLocation(), 1333 FirstTemplate->getSourceRange(), DiffType) 1334 << FirstTemplate; 1335 }; 1336 auto DiagTemplateNote = [&DiagNote, 1337 SecondTemplate](ODRCXXRecordDifference DiffType) { 1338 return DiagNote(SecondTemplate->getLocation(), 1339 SecondTemplate->getSourceRange(), DiffType) 1340 << SecondTemplate; 1341 }; 1342 1343 if (FirstTPL->size() != SecondTPL->size()) { 1344 DiagTemplateError(FunctionTemplateDifferentNumberParameters) 1345 << FirstTPL->size(); 1346 DiagTemplateNote(FunctionTemplateDifferentNumberParameters) 1347 << SecondTPL->size(); 1348 return true; 1349 } 1350 1351 for (unsigned i = 0, e = FirstTPL->size(); i != e; ++i) { 1352 NamedDecl *FirstParam = FirstTPL->getParam(i); 1353 NamedDecl *SecondParam = SecondTPL->getParam(i); 1354 1355 if (FirstParam->getKind() != SecondParam->getKind()) { 1356 enum { 1357 TemplateTypeParameter, 1358 NonTypeTemplateParameter, 1359 TemplateTemplateParameter, 1360 }; 1361 auto GetParamType = [](NamedDecl *D) { 1362 switch (D->getKind()) { 1363 default: 1364 llvm_unreachable("Unexpected template parameter type"); 1365 case Decl::TemplateTypeParm: 1366 return TemplateTypeParameter; 1367 case Decl::NonTypeTemplateParm: 1368 return NonTypeTemplateParameter; 1369 case Decl::TemplateTemplateParm: 1370 return TemplateTemplateParameter; 1371 } 1372 }; 1373 1374 DiagTemplateError(FunctionTemplateParameterDifferentKind) 1375 << (i + 1) << GetParamType(FirstParam); 1376 DiagTemplateNote(FunctionTemplateParameterDifferentKind) 1377 << (i + 1) << GetParamType(SecondParam); 1378 return true; 1379 } 1380 1381 if (FirstParam->getName() != SecondParam->getName()) { 1382 DiagTemplateError(FunctionTemplateParameterName) 1383 << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam; 1384 DiagTemplateNote(FunctionTemplateParameterName) 1385 << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam; 1386 return true; 1387 } 1388 1389 if (isa<TemplateTypeParmDecl>(FirstParam) && 1390 isa<TemplateTypeParmDecl>(SecondParam)) { 1391 TemplateTypeParmDecl *FirstTTPD = 1392 cast<TemplateTypeParmDecl>(FirstParam); 1393 TemplateTypeParmDecl *SecondTTPD = 1394 cast<TemplateTypeParmDecl>(SecondParam); 1395 bool HasFirstDefaultArgument = 1396 FirstTTPD->hasDefaultArgument() && 1397 !FirstTTPD->defaultArgumentWasInherited(); 1398 bool HasSecondDefaultArgument = 1399 SecondTTPD->hasDefaultArgument() && 1400 !SecondTTPD->defaultArgumentWasInherited(); 1401 if (HasFirstDefaultArgument != HasSecondDefaultArgument) { 1402 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument) 1403 << (i + 1) << HasFirstDefaultArgument; 1404 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument) 1405 << (i + 1) << HasSecondDefaultArgument; 1406 return true; 1407 } 1408 1409 if (HasFirstDefaultArgument && HasSecondDefaultArgument) { 1410 QualType FirstType = FirstTTPD->getDefaultArgument(); 1411 QualType SecondType = SecondTTPD->getDefaultArgument(); 1412 if (computeODRHash(FirstType) != computeODRHash(SecondType)) { 1413 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument) 1414 << (i + 1) << FirstType; 1415 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument) 1416 << (i + 1) << SecondType; 1417 return true; 1418 } 1419 } 1420 1421 if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) { 1422 DiagTemplateError(FunctionTemplatePackParameter) 1423 << (i + 1) << FirstTTPD->isParameterPack(); 1424 DiagTemplateNote(FunctionTemplatePackParameter) 1425 << (i + 1) << SecondTTPD->isParameterPack(); 1426 return true; 1427 } 1428 } 1429 1430 if (isa<TemplateTemplateParmDecl>(FirstParam) && 1431 isa<TemplateTemplateParmDecl>(SecondParam)) { 1432 TemplateTemplateParmDecl *FirstTTPD = 1433 cast<TemplateTemplateParmDecl>(FirstParam); 1434 TemplateTemplateParmDecl *SecondTTPD = 1435 cast<TemplateTemplateParmDecl>(SecondParam); 1436 1437 TemplateParameterList *FirstTPL = FirstTTPD->getTemplateParameters(); 1438 TemplateParameterList *SecondTPL = SecondTTPD->getTemplateParameters(); 1439 1440 auto ComputeTemplateParameterListODRHash = 1441 [](const TemplateParameterList *TPL) { 1442 assert(TPL); 1443 ODRHash Hasher; 1444 Hasher.AddTemplateParameterList(TPL); 1445 return Hasher.CalculateHash(); 1446 }; 1447 1448 if (ComputeTemplateParameterListODRHash(FirstTPL) != 1449 ComputeTemplateParameterListODRHash(SecondTPL)) { 1450 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1); 1451 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1); 1452 return true; 1453 } 1454 1455 bool HasFirstDefaultArgument = 1456 FirstTTPD->hasDefaultArgument() && 1457 !FirstTTPD->defaultArgumentWasInherited(); 1458 bool HasSecondDefaultArgument = 1459 SecondTTPD->hasDefaultArgument() && 1460 !SecondTTPD->defaultArgumentWasInherited(); 1461 if (HasFirstDefaultArgument != HasSecondDefaultArgument) { 1462 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument) 1463 << (i + 1) << HasFirstDefaultArgument; 1464 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument) 1465 << (i + 1) << HasSecondDefaultArgument; 1466 return true; 1467 } 1468 1469 if (HasFirstDefaultArgument && HasSecondDefaultArgument) { 1470 TemplateArgument FirstTA = 1471 FirstTTPD->getDefaultArgument().getArgument(); 1472 TemplateArgument SecondTA = 1473 SecondTTPD->getDefaultArgument().getArgument(); 1474 if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) { 1475 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument) 1476 << (i + 1) << FirstTA; 1477 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument) 1478 << (i + 1) << SecondTA; 1479 return true; 1480 } 1481 } 1482 1483 if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) { 1484 DiagTemplateError(FunctionTemplatePackParameter) 1485 << (i + 1) << FirstTTPD->isParameterPack(); 1486 DiagTemplateNote(FunctionTemplatePackParameter) 1487 << (i + 1) << SecondTTPD->isParameterPack(); 1488 return true; 1489 } 1490 } 1491 1492 if (isa<NonTypeTemplateParmDecl>(FirstParam) && 1493 isa<NonTypeTemplateParmDecl>(SecondParam)) { 1494 NonTypeTemplateParmDecl *FirstNTTPD = 1495 cast<NonTypeTemplateParmDecl>(FirstParam); 1496 NonTypeTemplateParmDecl *SecondNTTPD = 1497 cast<NonTypeTemplateParmDecl>(SecondParam); 1498 1499 QualType FirstType = FirstNTTPD->getType(); 1500 QualType SecondType = SecondNTTPD->getType(); 1501 if (computeODRHash(FirstType) != computeODRHash(SecondType)) { 1502 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1); 1503 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1); 1504 return true; 1505 } 1506 1507 bool HasFirstDefaultArgument = 1508 FirstNTTPD->hasDefaultArgument() && 1509 !FirstNTTPD->defaultArgumentWasInherited(); 1510 bool HasSecondDefaultArgument = 1511 SecondNTTPD->hasDefaultArgument() && 1512 !SecondNTTPD->defaultArgumentWasInherited(); 1513 if (HasFirstDefaultArgument != HasSecondDefaultArgument) { 1514 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument) 1515 << (i + 1) << HasFirstDefaultArgument; 1516 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument) 1517 << (i + 1) << HasSecondDefaultArgument; 1518 return true; 1519 } 1520 1521 if (HasFirstDefaultArgument && HasSecondDefaultArgument) { 1522 Expr *FirstDefaultArgument = FirstNTTPD->getDefaultArgument(); 1523 Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument(); 1524 if (computeODRHash(FirstDefaultArgument) != 1525 computeODRHash(SecondDefaultArgument)) { 1526 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument) 1527 << (i + 1) << FirstDefaultArgument; 1528 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument) 1529 << (i + 1) << SecondDefaultArgument; 1530 return true; 1531 } 1532 } 1533 1534 if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) { 1535 DiagTemplateError(FunctionTemplatePackParameter) 1536 << (i + 1) << FirstNTTPD->isParameterPack(); 1537 DiagTemplateNote(FunctionTemplatePackParameter) 1538 << (i + 1) << SecondNTTPD->isParameterPack(); 1539 return true; 1540 } 1541 } 1542 } 1543 break; 1544 } 1545 } 1546 1547 Diag(FirstDecl->getLocation(), 1548 diag::err_module_odr_violation_mismatch_decl_unknown) 1549 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType 1550 << FirstDecl->getSourceRange(); 1551 Diag(SecondDecl->getLocation(), 1552 diag::note_module_odr_violation_mismatch_decl_unknown) 1553 << SecondModule.empty() << SecondModule << FirstDiffType 1554 << SecondDecl->getSourceRange(); 1555 return true; 1556 } 1557 1558 bool ODRDiagsEmitter::diagnoseMismatch(const RecordDecl *FirstRecord, 1559 const RecordDecl *SecondRecord) const { 1560 if (FirstRecord == SecondRecord) 1561 return false; 1562 1563 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord); 1564 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord); 1565 1566 auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record, 1567 const DeclContext *DC) { 1568 for (const Decl *D : Record->decls()) { 1569 if (!ODRHash::isSubDeclToBeProcessed(D, DC)) 1570 continue; 1571 Hashes.emplace_back(D, computeODRHash(D)); 1572 } 1573 }; 1574 1575 DeclHashes FirstHashes; 1576 DeclHashes SecondHashes; 1577 const DeclContext *DC = FirstRecord; 1578 PopulateHashes(FirstHashes, FirstRecord, DC); 1579 PopulateHashes(SecondHashes, SecondRecord, DC); 1580 1581 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes); 1582 ODRMismatchDecl FirstDiffType = DR.FirstDiffType; 1583 ODRMismatchDecl SecondDiffType = DR.SecondDiffType; 1584 const Decl *FirstDecl = DR.FirstDecl; 1585 const Decl *SecondDecl = DR.SecondDecl; 1586 1587 if (FirstDiffType == Other || SecondDiffType == Other) { 1588 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord, 1589 SecondModule); 1590 return true; 1591 } 1592 1593 if (FirstDiffType != SecondDiffType) { 1594 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule, 1595 SecondRecord, SecondModule); 1596 return true; 1597 } 1598 1599 assert(FirstDiffType == SecondDiffType); 1600 switch (FirstDiffType) { 1601 // Already handled. 1602 case EndOfClass: 1603 case Other: 1604 // C++ only, invalid in this context. 1605 case PublicSpecifer: 1606 case PrivateSpecifer: 1607 case ProtectedSpecifer: 1608 case StaticAssert: 1609 case CXXMethod: 1610 case TypeAlias: 1611 case Friend: 1612 case FunctionTemplate: 1613 // Cannot be contained by RecordDecl, invalid in this context. 1614 case ObjCMethod: 1615 case ObjCIvar: 1616 case ObjCProperty: 1617 llvm_unreachable("Invalid diff type"); 1618 1619 case Field: { 1620 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule, 1621 cast<FieldDecl>(FirstDecl), 1622 cast<FieldDecl>(SecondDecl))) 1623 return true; 1624 break; 1625 } 1626 case TypeDef: { 1627 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule, 1628 cast<TypedefNameDecl>(FirstDecl), 1629 cast<TypedefNameDecl>(SecondDecl), 1630 /*IsTypeAlias=*/false)) 1631 return true; 1632 break; 1633 } 1634 case Var: { 1635 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule, 1636 cast<VarDecl>(FirstDecl), 1637 cast<VarDecl>(SecondDecl))) 1638 return true; 1639 break; 1640 } 1641 } 1642 1643 Diag(FirstDecl->getLocation(), 1644 diag::err_module_odr_violation_mismatch_decl_unknown) 1645 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType 1646 << FirstDecl->getSourceRange(); 1647 Diag(SecondDecl->getLocation(), 1648 diag::note_module_odr_violation_mismatch_decl_unknown) 1649 << SecondModule.empty() << SecondModule << FirstDiffType 1650 << SecondDecl->getSourceRange(); 1651 return true; 1652 } 1653 1654 bool ODRDiagsEmitter::diagnoseMismatch( 1655 const FunctionDecl *FirstFunction, 1656 const FunctionDecl *SecondFunction) const { 1657 if (FirstFunction == SecondFunction) 1658 return false; 1659 1660 // Keep in sync with select options in err_module_odr_violation_function. 1661 enum ODRFunctionDifference { 1662 ReturnType, 1663 ParameterName, 1664 ParameterType, 1665 ParameterSingleDefaultArgument, 1666 ParameterDifferentDefaultArgument, 1667 FunctionBody, 1668 }; 1669 1670 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction); 1671 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondFunction); 1672 1673 auto DiagError = [FirstFunction, &FirstModule, 1674 this](SourceLocation Loc, SourceRange Range, 1675 ODRFunctionDifference DiffType) { 1676 return Diag(Loc, diag::err_module_odr_violation_function) 1677 << FirstFunction << FirstModule.empty() << FirstModule << Range 1678 << DiffType; 1679 }; 1680 auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range, 1681 ODRFunctionDifference DiffType) { 1682 return Diag(Loc, diag::note_module_odr_violation_function) 1683 << SecondModule << Range << DiffType; 1684 }; 1685 1686 if (computeODRHash(FirstFunction->getReturnType()) != 1687 computeODRHash(SecondFunction->getReturnType())) { 1688 DiagError(FirstFunction->getReturnTypeSourceRange().getBegin(), 1689 FirstFunction->getReturnTypeSourceRange(), ReturnType) 1690 << FirstFunction->getReturnType(); 1691 DiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(), 1692 SecondFunction->getReturnTypeSourceRange(), ReturnType) 1693 << SecondFunction->getReturnType(); 1694 return true; 1695 } 1696 1697 assert(FirstFunction->param_size() == SecondFunction->param_size() && 1698 "Merged functions with different number of parameters"); 1699 1700 size_t ParamSize = FirstFunction->param_size(); 1701 for (unsigned I = 0; I < ParamSize; ++I) { 1702 const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I); 1703 const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I); 1704 1705 assert(Context.hasSameType(FirstParam->getType(), SecondParam->getType()) && 1706 "Merged function has different parameter types."); 1707 1708 if (FirstParam->getDeclName() != SecondParam->getDeclName()) { 1709 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(), 1710 ParameterName) 1711 << I + 1 << FirstParam->getDeclName(); 1712 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(), 1713 ParameterName) 1714 << I + 1 << SecondParam->getDeclName(); 1715 return true; 1716 }; 1717 1718 QualType FirstParamType = FirstParam->getType(); 1719 QualType SecondParamType = SecondParam->getType(); 1720 if (FirstParamType != SecondParamType && 1721 computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) { 1722 if (const DecayedType *ParamDecayedType = 1723 FirstParamType->getAs<DecayedType>()) { 1724 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(), 1725 ParameterType) 1726 << (I + 1) << FirstParamType << true 1727 << ParamDecayedType->getOriginalType(); 1728 } else { 1729 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(), 1730 ParameterType) 1731 << (I + 1) << FirstParamType << false; 1732 } 1733 1734 if (const DecayedType *ParamDecayedType = 1735 SecondParamType->getAs<DecayedType>()) { 1736 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(), 1737 ParameterType) 1738 << (I + 1) << SecondParamType << true 1739 << ParamDecayedType->getOriginalType(); 1740 } else { 1741 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(), 1742 ParameterType) 1743 << (I + 1) << SecondParamType << false; 1744 } 1745 return true; 1746 } 1747 1748 // Note, these calls can trigger deserialization. 1749 const Expr *FirstInit = FirstParam->getInit(); 1750 const Expr *SecondInit = SecondParam->getInit(); 1751 if ((FirstInit == nullptr) != (SecondInit == nullptr)) { 1752 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(), 1753 ParameterSingleDefaultArgument) 1754 << (I + 1) << (FirstInit == nullptr) 1755 << (FirstInit ? FirstInit->getSourceRange() : SourceRange()); 1756 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(), 1757 ParameterSingleDefaultArgument) 1758 << (I + 1) << (SecondInit == nullptr) 1759 << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); 1760 return true; 1761 } 1762 1763 if (FirstInit && SecondInit && 1764 computeODRHash(FirstInit) != computeODRHash(SecondInit)) { 1765 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(), 1766 ParameterDifferentDefaultArgument) 1767 << (I + 1) << FirstInit->getSourceRange(); 1768 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(), 1769 ParameterDifferentDefaultArgument) 1770 << (I + 1) << SecondInit->getSourceRange(); 1771 return true; 1772 } 1773 1774 assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) && 1775 "Undiagnosed parameter difference."); 1776 } 1777 1778 // If no error has been generated before now, assume the problem is in 1779 // the body and generate a message. 1780 DiagError(FirstFunction->getLocation(), FirstFunction->getSourceRange(), 1781 FunctionBody); 1782 DiagNote(SecondFunction->getLocation(), SecondFunction->getSourceRange(), 1783 FunctionBody); 1784 return true; 1785 } 1786 1787 bool ODRDiagsEmitter::diagnoseMismatch(const EnumDecl *FirstEnum, 1788 const EnumDecl *SecondEnum) const { 1789 if (FirstEnum == SecondEnum) 1790 return false; 1791 1792 // Keep in sync with select options in err_module_odr_violation_enum. 1793 enum ODREnumDifference { 1794 SingleScopedEnum, 1795 EnumTagKeywordMismatch, 1796 SingleSpecifiedType, 1797 DifferentSpecifiedTypes, 1798 DifferentNumberEnumConstants, 1799 EnumConstantName, 1800 EnumConstantSingleInitializer, 1801 EnumConstantDifferentInitializer, 1802 }; 1803 1804 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum); 1805 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondEnum); 1806 1807 auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor, 1808 ODREnumDifference DiffType) { 1809 return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum) 1810 << FirstEnum << FirstModule.empty() << FirstModule 1811 << DiagAnchor->getSourceRange() << DiffType; 1812 }; 1813 auto DiagNote = [&SecondModule, this](const auto *DiagAnchor, 1814 ODREnumDifference DiffType) { 1815 return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum) 1816 << SecondModule << DiagAnchor->getSourceRange() << DiffType; 1817 }; 1818 1819 if (FirstEnum->isScoped() != SecondEnum->isScoped()) { 1820 DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped(); 1821 DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped(); 1822 return true; 1823 } 1824 1825 if (FirstEnum->isScoped() && SecondEnum->isScoped()) { 1826 if (FirstEnum->isScopedUsingClassTag() != 1827 SecondEnum->isScopedUsingClassTag()) { 1828 DiagError(FirstEnum, EnumTagKeywordMismatch) 1829 << FirstEnum->isScopedUsingClassTag(); 1830 DiagNote(SecondEnum, EnumTagKeywordMismatch) 1831 << SecondEnum->isScopedUsingClassTag(); 1832 return true; 1833 } 1834 } 1835 1836 QualType FirstUnderlyingType = 1837 FirstEnum->getIntegerTypeSourceInfo() 1838 ? FirstEnum->getIntegerTypeSourceInfo()->getType() 1839 : QualType(); 1840 QualType SecondUnderlyingType = 1841 SecondEnum->getIntegerTypeSourceInfo() 1842 ? SecondEnum->getIntegerTypeSourceInfo()->getType() 1843 : QualType(); 1844 if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) { 1845 DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull(); 1846 DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull(); 1847 return true; 1848 } 1849 1850 if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) { 1851 if (computeODRHash(FirstUnderlyingType) != 1852 computeODRHash(SecondUnderlyingType)) { 1853 DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType; 1854 DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType; 1855 return true; 1856 } 1857 } 1858 1859 // Compare enum constants. 1860 using DeclHashes = 1861 llvm::SmallVector<std::pair<const EnumConstantDecl *, unsigned>, 4>; 1862 auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, const EnumDecl *Enum) { 1863 for (const Decl *D : Enum->decls()) { 1864 // Due to decl merging, the first EnumDecl is the parent of 1865 // Decls in both records. 1866 if (!ODRHash::isSubDeclToBeProcessed(D, FirstEnum)) 1867 continue; 1868 assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind"); 1869 Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D)); 1870 } 1871 }; 1872 DeclHashes FirstHashes; 1873 PopulateHashes(FirstHashes, FirstEnum); 1874 DeclHashes SecondHashes; 1875 PopulateHashes(SecondHashes, SecondEnum); 1876 1877 if (FirstHashes.size() != SecondHashes.size()) { 1878 DiagError(FirstEnum, DifferentNumberEnumConstants) 1879 << (int)FirstHashes.size(); 1880 DiagNote(SecondEnum, DifferentNumberEnumConstants) 1881 << (int)SecondHashes.size(); 1882 return true; 1883 } 1884 1885 for (unsigned I = 0, N = FirstHashes.size(); I < N; ++I) { 1886 if (FirstHashes[I].second == SecondHashes[I].second) 1887 continue; 1888 const EnumConstantDecl *FirstConstant = FirstHashes[I].first; 1889 const EnumConstantDecl *SecondConstant = SecondHashes[I].first; 1890 1891 if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) { 1892 DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant; 1893 DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant; 1894 return true; 1895 } 1896 1897 const Expr *FirstInit = FirstConstant->getInitExpr(); 1898 const Expr *SecondInit = SecondConstant->getInitExpr(); 1899 if (!FirstInit && !SecondInit) 1900 continue; 1901 1902 if (!FirstInit || !SecondInit) { 1903 DiagError(FirstConstant, EnumConstantSingleInitializer) 1904 << I + 1 << FirstConstant << (FirstInit != nullptr); 1905 DiagNote(SecondConstant, EnumConstantSingleInitializer) 1906 << I + 1 << SecondConstant << (SecondInit != nullptr); 1907 return true; 1908 } 1909 1910 if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) { 1911 DiagError(FirstConstant, EnumConstantDifferentInitializer) 1912 << I + 1 << FirstConstant; 1913 DiagNote(SecondConstant, EnumConstantDifferentInitializer) 1914 << I + 1 << SecondConstant; 1915 return true; 1916 } 1917 } 1918 return false; 1919 } 1920 1921 bool ODRDiagsEmitter::diagnoseMismatch( 1922 const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID, 1923 const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const { 1924 // Multiple different declarations got merged together; tell the user 1925 // where they came from. 1926 if (FirstID == SecondID) 1927 return false; 1928 1929 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstID); 1930 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondID); 1931 1932 // Keep in sync with err_module_odr_violation_objc_interface. 1933 enum ODRInterfaceDifference { 1934 SuperClassType, 1935 IVarAccess, 1936 }; 1937 1938 auto DiagError = [FirstID, &FirstModule, 1939 this](SourceLocation Loc, SourceRange Range, 1940 ODRInterfaceDifference DiffType) { 1941 return Diag(Loc, diag::err_module_odr_violation_objc_interface) 1942 << FirstID << FirstModule.empty() << FirstModule << Range 1943 << DiffType; 1944 }; 1945 auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range, 1946 ODRInterfaceDifference DiffType) { 1947 return Diag(Loc, diag::note_module_odr_violation_objc_interface) 1948 << SecondModule.empty() << SecondModule << Range << DiffType; 1949 }; 1950 1951 const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data(); 1952 assert(FirstDD && SecondDD && "Definitions without DefinitionData"); 1953 if (FirstDD != SecondDD) { 1954 // Check for matching super class. 1955 auto GetSuperClassSourceRange = [](const TypeSourceInfo *SuperInfo, 1956 const ObjCInterfaceDecl *ID) { 1957 if (!SuperInfo) 1958 return ID->getSourceRange(); 1959 TypeLoc Loc = SuperInfo->getTypeLoc(); 1960 return SourceRange(Loc.getBeginLoc(), Loc.getEndLoc()); 1961 }; 1962 1963 ObjCInterfaceDecl *FirstSuperClass = FirstID->getSuperClass(); 1964 ObjCInterfaceDecl *SecondSuperClass = nullptr; 1965 const TypeSourceInfo *FirstSuperInfo = FirstID->getSuperClassTInfo(); 1966 const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo; 1967 if (SecondSuperInfo) 1968 SecondSuperClass = 1969 SecondSuperInfo->getType()->castAs<ObjCObjectType>()->getInterface(); 1970 1971 if ((FirstSuperClass && SecondSuperClass && 1972 FirstSuperClass->getODRHash() != SecondSuperClass->getODRHash()) || 1973 (FirstSuperClass && !SecondSuperClass) || 1974 (!FirstSuperClass && SecondSuperClass)) { 1975 QualType FirstType; 1976 if (FirstSuperInfo) 1977 FirstType = FirstSuperInfo->getType(); 1978 1979 DiagError(FirstID->getLocation(), 1980 GetSuperClassSourceRange(FirstSuperInfo, FirstID), 1981 SuperClassType) 1982 << (bool)FirstSuperInfo << FirstType; 1983 1984 QualType SecondType; 1985 if (SecondSuperInfo) 1986 SecondType = SecondSuperInfo->getType(); 1987 1988 DiagNote(SecondID->getLocation(), 1989 GetSuperClassSourceRange(SecondSuperInfo, SecondID), 1990 SuperClassType) 1991 << (bool)SecondSuperInfo << SecondType; 1992 return true; 1993 } 1994 1995 // Check both interfaces reference the same protocols. 1996 auto &FirstProtos = FirstID->getReferencedProtocols(); 1997 auto &SecondProtos = SecondDD->ReferencedProtocols; 1998 if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule, 1999 SecondProtos, SecondID, SecondModule)) 2000 return true; 2001 } 2002 2003 auto PopulateHashes = [](DeclHashes &Hashes, const ObjCInterfaceDecl *ID, 2004 const DeclContext *DC) { 2005 for (auto *D : ID->decls()) { 2006 if (!ODRHash::isSubDeclToBeProcessed(D, DC)) 2007 continue; 2008 Hashes.emplace_back(D, computeODRHash(D)); 2009 } 2010 }; 2011 2012 DeclHashes FirstHashes; 2013 DeclHashes SecondHashes; 2014 // Use definition as DeclContext because definitions are merged when 2015 // DeclContexts are merged and separate when DeclContexts are separate. 2016 PopulateHashes(FirstHashes, FirstID, FirstID->getDefinition()); 2017 PopulateHashes(SecondHashes, SecondID, SecondID->getDefinition()); 2018 2019 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes); 2020 ODRMismatchDecl FirstDiffType = DR.FirstDiffType; 2021 ODRMismatchDecl SecondDiffType = DR.SecondDiffType; 2022 const Decl *FirstDecl = DR.FirstDecl; 2023 const Decl *SecondDecl = DR.SecondDecl; 2024 2025 if (FirstDiffType == Other || SecondDiffType == Other) { 2026 diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID, 2027 SecondModule); 2028 return true; 2029 } 2030 2031 if (FirstDiffType != SecondDiffType) { 2032 diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID, 2033 SecondModule); 2034 return true; 2035 } 2036 2037 assert(FirstDiffType == SecondDiffType); 2038 switch (FirstDiffType) { 2039 // Already handled. 2040 case EndOfClass: 2041 case Other: 2042 // Cannot be contained by ObjCInterfaceDecl, invalid in this context. 2043 case Field: 2044 case TypeDef: 2045 case Var: 2046 // C++ only, invalid in this context. 2047 case PublicSpecifer: 2048 case PrivateSpecifer: 2049 case ProtectedSpecifer: 2050 case StaticAssert: 2051 case CXXMethod: 2052 case TypeAlias: 2053 case Friend: 2054 case FunctionTemplate: 2055 llvm_unreachable("Invalid diff type"); 2056 2057 case ObjCMethod: { 2058 if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule, 2059 cast<ObjCMethodDecl>(FirstDecl), 2060 cast<ObjCMethodDecl>(SecondDecl))) 2061 return true; 2062 break; 2063 } 2064 case ObjCIvar: { 2065 if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule, 2066 cast<FieldDecl>(FirstDecl), 2067 cast<FieldDecl>(SecondDecl))) 2068 return true; 2069 2070 // Check if the access match. 2071 const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl); 2072 const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl); 2073 if (FirstIvar->getCanonicalAccessControl() != 2074 SecondIvar->getCanonicalAccessControl()) { 2075 DiagError(FirstIvar->getLocation(), FirstIvar->getSourceRange(), 2076 IVarAccess) 2077 << FirstIvar->getName() 2078 << (int)FirstIvar->getCanonicalAccessControl(); 2079 DiagNote(SecondIvar->getLocation(), SecondIvar->getSourceRange(), 2080 IVarAccess) 2081 << SecondIvar->getName() 2082 << (int)SecondIvar->getCanonicalAccessControl(); 2083 return true; 2084 } 2085 break; 2086 } 2087 case ObjCProperty: { 2088 if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule, 2089 cast<ObjCPropertyDecl>(FirstDecl), 2090 cast<ObjCPropertyDecl>(SecondDecl))) 2091 return true; 2092 break; 2093 } 2094 } 2095 2096 Diag(FirstDecl->getLocation(), 2097 diag::err_module_odr_violation_mismatch_decl_unknown) 2098 << FirstID << FirstModule.empty() << FirstModule << FirstDiffType 2099 << FirstDecl->getSourceRange(); 2100 Diag(SecondDecl->getLocation(), 2101 diag::note_module_odr_violation_mismatch_decl_unknown) 2102 << SecondModule.empty() << SecondModule << FirstDiffType 2103 << SecondDecl->getSourceRange(); 2104 return true; 2105 } 2106 2107 bool ODRDiagsEmitter::diagnoseMismatch( 2108 const ObjCProtocolDecl *FirstProtocol, 2109 const ObjCProtocolDecl *SecondProtocol, 2110 const struct ObjCProtocolDecl::DefinitionData *SecondDD) const { 2111 if (FirstProtocol == SecondProtocol) 2112 return false; 2113 2114 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstProtocol); 2115 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondProtocol); 2116 2117 const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data(); 2118 assert(FirstDD && SecondDD && "Definitions without DefinitionData"); 2119 // Diagnostics from ObjCProtocol DefinitionData are emitted here. 2120 if (FirstDD != SecondDD) { 2121 // Check both protocols reference the same protocols. 2122 const ObjCProtocolList &FirstProtocols = 2123 FirstProtocol->getReferencedProtocols(); 2124 const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols; 2125 if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule, 2126 SecondProtocols, SecondProtocol, 2127 SecondModule)) 2128 return true; 2129 } 2130 2131 auto PopulateHashes = [](DeclHashes &Hashes, const ObjCProtocolDecl *ID, 2132 const DeclContext *DC) { 2133 for (const Decl *D : ID->decls()) { 2134 if (!ODRHash::isSubDeclToBeProcessed(D, DC)) 2135 continue; 2136 Hashes.emplace_back(D, computeODRHash(D)); 2137 } 2138 }; 2139 2140 DeclHashes FirstHashes; 2141 DeclHashes SecondHashes; 2142 // Use definition as DeclContext because definitions are merged when 2143 // DeclContexts are merged and separate when DeclContexts are separate. 2144 PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition()); 2145 PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition()); 2146 2147 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes); 2148 ODRMismatchDecl FirstDiffType = DR.FirstDiffType; 2149 ODRMismatchDecl SecondDiffType = DR.SecondDiffType; 2150 const Decl *FirstDecl = DR.FirstDecl; 2151 const Decl *SecondDecl = DR.SecondDecl; 2152 2153 if (FirstDiffType == Other || SecondDiffType == Other) { 2154 diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule, 2155 SecondProtocol, SecondModule); 2156 return true; 2157 } 2158 2159 if (FirstDiffType != SecondDiffType) { 2160 diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule, 2161 SecondProtocol, SecondModule); 2162 return true; 2163 } 2164 2165 assert(FirstDiffType == SecondDiffType); 2166 switch (FirstDiffType) { 2167 // Already handled. 2168 case EndOfClass: 2169 case Other: 2170 // Cannot be contained by ObjCProtocolDecl, invalid in this context. 2171 case Field: 2172 case TypeDef: 2173 case Var: 2174 case ObjCIvar: 2175 // C++ only, invalid in this context. 2176 case PublicSpecifer: 2177 case PrivateSpecifer: 2178 case ProtectedSpecifer: 2179 case StaticAssert: 2180 case CXXMethod: 2181 case TypeAlias: 2182 case Friend: 2183 case FunctionTemplate: 2184 llvm_unreachable("Invalid diff type"); 2185 case ObjCMethod: { 2186 if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule, 2187 cast<ObjCMethodDecl>(FirstDecl), 2188 cast<ObjCMethodDecl>(SecondDecl))) 2189 return true; 2190 break; 2191 } 2192 case ObjCProperty: { 2193 if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule, 2194 SecondModule, 2195 cast<ObjCPropertyDecl>(FirstDecl), 2196 cast<ObjCPropertyDecl>(SecondDecl))) 2197 return true; 2198 break; 2199 } 2200 } 2201 2202 Diag(FirstDecl->getLocation(), 2203 diag::err_module_odr_violation_mismatch_decl_unknown) 2204 << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType 2205 << FirstDecl->getSourceRange(); 2206 Diag(SecondDecl->getLocation(), 2207 diag::note_module_odr_violation_mismatch_decl_unknown) 2208 << SecondModule.empty() << SecondModule << FirstDiffType 2209 << SecondDecl->getSourceRange(); 2210 return true; 2211 } 2212