brintos

brintos / llvm-project-archived public Read only

0
0
Text · 83.5 KiB · 74f3881 Raw
2217 lines · cpp
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-exception6//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 16using namespace clang;17 18static unsigned computeODRHash(QualType Ty) {19  ODRHash Hasher;20  Hasher.AddQualType(Ty);21  return Hasher.CalculateHash();22}23 24static unsigned computeODRHash(const Stmt *S) {25  ODRHash Hasher;26  Hasher.AddStmt(S);27  return Hasher.CalculateHash();28}29 30static unsigned computeODRHash(const Decl *D) {31  assert(D);32  ODRHash Hasher;33  Hasher.AddSubDecl(D);34  return Hasher.CalculateHash();35}36 37static unsigned computeODRHash(const TemplateArgument &TA) {38  ODRHash Hasher;39  Hasher.AddTemplateArgument(TA);40  return Hasher.CalculateHash();41}42 43std::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 52template <typename MethodT>53static 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() << FirstModule84           << FirstMethod->getSourceRange() << DiffType << FirstMethodType85           << 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() << SecondModule94           << SecondMethod->getSourceRange() << DiffType << SecondMethodType95           << 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 << true117                                 << 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 << true125                                << 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 144bool 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() << FirstModule161           << 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 246bool 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() << FirstModule259           << 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 286bool 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() << FirstModule303           << 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 361bool 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 << Range376           << 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 420bool 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/required428    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() << FirstModule438           << 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() << SecondModule445           << 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        << FirstMethod472        << FirstMethod->isThisDeclarationADesignatedInitializer();473    DiagNote(DesignatedInitializer)474        << SecondMethod475        << 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 a489  // less ideal diagnostics: a ObjCMethodName mismatch given that selectors490  // 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 502bool 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/required510    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() << FirstModule517           << 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() << SecondModule523           << 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 578ODRDiagsEmitter::DiffResult579ODRDiagsEmitter::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 648void 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 670void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(671    DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,672    const NamedDecl *SecondRecord, StringRef SecondModule) const {673  auto GetMismatchedDeclLoc = [](const NamedDecl *Container,674                                 ODRMismatchDecl DiffType, const Decl *D) {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      else683        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() << FirstModule695      << 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.second701      << DR.SecondDiffType;702}703 704bool 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 user708  // 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 << Range734             << 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      else876        ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;877 878      Diag(FirstDecl->getLocation(),879           diag::err_module_odr_violation_template_parameter)880          << FirstRecord << FirstModule.empty() << FirstModule881          << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg882          << FirstName;883      Diag(SecondDecl->getLocation(),884           diag::note_module_odr_violation_template_parameter)885          << SecondModule << SecondDecl->getSourceRange() << NoteDiffType886          << 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 and925  // note_module_odr_violation_record926  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 << Range961           << 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->isPureVirtual();1104    const bool SecondPure = SecondMethod->isPureVirtual();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 storage1114    // 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 means1241    // 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          TemplateArgument FirstTA =1411              FirstTTPD->getDefaultArgument().getArgument();1412          TemplateArgument SecondTA =1413              SecondTTPD->getDefaultArgument().getArgument();1414          if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {1415            DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)1416                << (i + 1) << FirstTA;1417            DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)1418                << (i + 1) << SecondTA;1419            return true;1420          }1421        }1422 1423        if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {1424          DiagTemplateError(FunctionTemplatePackParameter)1425              << (i + 1) << FirstTTPD->isParameterPack();1426          DiagTemplateNote(FunctionTemplatePackParameter)1427              << (i + 1) << SecondTTPD->isParameterPack();1428          return true;1429        }1430      }1431 1432      if (isa<TemplateTemplateParmDecl>(FirstParam) &&1433          isa<TemplateTemplateParmDecl>(SecondParam)) {1434        TemplateTemplateParmDecl *FirstTTPD =1435            cast<TemplateTemplateParmDecl>(FirstParam);1436        TemplateTemplateParmDecl *SecondTTPD =1437            cast<TemplateTemplateParmDecl>(SecondParam);1438 1439        TemplateParameterList *FirstTPL = FirstTTPD->getTemplateParameters();1440        TemplateParameterList *SecondTPL = SecondTTPD->getTemplateParameters();1441 1442        auto ComputeTemplateParameterListODRHash =1443            [](const TemplateParameterList *TPL) {1444              assert(TPL);1445              ODRHash Hasher;1446              Hasher.AddTemplateParameterList(TPL);1447              return Hasher.CalculateHash();1448            };1449 1450        if (ComputeTemplateParameterListODRHash(FirstTPL) !=1451            ComputeTemplateParameterListODRHash(SecondTPL)) {1452          DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);1453          DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);1454          return true;1455        }1456 1457        bool HasFirstDefaultArgument =1458            FirstTTPD->hasDefaultArgument() &&1459            !FirstTTPD->defaultArgumentWasInherited();1460        bool HasSecondDefaultArgument =1461            SecondTTPD->hasDefaultArgument() &&1462            !SecondTTPD->defaultArgumentWasInherited();1463        if (HasFirstDefaultArgument != HasSecondDefaultArgument) {1464          DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)1465              << (i + 1) << HasFirstDefaultArgument;1466          DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)1467              << (i + 1) << HasSecondDefaultArgument;1468          return true;1469        }1470 1471        if (HasFirstDefaultArgument && HasSecondDefaultArgument) {1472          TemplateArgument FirstTA =1473              FirstTTPD->getDefaultArgument().getArgument();1474          TemplateArgument SecondTA =1475              SecondTTPD->getDefaultArgument().getArgument();1476          if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {1477            DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)1478                << (i + 1) << FirstTA;1479            DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)1480                << (i + 1) << SecondTA;1481            return true;1482          }1483        }1484 1485        if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {1486          DiagTemplateError(FunctionTemplatePackParameter)1487              << (i + 1) << FirstTTPD->isParameterPack();1488          DiagTemplateNote(FunctionTemplatePackParameter)1489              << (i + 1) << SecondTTPD->isParameterPack();1490          return true;1491        }1492      }1493 1494      if (isa<NonTypeTemplateParmDecl>(FirstParam) &&1495          isa<NonTypeTemplateParmDecl>(SecondParam)) {1496        NonTypeTemplateParmDecl *FirstNTTPD =1497            cast<NonTypeTemplateParmDecl>(FirstParam);1498        NonTypeTemplateParmDecl *SecondNTTPD =1499            cast<NonTypeTemplateParmDecl>(SecondParam);1500 1501        QualType FirstType = FirstNTTPD->getType();1502        QualType SecondType = SecondNTTPD->getType();1503        if (computeODRHash(FirstType) != computeODRHash(SecondType)) {1504          DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);1505          DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);1506          return true;1507        }1508 1509        bool HasFirstDefaultArgument =1510            FirstNTTPD->hasDefaultArgument() &&1511            !FirstNTTPD->defaultArgumentWasInherited();1512        bool HasSecondDefaultArgument =1513            SecondNTTPD->hasDefaultArgument() &&1514            !SecondNTTPD->defaultArgumentWasInherited();1515        if (HasFirstDefaultArgument != HasSecondDefaultArgument) {1516          DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)1517              << (i + 1) << HasFirstDefaultArgument;1518          DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)1519              << (i + 1) << HasSecondDefaultArgument;1520          return true;1521        }1522 1523        if (HasFirstDefaultArgument && HasSecondDefaultArgument) {1524          TemplateArgument FirstDefaultArgument =1525              FirstNTTPD->getDefaultArgument().getArgument();1526          TemplateArgument SecondDefaultArgument =1527              SecondNTTPD->getDefaultArgument().getArgument();1528 1529          if (computeODRHash(FirstDefaultArgument) !=1530              computeODRHash(SecondDefaultArgument)) {1531            DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)1532                << (i + 1) << FirstDefaultArgument;1533            DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)1534                << (i + 1) << SecondDefaultArgument;1535            return true;1536          }1537        }1538 1539        if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) {1540          DiagTemplateError(FunctionTemplatePackParameter)1541              << (i + 1) << FirstNTTPD->isParameterPack();1542          DiagTemplateNote(FunctionTemplatePackParameter)1543              << (i + 1) << SecondNTTPD->isParameterPack();1544          return true;1545        }1546      }1547    }1548    break;1549  }1550  }1551 1552  Diag(FirstDecl->getLocation(),1553       diag::err_module_odr_violation_mismatch_decl_unknown)1554      << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType1555      << FirstDecl->getSourceRange();1556  Diag(SecondDecl->getLocation(),1557       diag::note_module_odr_violation_mismatch_decl_unknown)1558      << SecondModule.empty() << SecondModule << FirstDiffType1559      << SecondDecl->getSourceRange();1560  return true;1561}1562 1563bool ODRDiagsEmitter::diagnoseMismatch(const RecordDecl *FirstRecord,1564                                       const RecordDecl *SecondRecord) const {1565  if (FirstRecord == SecondRecord)1566    return false;1567 1568  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);1569  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);1570 1571  auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,1572                           const DeclContext *DC) {1573    for (const Decl *D : Record->decls()) {1574      if (!ODRHash::isSubDeclToBeProcessed(D, DC))1575        continue;1576      Hashes.emplace_back(D, computeODRHash(D));1577    }1578  };1579 1580  DeclHashes FirstHashes;1581  DeclHashes SecondHashes;1582  const DeclContext *DC = FirstRecord;1583  PopulateHashes(FirstHashes, FirstRecord, DC);1584  PopulateHashes(SecondHashes, SecondRecord, DC);1585 1586  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);1587  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;1588  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;1589  const Decl *FirstDecl = DR.FirstDecl;1590  const Decl *SecondDecl = DR.SecondDecl;1591 1592  if (FirstDiffType == Other || SecondDiffType == Other) {1593    diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,1594                                  SecondModule);1595    return true;1596  }1597 1598  if (FirstDiffType != SecondDiffType) {1599    diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,1600                                          SecondRecord, SecondModule);1601    return true;1602  }1603 1604  assert(FirstDiffType == SecondDiffType);1605  switch (FirstDiffType) {1606  // Already handled.1607  case EndOfClass:1608  case Other:1609  // C++ only, invalid in this context.1610  case PublicSpecifer:1611  case PrivateSpecifer:1612  case ProtectedSpecifer:1613  case StaticAssert:1614  case CXXMethod:1615  case TypeAlias:1616  case Friend:1617  case FunctionTemplate:1618  // Cannot be contained by RecordDecl, invalid in this context.1619  case ObjCMethod:1620  case ObjCIvar:1621  case ObjCProperty:1622    llvm_unreachable("Invalid diff type");1623 1624  case Field: {1625    if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,1626                                 cast<FieldDecl>(FirstDecl),1627                                 cast<FieldDecl>(SecondDecl)))1628      return true;1629    break;1630  }1631  case TypeDef: {1632    if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,1633                                   cast<TypedefNameDecl>(FirstDecl),1634                                   cast<TypedefNameDecl>(SecondDecl),1635                                   /*IsTypeAlias=*/false))1636      return true;1637    break;1638  }1639  case Var: {1640    if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,1641                               cast<VarDecl>(FirstDecl),1642                               cast<VarDecl>(SecondDecl)))1643      return true;1644    break;1645  }1646  }1647 1648  Diag(FirstDecl->getLocation(),1649       diag::err_module_odr_violation_mismatch_decl_unknown)1650      << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType1651      << FirstDecl->getSourceRange();1652  Diag(SecondDecl->getLocation(),1653       diag::note_module_odr_violation_mismatch_decl_unknown)1654      << SecondModule.empty() << SecondModule << FirstDiffType1655      << SecondDecl->getSourceRange();1656  return true;1657}1658 1659bool ODRDiagsEmitter::diagnoseMismatch(1660    const FunctionDecl *FirstFunction,1661    const FunctionDecl *SecondFunction) const {1662  if (FirstFunction == SecondFunction)1663    return false;1664 1665  // Keep in sync with select options in err_module_odr_violation_function.1666  enum ODRFunctionDifference {1667    ReturnType,1668    ParameterName,1669    ParameterType,1670    ParameterSingleDefaultArgument,1671    ParameterDifferentDefaultArgument,1672    FunctionBody,1673  };1674 1675  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);1676  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondFunction);1677 1678  auto DiagError = [FirstFunction, &FirstModule,1679                    this](SourceLocation Loc, SourceRange Range,1680                          ODRFunctionDifference DiffType) {1681    return Diag(Loc, diag::err_module_odr_violation_function)1682           << FirstFunction << FirstModule.empty() << FirstModule << Range1683           << DiffType;1684  };1685  auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,1686                                        ODRFunctionDifference DiffType) {1687    return Diag(Loc, diag::note_module_odr_violation_function)1688           << SecondModule << Range << DiffType;1689  };1690 1691  if (computeODRHash(FirstFunction->getReturnType()) !=1692      computeODRHash(SecondFunction->getReturnType())) {1693    DiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),1694              FirstFunction->getReturnTypeSourceRange(), ReturnType)1695        << FirstFunction->getReturnType();1696    DiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),1697             SecondFunction->getReturnTypeSourceRange(), ReturnType)1698        << SecondFunction->getReturnType();1699    return true;1700  }1701 1702  assert(FirstFunction->param_size() == SecondFunction->param_size() &&1703         "Merged functions with different number of parameters");1704 1705  size_t ParamSize = FirstFunction->param_size();1706  for (unsigned I = 0; I < ParamSize; ++I) {1707    const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I);1708    const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I);1709 1710    assert(Context.hasSameType(FirstParam->getType(), SecondParam->getType()) &&1711           "Merged function has different parameter types.");1712 1713    if (FirstParam->getDeclName() != SecondParam->getDeclName()) {1714      DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),1715                ParameterName)1716          << I + 1 << FirstParam->getDeclName();1717      DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),1718               ParameterName)1719          << I + 1 << SecondParam->getDeclName();1720      return true;1721    };1722 1723    QualType FirstParamType = FirstParam->getType();1724    QualType SecondParamType = SecondParam->getType();1725    if (FirstParamType != SecondParamType &&1726        computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) {1727      if (const DecayedType *ParamDecayedType =1728              FirstParamType->getAs<DecayedType>()) {1729        DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),1730                  ParameterType)1731            << (I + 1) << FirstParamType << true1732            << ParamDecayedType->getOriginalType();1733      } else {1734        DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),1735                  ParameterType)1736            << (I + 1) << FirstParamType << false;1737      }1738 1739      if (const DecayedType *ParamDecayedType =1740              SecondParamType->getAs<DecayedType>()) {1741        DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),1742                 ParameterType)1743            << (I + 1) << SecondParamType << true1744            << ParamDecayedType->getOriginalType();1745      } else {1746        DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),1747                 ParameterType)1748            << (I + 1) << SecondParamType << false;1749      }1750      return true;1751    }1752 1753    // Note, these calls can trigger deserialization.1754    const Expr *FirstInit = FirstParam->getInit();1755    const Expr *SecondInit = SecondParam->getInit();1756    if ((FirstInit == nullptr) != (SecondInit == nullptr)) {1757      DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),1758                ParameterSingleDefaultArgument)1759          << (I + 1) << (FirstInit == nullptr)1760          << (FirstInit ? FirstInit->getSourceRange() : SourceRange());1761      DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),1762               ParameterSingleDefaultArgument)1763          << (I + 1) << (SecondInit == nullptr)1764          << (SecondInit ? SecondInit->getSourceRange() : SourceRange());1765      return true;1766    }1767 1768    if (FirstInit && SecondInit &&1769        computeODRHash(FirstInit) != computeODRHash(SecondInit)) {1770      DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),1771                ParameterDifferentDefaultArgument)1772          << (I + 1) << FirstInit->getSourceRange();1773      DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),1774               ParameterDifferentDefaultArgument)1775          << (I + 1) << SecondInit->getSourceRange();1776      return true;1777    }1778 1779    assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) &&1780           "Undiagnosed parameter difference.");1781  }1782 1783  // If no error has been generated before now, assume the problem is in1784  // the body and generate a message.1785  DiagError(FirstFunction->getLocation(), FirstFunction->getSourceRange(),1786            FunctionBody);1787  DiagNote(SecondFunction->getLocation(), SecondFunction->getSourceRange(),1788           FunctionBody);1789  return true;1790}1791 1792bool ODRDiagsEmitter::diagnoseMismatch(const EnumDecl *FirstEnum,1793                                       const EnumDecl *SecondEnum) const {1794  if (FirstEnum == SecondEnum)1795    return false;1796 1797  // Keep in sync with select options in err_module_odr_violation_enum.1798  enum ODREnumDifference {1799    SingleScopedEnum,1800    EnumTagKeywordMismatch,1801    SingleSpecifiedType,1802    DifferentSpecifiedTypes,1803    DifferentNumberEnumConstants,1804    EnumConstantName,1805    EnumConstantSingleInitializer,1806    EnumConstantDifferentInitializer,1807  };1808 1809  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum);1810  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondEnum);1811 1812  auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor,1813                                                   ODREnumDifference DiffType) {1814    return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)1815           << FirstEnum << FirstModule.empty() << FirstModule1816           << DiagAnchor->getSourceRange() << DiffType;1817  };1818  auto DiagNote = [&SecondModule, this](const auto *DiagAnchor,1819                                        ODREnumDifference DiffType) {1820    return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)1821           << SecondModule << DiagAnchor->getSourceRange() << DiffType;1822  };1823 1824  if (FirstEnum->isScoped() != SecondEnum->isScoped()) {1825    DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();1826    DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();1827    return true;1828  }1829 1830  if (FirstEnum->isScoped() && SecondEnum->isScoped()) {1831    if (FirstEnum->isScopedUsingClassTag() !=1832        SecondEnum->isScopedUsingClassTag()) {1833      DiagError(FirstEnum, EnumTagKeywordMismatch)1834          << FirstEnum->isScopedUsingClassTag();1835      DiagNote(SecondEnum, EnumTagKeywordMismatch)1836          << SecondEnum->isScopedUsingClassTag();1837      return true;1838    }1839  }1840 1841  QualType FirstUnderlyingType =1842      FirstEnum->getIntegerTypeSourceInfo()1843          ? FirstEnum->getIntegerTypeSourceInfo()->getType()1844          : QualType();1845  QualType SecondUnderlyingType =1846      SecondEnum->getIntegerTypeSourceInfo()1847          ? SecondEnum->getIntegerTypeSourceInfo()->getType()1848          : QualType();1849  if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {1850    DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull();1851    DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull();1852    return true;1853  }1854 1855  if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {1856    if (computeODRHash(FirstUnderlyingType) !=1857        computeODRHash(SecondUnderlyingType)) {1858      DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;1859      DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;1860      return true;1861    }1862  }1863 1864  // Compare enum constants.1865  using DeclHashes =1866      llvm::SmallVector<std::pair<const EnumConstantDecl *, unsigned>, 4>;1867  auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, const EnumDecl *Enum) {1868    for (const Decl *D : Enum->decls()) {1869      // Due to decl merging, the first EnumDecl is the parent of1870      // Decls in both records.1871      if (!ODRHash::isSubDeclToBeProcessed(D, FirstEnum))1872        continue;1873      assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");1874      Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D));1875    }1876  };1877  DeclHashes FirstHashes;1878  PopulateHashes(FirstHashes, FirstEnum);1879  DeclHashes SecondHashes;1880  PopulateHashes(SecondHashes, SecondEnum);1881 1882  if (FirstHashes.size() != SecondHashes.size()) {1883    DiagError(FirstEnum, DifferentNumberEnumConstants)1884        << (int)FirstHashes.size();1885    DiagNote(SecondEnum, DifferentNumberEnumConstants)1886        << (int)SecondHashes.size();1887    return true;1888  }1889 1890  for (unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {1891    if (FirstHashes[I].second == SecondHashes[I].second)1892      continue;1893    const EnumConstantDecl *FirstConstant = FirstHashes[I].first;1894    const EnumConstantDecl *SecondConstant = SecondHashes[I].first;1895 1896    if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) {1897      DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;1898      DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;1899      return true;1900    }1901 1902    const Expr *FirstInit = FirstConstant->getInitExpr();1903    const Expr *SecondInit = SecondConstant->getInitExpr();1904    if (!FirstInit && !SecondInit)1905      continue;1906 1907    if (!FirstInit || !SecondInit) {1908      DiagError(FirstConstant, EnumConstantSingleInitializer)1909          << I + 1 << FirstConstant << (FirstInit != nullptr);1910      DiagNote(SecondConstant, EnumConstantSingleInitializer)1911          << I + 1 << SecondConstant << (SecondInit != nullptr);1912      return true;1913    }1914 1915    if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) {1916      DiagError(FirstConstant, EnumConstantDifferentInitializer)1917          << I + 1 << FirstConstant;1918      DiagNote(SecondConstant, EnumConstantDifferentInitializer)1919          << I + 1 << SecondConstant;1920      return true;1921    }1922  }1923  return false;1924}1925 1926bool ODRDiagsEmitter::diagnoseMismatch(1927    const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,1928    const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const {1929  // Multiple different declarations got merged together; tell the user1930  // where they came from.1931  if (FirstID == SecondID)1932    return false;1933 1934  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstID);1935  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondID);1936 1937  // Keep in sync with err_module_odr_violation_objc_interface.1938  enum ODRInterfaceDifference {1939    SuperClassType,1940    IVarAccess,1941  };1942 1943  auto DiagError = [FirstID, &FirstModule,1944                    this](SourceLocation Loc, SourceRange Range,1945                          ODRInterfaceDifference DiffType) {1946    return Diag(Loc, diag::err_module_odr_violation_objc_interface)1947           << FirstID << FirstModule.empty() << FirstModule << Range1948           << DiffType;1949  };1950  auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,1951                                        ODRInterfaceDifference DiffType) {1952    return Diag(Loc, diag::note_module_odr_violation_objc_interface)1953           << SecondModule.empty() << SecondModule << Range << DiffType;1954  };1955 1956  const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();1957  assert(FirstDD && SecondDD && "Definitions without DefinitionData");1958  if (FirstDD != SecondDD) {1959    // Check for matching super class.1960    auto GetSuperClassSourceRange = [](const TypeSourceInfo *SuperInfo,1961                                       const ObjCInterfaceDecl *ID) {1962      if (!SuperInfo)1963        return ID->getSourceRange();1964      TypeLoc Loc = SuperInfo->getTypeLoc();1965      return SourceRange(Loc.getBeginLoc(), Loc.getEndLoc());1966    };1967 1968    ObjCInterfaceDecl *FirstSuperClass = FirstID->getSuperClass();1969    ObjCInterfaceDecl *SecondSuperClass = nullptr;1970    const TypeSourceInfo *FirstSuperInfo = FirstID->getSuperClassTInfo();1971    const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;1972    if (SecondSuperInfo)1973      SecondSuperClass =1974          SecondSuperInfo->getType()->castAs<ObjCObjectType>()->getInterface();1975 1976    if ((FirstSuperClass && SecondSuperClass &&1977         FirstSuperClass->getODRHash() != SecondSuperClass->getODRHash()) ||1978        (FirstSuperClass && !SecondSuperClass) ||1979        (!FirstSuperClass && SecondSuperClass)) {1980      QualType FirstType;1981      if (FirstSuperInfo)1982        FirstType = FirstSuperInfo->getType();1983 1984      DiagError(FirstID->getLocation(),1985                GetSuperClassSourceRange(FirstSuperInfo, FirstID),1986                SuperClassType)1987          << (bool)FirstSuperInfo << FirstType;1988 1989      QualType SecondType;1990      if (SecondSuperInfo)1991        SecondType = SecondSuperInfo->getType();1992 1993      DiagNote(SecondID->getLocation(),1994               GetSuperClassSourceRange(SecondSuperInfo, SecondID),1995               SuperClassType)1996          << (bool)SecondSuperInfo << SecondType;1997      return true;1998    }1999 2000    // Check both interfaces reference the same protocols.2001    auto &FirstProtos = FirstID->getReferencedProtocols();2002    auto &SecondProtos = SecondDD->ReferencedProtocols;2003    if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,2004                                     SecondProtos, SecondID, SecondModule))2005      return true;2006  }2007 2008  auto PopulateHashes = [](DeclHashes &Hashes, const ObjCInterfaceDecl *ID,2009                           const DeclContext *DC) {2010    for (auto *D : ID->decls()) {2011      if (!ODRHash::isSubDeclToBeProcessed(D, DC))2012        continue;2013      Hashes.emplace_back(D, computeODRHash(D));2014    }2015  };2016 2017  DeclHashes FirstHashes;2018  DeclHashes SecondHashes;2019  // Use definition as DeclContext because definitions are merged when2020  // DeclContexts are merged and separate when DeclContexts are separate.2021  PopulateHashes(FirstHashes, FirstID, FirstID->getDefinition());2022  PopulateHashes(SecondHashes, SecondID, SecondID->getDefinition());2023 2024  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);2025  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;2026  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;2027  const Decl *FirstDecl = DR.FirstDecl;2028  const Decl *SecondDecl = DR.SecondDecl;2029 2030  if (FirstDiffType == Other || SecondDiffType == Other) {2031    diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,2032                                  SecondModule);2033    return true;2034  }2035 2036  if (FirstDiffType != SecondDiffType) {2037    diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,2038                                          SecondModule);2039    return true;2040  }2041 2042  assert(FirstDiffType == SecondDiffType);2043  switch (FirstDiffType) {2044  // Already handled.2045  case EndOfClass:2046  case Other:2047  // Cannot be contained by ObjCInterfaceDecl, invalid in this context.2048  case Field:2049  case TypeDef:2050  case Var:2051  // C++ only, invalid in this context.2052  case PublicSpecifer:2053  case PrivateSpecifer:2054  case ProtectedSpecifer:2055  case StaticAssert:2056  case CXXMethod:2057  case TypeAlias:2058  case Friend:2059  case FunctionTemplate:2060    llvm_unreachable("Invalid diff type");2061 2062  case ObjCMethod: {2063    if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,2064                                      cast<ObjCMethodDecl>(FirstDecl),2065                                      cast<ObjCMethodDecl>(SecondDecl)))2066      return true;2067    break;2068  }2069  case ObjCIvar: {2070    if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,2071                                 cast<FieldDecl>(FirstDecl),2072                                 cast<FieldDecl>(SecondDecl)))2073      return true;2074 2075    // Check if the access match.2076    const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl);2077    const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl);2078    if (FirstIvar->getCanonicalAccessControl() !=2079        SecondIvar->getCanonicalAccessControl()) {2080      DiagError(FirstIvar->getLocation(), FirstIvar->getSourceRange(),2081                IVarAccess)2082          << FirstIvar->getName()2083          << (int)FirstIvar->getCanonicalAccessControl();2084      DiagNote(SecondIvar->getLocation(), SecondIvar->getSourceRange(),2085               IVarAccess)2086          << SecondIvar->getName()2087          << (int)SecondIvar->getCanonicalAccessControl();2088      return true;2089    }2090    break;2091  }2092  case ObjCProperty: {2093    if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,2094                                        cast<ObjCPropertyDecl>(FirstDecl),2095                                        cast<ObjCPropertyDecl>(SecondDecl)))2096      return true;2097    break;2098  }2099  }2100 2101  Diag(FirstDecl->getLocation(),2102       diag::err_module_odr_violation_mismatch_decl_unknown)2103      << FirstID << FirstModule.empty() << FirstModule << FirstDiffType2104      << FirstDecl->getSourceRange();2105  Diag(SecondDecl->getLocation(),2106       diag::note_module_odr_violation_mismatch_decl_unknown)2107      << SecondModule.empty() << SecondModule << FirstDiffType2108      << SecondDecl->getSourceRange();2109  return true;2110}2111 2112bool ODRDiagsEmitter::diagnoseMismatch(2113    const ObjCProtocolDecl *FirstProtocol,2114    const ObjCProtocolDecl *SecondProtocol,2115    const struct ObjCProtocolDecl::DefinitionData *SecondDD) const {2116  if (FirstProtocol == SecondProtocol)2117    return false;2118 2119  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstProtocol);2120  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondProtocol);2121 2122  const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();2123  assert(FirstDD && SecondDD && "Definitions without DefinitionData");2124  // Diagnostics from ObjCProtocol DefinitionData are emitted here.2125  if (FirstDD != SecondDD) {2126    // Check both protocols reference the same protocols.2127    const ObjCProtocolList &FirstProtocols =2128        FirstProtocol->getReferencedProtocols();2129    const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols;2130    if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,2131                                     SecondProtocols, SecondProtocol,2132                                     SecondModule))2133      return true;2134  }2135 2136  auto PopulateHashes = [](DeclHashes &Hashes, const ObjCProtocolDecl *ID,2137                           const DeclContext *DC) {2138    for (const Decl *D : ID->decls()) {2139      if (!ODRHash::isSubDeclToBeProcessed(D, DC))2140        continue;2141      Hashes.emplace_back(D, computeODRHash(D));2142    }2143  };2144 2145  DeclHashes FirstHashes;2146  DeclHashes SecondHashes;2147  // Use definition as DeclContext because definitions are merged when2148  // DeclContexts are merged and separate when DeclContexts are separate.2149  PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition());2150  PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition());2151 2152  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);2153  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;2154  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;2155  const Decl *FirstDecl = DR.FirstDecl;2156  const Decl *SecondDecl = DR.SecondDecl;2157 2158  if (FirstDiffType == Other || SecondDiffType == Other) {2159    diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,2160                                  SecondProtocol, SecondModule);2161    return true;2162  }2163 2164  if (FirstDiffType != SecondDiffType) {2165    diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,2166                                          SecondProtocol, SecondModule);2167    return true;2168  }2169 2170  assert(FirstDiffType == SecondDiffType);2171  switch (FirstDiffType) {2172  // Already handled.2173  case EndOfClass:2174  case Other:2175  // Cannot be contained by ObjCProtocolDecl, invalid in this context.2176  case Field:2177  case TypeDef:2178  case Var:2179  case ObjCIvar:2180  // C++ only, invalid in this context.2181  case PublicSpecifer:2182  case PrivateSpecifer:2183  case ProtectedSpecifer:2184  case StaticAssert:2185  case CXXMethod:2186  case TypeAlias:2187  case Friend:2188  case FunctionTemplate:2189    llvm_unreachable("Invalid diff type");2190  case ObjCMethod: {2191    if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,2192                                      cast<ObjCMethodDecl>(FirstDecl),2193                                      cast<ObjCMethodDecl>(SecondDecl)))2194      return true;2195    break;2196  }2197  case ObjCProperty: {2198    if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,2199                                        SecondModule,2200                                        cast<ObjCPropertyDecl>(FirstDecl),2201                                        cast<ObjCPropertyDecl>(SecondDecl)))2202      return true;2203    break;2204  }2205  }2206 2207  Diag(FirstDecl->getLocation(),2208       diag::err_module_odr_violation_mismatch_decl_unknown)2209      << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType2210      << FirstDecl->getSourceRange();2211  Diag(SecondDecl->getLocation(),2212       diag::note_module_odr_violation_mismatch_decl_unknown)2213      << SecondModule.empty() << SecondModule << FirstDiffType2214      << SecondDecl->getSourceRange();2215  return true;2216}2217