diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 21f6a36565ef..5351ac31c179 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9451,6 +9451,446 @@ void ASTReader::diagnoseOdrViolations() { return Hash.CalculateHash(); }; + // Used with err_module_odr_violation_mismatch_decl and + // note_module_odr_violation_mismatch_decl + // This list should be the same Decl's as in ODRHash::isWhiteListedDecl + enum ODRMismatchDecl { + EndOfClass, + PublicSpecifer, + PrivateSpecifer, + ProtectedSpecifer, + StaticAssert, + Field, + CXXMethod, + TypeAlias, + TypeDef, + Var, + Friend, + FunctionTemplate, + Other + }; + + // Used with err_module_odr_violation_mismatch_decl_diff and + // note_module_odr_violation_mismatch_decl_diff + enum ODRMismatchDeclDifference { + StaticAssertCondition, + StaticAssertMessage, + StaticAssertOnlyMessage, + FieldName, + FieldTypeName, + FieldSingleBitField, + FieldDifferentWidthBitField, + FieldSingleMutable, + FieldSingleInitializer, + FieldDifferentInitializers, + MethodName, + MethodDeleted, + MethodDefaulted, + MethodVirtual, + MethodStatic, + MethodVolatile, + MethodConst, + MethodInline, + MethodNumberParameters, + MethodParameterType, + MethodParameterName, + MethodParameterSingleDefaultArgument, + MethodParameterDifferentDefaultArgument, + MethodNoTemplateArguments, + MethodDifferentNumberTemplateArguments, + MethodDifferentTemplateArgument, + MethodSingleBody, + MethodDifferentBody, + TypedefName, + TypedefType, + VarName, + VarType, + VarSingleInitializer, + VarDifferentInitializer, + VarConstexpr, + FriendTypeFunction, + FriendType, + FriendFunction, + FunctionTemplateDifferentNumberParameters, + FunctionTemplateParameterDifferentKind, + FunctionTemplateParameterName, + FunctionTemplateParameterSingleDefaultArgument, + FunctionTemplateParameterDifferentDefaultArgument, + FunctionTemplateParameterDifferentType, + FunctionTemplatePackParameter, + }; + + // These lambdas have the common portions of the ODR diagnostics. This + // has the same return as Diag(), so addition parameters can be passed + // in with operator<< + auto ODRDiagDeclError = [this](NamedDecl *FirstRecord, StringRef FirstModule, + SourceLocation Loc, SourceRange Range, + ODRMismatchDeclDifference DiffType) { + return Diag(Loc, diag::err_module_odr_violation_mismatch_decl_diff) + << FirstRecord << FirstModule.empty() << FirstModule << Range + << DiffType; + }; + auto ODRDiagDeclNote = [this](StringRef SecondModule, SourceLocation Loc, + SourceRange Range, ODRMismatchDeclDifference DiffType) { + return Diag(Loc, diag::note_module_odr_violation_mismatch_decl_diff) + << SecondModule << Range << DiffType; + }; + + auto ODRDiagField = [this, &ODRDiagDeclError, &ODRDiagDeclNote, + &ComputeQualTypeODRHash, &ComputeODRHash]( + NamedDecl *FirstRecord, StringRef FirstModule, + StringRef SecondModule, FieldDecl *FirstField, + FieldDecl *SecondField) { + IdentifierInfo *FirstII = FirstField->getIdentifier(); + IdentifierInfo *SecondII = SecondField->getIdentifier(); + if (FirstII->getName() != SecondII->getName()) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldName) + << FirstII; + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldName) + << SecondII; + + return true; + } + + assert(getContext().hasSameType(FirstField->getType(), + SecondField->getType())); + + QualType FirstType = FirstField->getType(); + QualType SecondType = SecondField->getType(); + if (ComputeQualTypeODRHash(FirstType) != + ComputeQualTypeODRHash(SecondType)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldTypeName) + << FirstII << FirstType; + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldTypeName) + << SecondII << SecondType; + + return true; + } + + const bool IsFirstBitField = FirstField->isBitField(); + const bool IsSecondBitField = SecondField->isBitField(); + if (IsFirstBitField != IsSecondBitField) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldSingleBitField) + << FirstII << IsFirstBitField; + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldSingleBitField) + << SecondII << IsSecondBitField; + return true; + } + + if (IsFirstBitField && IsSecondBitField) { + unsigned FirstBitWidthHash = + ComputeODRHash(FirstField->getBitWidth()); + unsigned SecondBitWidthHash = + ComputeODRHash(SecondField->getBitWidth()); + if (FirstBitWidthHash != SecondBitWidthHash) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), + FieldDifferentWidthBitField) + << FirstII << FirstField->getBitWidth()->getSourceRange(); + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), + FieldDifferentWidthBitField) + << SecondII << SecondField->getBitWidth()->getSourceRange(); + return true; + } + } + + if (!PP.getLangOpts().CPlusPlus) + return false; + + const bool IsFirstMutable = FirstField->isMutable(); + const bool IsSecondMutable = SecondField->isMutable(); + if (IsFirstMutable != IsSecondMutable) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldSingleMutable) + << FirstII << IsFirstMutable; + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldSingleMutable) + << SecondII << IsSecondMutable; + return true; + } + + const Expr *FirstInitializer = FirstField->getInClassInitializer(); + const Expr *SecondInitializer = SecondField->getInClassInitializer(); + if ((!FirstInitializer && SecondInitializer) || + (FirstInitializer && !SecondInitializer)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldSingleInitializer) + << FirstII << (FirstInitializer != nullptr); + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldSingleInitializer) + << SecondII << (SecondInitializer != nullptr); + return true; + } + + if (FirstInitializer && SecondInitializer) { + unsigned FirstInitHash = ComputeODRHash(FirstInitializer); + unsigned SecondInitHash = ComputeODRHash(SecondInitializer); + if (FirstInitHash != SecondInitHash) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), + FieldDifferentInitializers) + << FirstII << FirstInitializer->getSourceRange(); + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), + FieldDifferentInitializers) + << SecondII << SecondInitializer->getSourceRange(); + return true; + } + } + + return false; + }; + + auto ODRDiagTypeDefOrAlias = + [&ODRDiagDeclError, &ODRDiagDeclNote, &ComputeQualTypeODRHash]( + NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule, + TypedefNameDecl *FirstTD, TypedefNameDecl *SecondTD, + bool IsTypeAlias) { + auto FirstName = FirstTD->getDeclName(); + auto SecondName = SecondTD->getDeclName(); + if (FirstName != SecondName) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstTD->getLocation(), + FirstTD->getSourceRange(), TypedefName) + << IsTypeAlias << FirstName; + ODRDiagDeclNote(SecondModule, SecondTD->getLocation(), + SecondTD->getSourceRange(), TypedefName) + << IsTypeAlias << SecondName; + return true; + } + + QualType FirstType = FirstTD->getUnderlyingType(); + QualType SecondType = SecondTD->getUnderlyingType(); + if (ComputeQualTypeODRHash(FirstType) != + ComputeQualTypeODRHash(SecondType)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstTD->getLocation(), + FirstTD->getSourceRange(), TypedefType) + << IsTypeAlias << FirstName << FirstType; + ODRDiagDeclNote(SecondModule, SecondTD->getLocation(), + SecondTD->getSourceRange(), TypedefType) + << IsTypeAlias << SecondName << SecondType; + return true; + } + + return false; + }; + + auto ODRDiagVar = [&ODRDiagDeclError, &ODRDiagDeclNote, + &ComputeQualTypeODRHash, &ComputeODRHash, + this](NamedDecl *FirstRecord, StringRef FirstModule, + StringRef SecondModule, VarDecl *FirstVD, + VarDecl *SecondVD) { + auto FirstName = FirstVD->getDeclName(); + auto SecondName = SecondVD->getDeclName(); + if (FirstName != SecondName) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarName) + << FirstName; + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarName) + << SecondName; + return true; + } + + QualType FirstType = FirstVD->getType(); + QualType SecondType = SecondVD->getType(); + if (ComputeQualTypeODRHash(FirstType) != + ComputeQualTypeODRHash(SecondType)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarType) + << FirstName << FirstType; + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarType) + << SecondName << SecondType; + return true; + } + + if (!PP.getLangOpts().CPlusPlus) + return false; + + const Expr *FirstInit = FirstVD->getInit(); + const Expr *SecondInit = SecondVD->getInit(); + if ((FirstInit == nullptr) != (SecondInit == nullptr)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarSingleInitializer) + << FirstName << (FirstInit == nullptr) + << (FirstInit ? FirstInit->getSourceRange() : SourceRange()); + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarSingleInitializer) + << SecondName << (SecondInit == nullptr) + << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); + return true; + } + + if (FirstInit && SecondInit && + ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarDifferentInitializer) + << FirstName << FirstInit->getSourceRange(); + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarDifferentInitializer) + << SecondName << SecondInit->getSourceRange(); + return true; + } + + const bool FirstIsConstexpr = FirstVD->isConstexpr(); + const bool SecondIsConstexpr = SecondVD->isConstexpr(); + if (FirstIsConstexpr != SecondIsConstexpr) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarConstexpr) + << FirstName << FirstIsConstexpr; + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarConstexpr) + << SecondName << SecondIsConstexpr; + return true; + } + return false; + }; + + auto DifferenceSelector = [](Decl *D) { + assert(D && "valid Decl required"); + switch (D->getKind()) { + default: + return Other; + case Decl::AccessSpec: + switch (D->getAccess()) { + case AS_public: + return PublicSpecifer; + case AS_private: + return PrivateSpecifer; + case AS_protected: + return ProtectedSpecifer; + case AS_none: + break; + } + llvm_unreachable("Invalid access specifier"); + case Decl::StaticAssert: + return StaticAssert; + case Decl::Field: + return Field; + case Decl::CXXMethod: + case Decl::CXXConstructor: + case Decl::CXXDestructor: + return CXXMethod; + case Decl::TypeAlias: + return TypeAlias; + case Decl::Typedef: + return TypeDef; + case Decl::Var: + return Var; + case Decl::Friend: + return Friend; + case Decl::FunctionTemplate: + return FunctionTemplate; + } + }; + + using DeclHashes = llvm::SmallVector, 4>; + auto PopulateHashes = [&ComputeSubDeclODRHash](DeclHashes &Hashes, + RecordDecl *Record, + const DeclContext *DC) { + for (auto *D : Record->decls()) { + if (!ODRHash::isWhitelistedDecl(D, DC)) + continue; + Hashes.emplace_back(D, ComputeSubDeclODRHash(D)); + } + }; + + struct DiffResult { + Decl *FirstDecl = nullptr, *SecondDecl = nullptr; + ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other; + }; + + // If there is a diagnoseable difference, FirstDiffType and + // SecondDiffType will not be Other and FirstDecl and SecondDecl will be + // filled in if not EndOfClass. + auto FindTypeDiffs = [&DifferenceSelector](DeclHashes &FirstHashes, + DeclHashes &SecondHashes) { + DiffResult DR; + auto FirstIt = FirstHashes.begin(); + auto SecondIt = SecondHashes.begin(); + while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) { + if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() && + FirstIt->second == SecondIt->second) { + ++FirstIt; + ++SecondIt; + continue; + } + + DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first; + DR.SecondDecl = + SecondIt == SecondHashes.end() ? nullptr : SecondIt->first; + + DR.FirstDiffType = + DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass; + DR.SecondDiffType = + DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass; + return DR; + } + return DR; + }; + + // Use this to diagnose that an unexpected Decl was encountered + // or no difference was detected. This causes a generic error + // message to be emitted. + auto DiagnoseODRUnexpected = [this](DiffResult &DR, NamedDecl *FirstRecord, + StringRef FirstModule, + NamedDecl *SecondRecord, + StringRef SecondModule) { + Diag(FirstRecord->getLocation(), + diag::err_module_odr_violation_different_definitions) + << FirstRecord << FirstModule.empty() << FirstModule; + + if (DR.FirstDecl) { + Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference) + << FirstRecord << DR.FirstDecl->getSourceRange(); + } + + Diag(SecondRecord->getLocation(), + diag::note_module_odr_violation_different_definitions) + << SecondModule; + + if (DR.SecondDecl) { + Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference) + << DR.SecondDecl->getSourceRange(); + } + }; + + auto DiagnoseODRMismatch = + [this](DiffResult &DR, NamedDecl *FirstRecord, StringRef FirstModule, + NamedDecl *SecondRecord, StringRef SecondModule) { + SourceLocation FirstLoc; + SourceRange FirstRange; + auto *FirstTag = dyn_cast(FirstRecord); + if (DR.FirstDiffType == EndOfClass && FirstTag) { + FirstLoc = FirstTag->getBraceRange().getEnd(); + } else { + FirstLoc = DR.FirstDecl->getLocation(); + FirstRange = DR.FirstDecl->getSourceRange(); + } + Diag(FirstLoc, diag::err_module_odr_violation_mismatch_decl) + << FirstRecord << FirstModule.empty() << FirstModule << FirstRange + << DR.FirstDiffType; + + SourceLocation SecondLoc; + SourceRange SecondRange; + auto *SecondTag = dyn_cast(SecondRecord); + if (DR.SecondDiffType == EndOfClass && SecondTag) { + SecondLoc = SecondTag->getBraceRange().getEnd(); + } else { + SecondLoc = DR.SecondDecl->getLocation(); + SecondRange = DR.SecondDecl->getSourceRange(); + } + Diag(SecondLoc, diag::note_module_odr_violation_mismatch_decl) + << SecondModule << SecondRange << DR.SecondDiffType; + }; + // Issue any pending ODR-failure diagnostics. for (auto &Merge : OdrMergeFailures) { // If we've already pointed out a specific problem with this class, don't @@ -9484,16 +9924,16 @@ void ASTReader::diagnoseOdrViolations() { BaseVirtual, BaseAccess, }; - auto ODRDiagError = [FirstRecord, &FirstModule, - this](SourceLocation Loc, SourceRange Range, - ODRDefinitionDataDifference DiffType) { + auto ODRDiagBaseError = [FirstRecord, &FirstModule, + this](SourceLocation Loc, SourceRange Range, + ODRDefinitionDataDifference DiffType) { return Diag(Loc, diag::err_module_odr_violation_definition_data) << FirstRecord << FirstModule.empty() << FirstModule << Range << DiffType; }; - auto ODRDiagNote = [&SecondModule, - this](SourceLocation Loc, SourceRange Range, - ODRDefinitionDataDifference DiffType) { + auto ODRDiagBaseNote = [&SecondModule, + this](SourceLocation Loc, SourceRange Range, + ODRDefinitionDataDifference DiffType) { return Diag(Loc, diag::note_module_odr_violation_definition_data) << SecondModule << Range << DiffType; }; @@ -9512,22 +9952,22 @@ void ASTReader::diagnoseOdrViolations() { }; if (FirstNumBases != SecondNumBases) { - ODRDiagError(FirstRecord->getLocation(), GetSourceRange(FirstDD), - NumBases) + ODRDiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD), + NumBases) << FirstNumBases; - ODRDiagNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), - NumBases) + ODRDiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), + NumBases) << SecondNumBases; Diagnosed = true; break; } if (FirstNumVBases != SecondNumVBases) { - ODRDiagError(FirstRecord->getLocation(), GetSourceRange(FirstDD), - NumVBases) + ODRDiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD), + NumVBases) << FirstNumVBases; - ODRDiagNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), - NumVBases) + ODRDiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), + NumVBases) << SecondNumVBases; Diagnosed = true; break; @@ -9541,33 +9981,33 @@ void ASTReader::diagnoseOdrViolations() { auto SecondBase = SecondBases[i]; if (ComputeQualTypeODRHash(FirstBase.getType()) != ComputeQualTypeODRHash(SecondBase.getType())) { - ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(), - BaseType) + ODRDiagBaseError(FirstRecord->getLocation(), + FirstBase.getSourceRange(), BaseType) << (i + 1) << FirstBase.getType(); - ODRDiagNote(SecondRecord->getLocation(), - SecondBase.getSourceRange(), BaseType) + ODRDiagBaseNote(SecondRecord->getLocation(), + SecondBase.getSourceRange(), BaseType) << (i + 1) << SecondBase.getType(); break; } if (FirstBase.isVirtual() != SecondBase.isVirtual()) { - ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(), - BaseVirtual) + ODRDiagBaseError(FirstRecord->getLocation(), + FirstBase.getSourceRange(), BaseVirtual) << (i + 1) << FirstBase.isVirtual() << FirstBase.getType(); - ODRDiagNote(SecondRecord->getLocation(), - SecondBase.getSourceRange(), BaseVirtual) + ODRDiagBaseNote(SecondRecord->getLocation(), + SecondBase.getSourceRange(), BaseVirtual) << (i + 1) << SecondBase.isVirtual() << SecondBase.getType(); break; } if (FirstBase.getAccessSpecifierAsWritten() != SecondBase.getAccessSpecifierAsWritten()) { - ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(), - BaseAccess) + ODRDiagBaseError(FirstRecord->getLocation(), + FirstBase.getSourceRange(), BaseAccess) << (i + 1) << FirstBase.getType() << (int)FirstBase.getAccessSpecifierAsWritten(); - ODRDiagNote(SecondRecord->getLocation(), - SecondBase.getSourceRange(), BaseAccess) + ODRDiagBaseNote(SecondRecord->getLocation(), + SecondBase.getSourceRange(), BaseAccess) << (i + 1) << SecondBase.getType() << (int)SecondBase.getAccessSpecifierAsWritten(); break; @@ -9580,8 +10020,6 @@ void ASTReader::diagnoseOdrViolations() { } } - using DeclHashes = llvm::SmallVector, 4>; - const ClassTemplateDecl *FirstTemplate = FirstRecord->getDescribedClassTemplate(); const ClassTemplateDecl *SecondTemplate = @@ -9622,16 +10060,16 @@ void ASTReader::diagnoseOdrViolations() { if (FirstIt->second == SecondIt->second) continue; - auto ODRDiagError = [FirstRecord, &FirstModule, - this](SourceLocation Loc, SourceRange Range, - ODRTemplateDifference DiffType) { + auto ODRDiagTemplateError = [FirstRecord, &FirstModule, this]( + SourceLocation Loc, SourceRange Range, + ODRTemplateDifference DiffType) { return Diag(Loc, diag::err_module_odr_violation_template_parameter) << FirstRecord << FirstModule.empty() << FirstModule << Range << DiffType; }; - auto ODRDiagNote = [&SecondModule, - this](SourceLocation Loc, SourceRange Range, - ODRTemplateDifference DiffType) { + auto ODRDiagTemplateNote = [&SecondModule, this]( + SourceLocation Loc, SourceRange Range, + ODRTemplateDifference DiffType) { return Diag(Loc, diag::note_module_odr_violation_template_parameter) << SecondModule << Range << DiffType; }; @@ -9652,11 +10090,13 @@ void ASTReader::diagnoseOdrViolations() { SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo(); assert((!FirstNameEmpty || !SecondNameEmpty) && "Both template parameters cannot be unnamed."); - ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(), - FirstNameEmpty ? ParamEmptyName : ParamName) + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + FirstNameEmpty ? ParamEmptyName : ParamName) << FirstName; - ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(), - SecondNameEmpty ? ParamEmptyName : ParamName) + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + SecondNameEmpty ? ParamEmptyName : ParamName) << SecondName; break; } @@ -9675,13 +10115,13 @@ void ASTReader::diagnoseOdrViolations() { !SecondParam->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstDecl->getLocation(), - FirstDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasFirstDefaultArgument; - ODRDiagNote(SecondDecl->getLocation(), - SecondDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasSecondDefaultArgument; break; } @@ -9689,10 +10129,12 @@ void ASTReader::diagnoseOdrViolations() { assert(HasFirstDefaultArgument && HasSecondDefaultArgument && "Expecting default arguments."); - ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(), - ParamDifferentDefaultArgument); - ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(), - ParamDifferentDefaultArgument); + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamDifferentDefaultArgument); + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamDifferentDefaultArgument); break; } @@ -9707,13 +10149,13 @@ void ASTReader::diagnoseOdrViolations() { !SecondParam->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstDecl->getLocation(), - FirstDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasFirstDefaultArgument; - ODRDiagNote(SecondDecl->getLocation(), - SecondDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasSecondDefaultArgument; break; } @@ -9721,10 +10163,12 @@ void ASTReader::diagnoseOdrViolations() { assert(HasFirstDefaultArgument && HasSecondDefaultArgument && "Expecting default arguments."); - ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(), - ParamDifferentDefaultArgument); - ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(), - ParamDifferentDefaultArgument); + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamDifferentDefaultArgument); + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamDifferentDefaultArgument); break; } @@ -9740,13 +10184,13 @@ void ASTReader::diagnoseOdrViolations() { !SecondParam->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstDecl->getLocation(), - FirstDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasFirstDefaultArgument; - ODRDiagNote(SecondDecl->getLocation(), - SecondDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasSecondDefaultArgument; break; } @@ -9754,10 +10198,12 @@ void ASTReader::diagnoseOdrViolations() { assert(HasFirstDefaultArgument && HasSecondDefaultArgument && "Expecting default arguments."); - ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(), - ParamDifferentDefaultArgument); - ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(), - ParamDifferentDefaultArgument); + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamDifferentDefaultArgument); + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamDifferentDefaultArgument); break; } @@ -9774,224 +10220,32 @@ void ASTReader::diagnoseOdrViolations() { DeclHashes FirstHashes; DeclHashes SecondHashes; + const DeclContext *DC = FirstRecord; + PopulateHashes(FirstHashes, FirstRecord, DC); + PopulateHashes(SecondHashes, SecondRecord, DC); - auto PopulateHashes = [&ComputeSubDeclODRHash, FirstRecord]( - DeclHashes &Hashes, CXXRecordDecl *Record) { - for (auto *D : Record->decls()) { - // Due to decl merging, the first CXXRecordDecl is the parent of - // Decls in both records. - if (!ODRHash::isWhitelistedDecl(D, FirstRecord)) - continue; - Hashes.emplace_back(D, ComputeSubDeclODRHash(D)); - } - }; - PopulateHashes(FirstHashes, FirstRecord); - PopulateHashes(SecondHashes, SecondRecord); - - // Used with err_module_odr_violation_mismatch_decl and - // note_module_odr_violation_mismatch_decl - // This list should be the same Decl's as in ODRHash::isWhiteListedDecl - enum { - EndOfClass, - PublicSpecifer, - PrivateSpecifer, - ProtectedSpecifer, - StaticAssert, - Field, - CXXMethod, - TypeAlias, - TypeDef, - Var, - Friend, - FunctionTemplate, - Other - } FirstDiffType = Other, - SecondDiffType = Other; - - auto DifferenceSelector = [](Decl *D) { - assert(D && "valid Decl required"); - switch (D->getKind()) { - default: - return Other; - case Decl::AccessSpec: - switch (D->getAccess()) { - case AS_public: - return PublicSpecifer; - case AS_private: - return PrivateSpecifer; - case AS_protected: - return ProtectedSpecifer; - case AS_none: - break; - } - llvm_unreachable("Invalid access specifier"); - case Decl::StaticAssert: - return StaticAssert; - case Decl::Field: - return Field; - case Decl::CXXMethod: - case Decl::CXXConstructor: - case Decl::CXXDestructor: - return CXXMethod; - case Decl::TypeAlias: - return TypeAlias; - case Decl::Typedef: - return TypeDef; - case Decl::Var: - return Var; - case Decl::Friend: - return Friend; - case Decl::FunctionTemplate: - return FunctionTemplate; - } - }; - - Decl *FirstDecl = nullptr; - Decl *SecondDecl = nullptr; - auto FirstIt = FirstHashes.begin(); - auto SecondIt = SecondHashes.begin(); - - // If there is a diagnoseable difference, FirstDiffType and - // SecondDiffType will not be Other and FirstDecl and SecondDecl will be - // filled in if not EndOfClass. - while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) { - if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() && - FirstIt->second == SecondIt->second) { - ++FirstIt; - ++SecondIt; - continue; - } - - FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first; - SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first; - - FirstDiffType = FirstDecl ? DifferenceSelector(FirstDecl) : EndOfClass; - SecondDiffType = - SecondDecl ? DifferenceSelector(SecondDecl) : EndOfClass; - - break; - } + auto DR = FindTypeDiffs(FirstHashes, SecondHashes); + ODRMismatchDecl FirstDiffType = DR.FirstDiffType; + ODRMismatchDecl SecondDiffType = DR.SecondDiffType; + Decl *FirstDecl = DR.FirstDecl; + Decl *SecondDecl = DR.SecondDecl; if (FirstDiffType == Other || SecondDiffType == Other) { - // Reaching this point means an unexpected Decl was encountered - // or no difference was detected. This causes a generic error - // message to be emitted. - Diag(FirstRecord->getLocation(), - diag::err_module_odr_violation_different_definitions) - << FirstRecord << FirstModule.empty() << FirstModule; - - if (FirstDecl) { - Diag(FirstDecl->getLocation(), diag::note_first_module_difference) - << FirstRecord << FirstDecl->getSourceRange(); - } - - Diag(SecondRecord->getLocation(), - diag::note_module_odr_violation_different_definitions) - << SecondModule; - - if (SecondDecl) { - Diag(SecondDecl->getLocation(), diag::note_second_module_difference) - << SecondDecl->getSourceRange(); - } - + DiagnoseODRUnexpected(DR, FirstRecord, FirstModule, SecondRecord, + SecondModule); Diagnosed = true; break; } if (FirstDiffType != SecondDiffType) { - SourceLocation FirstLoc; - SourceRange FirstRange; - if (FirstDiffType == EndOfClass) { - FirstLoc = FirstRecord->getBraceRange().getEnd(); - } else { - FirstLoc = FirstIt->first->getLocation(); - FirstRange = FirstIt->first->getSourceRange(); - } - Diag(FirstLoc, diag::err_module_odr_violation_mismatch_decl) - << FirstRecord << FirstModule.empty() << FirstModule << FirstRange - << FirstDiffType; - - SourceLocation SecondLoc; - SourceRange SecondRange; - if (SecondDiffType == EndOfClass) { - SecondLoc = SecondRecord->getBraceRange().getEnd(); - } else { - SecondLoc = SecondDecl->getLocation(); - SecondRange = SecondDecl->getSourceRange(); - } - Diag(SecondLoc, diag::note_module_odr_violation_mismatch_decl) - << SecondModule << SecondRange << SecondDiffType; + DiagnoseODRMismatch(DR, FirstRecord, FirstModule, SecondRecord, + SecondModule); Diagnosed = true; break; } assert(FirstDiffType == SecondDiffType); - // Used with err_module_odr_violation_mismatch_decl_diff and - // note_module_odr_violation_mismatch_decl_diff - enum ODRDeclDifference { - StaticAssertCondition, - StaticAssertMessage, - StaticAssertOnlyMessage, - FieldName, - FieldTypeName, - FieldSingleBitField, - FieldDifferentWidthBitField, - FieldSingleMutable, - FieldSingleInitializer, - FieldDifferentInitializers, - MethodName, - MethodDeleted, - MethodDefaulted, - MethodVirtual, - MethodStatic, - MethodVolatile, - MethodConst, - MethodInline, - MethodNumberParameters, - MethodParameterType, - MethodParameterName, - MethodParameterSingleDefaultArgument, - MethodParameterDifferentDefaultArgument, - MethodNoTemplateArguments, - MethodDifferentNumberTemplateArguments, - MethodDifferentTemplateArgument, - MethodSingleBody, - MethodDifferentBody, - TypedefName, - TypedefType, - VarName, - VarType, - VarSingleInitializer, - VarDifferentInitializer, - VarConstexpr, - FriendTypeFunction, - FriendType, - FriendFunction, - FunctionTemplateDifferentNumberParameters, - FunctionTemplateParameterDifferentKind, - FunctionTemplateParameterName, - FunctionTemplateParameterSingleDefaultArgument, - FunctionTemplateParameterDifferentDefaultArgument, - FunctionTemplateParameterDifferentType, - FunctionTemplatePackParameter, - }; - - // These lambdas have the common portions of the ODR diagnostics. This - // has the same return as Diag(), so addition parameters can be passed - // in with operator<< - auto ODRDiagError = [FirstRecord, &FirstModule, this]( - SourceLocation Loc, SourceRange Range, ODRDeclDifference DiffType) { - return Diag(Loc, diag::err_module_odr_violation_mismatch_decl_diff) - << FirstRecord << FirstModule.empty() << FirstModule << Range - << DiffType; - }; - auto ODRDiagNote = [&SecondModule, this]( - SourceLocation Loc, SourceRange Range, ODRDeclDifference DiffType) { - return Diag(Loc, diag::note_module_odr_violation_mismatch_decl_diff) - << SecondModule << Range << DiffType; - }; - switch (FirstDiffType) { case Other: case EndOfClass: @@ -10009,10 +10263,10 @@ void ASTReader::diagnoseOdrViolations() { unsigned FirstODRHash = ComputeODRHash(FirstExpr); unsigned SecondODRHash = ComputeODRHash(SecondExpr); if (FirstODRHash != SecondODRHash) { - ODRDiagError(FirstExpr->getBeginLoc(), FirstExpr->getSourceRange(), - StaticAssertCondition); - ODRDiagNote(SecondExpr->getBeginLoc(), SecondExpr->getSourceRange(), - StaticAssertCondition); + ODRDiagDeclError(FirstRecord, FirstModule, FirstExpr->getBeginLoc(), + FirstExpr->getSourceRange(), StaticAssertCondition); + ODRDiagDeclNote(SecondModule, SecondExpr->getBeginLoc(), + SecondExpr->getSourceRange(), StaticAssertCondition); Diagnosed = true; break; } @@ -10037,9 +10291,11 @@ void ASTReader::diagnoseOdrViolations() { SecondLoc = SecondSA->getBeginLoc(); SecondRange = SecondSA->getSourceRange(); } - ODRDiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage) + ODRDiagDeclError(FirstRecord, FirstModule, FirstLoc, FirstRange, + StaticAssertOnlyMessage) << (FirstStr == nullptr); - ODRDiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage) + ODRDiagDeclNote(SecondModule, SecondLoc, SecondRange, + StaticAssertOnlyMessage) << (SecondStr == nullptr); Diagnosed = true; break; @@ -10047,126 +10303,19 @@ void ASTReader::diagnoseOdrViolations() { if (FirstStr && SecondStr && FirstStr->getString() != SecondStr->getString()) { - ODRDiagError(FirstStr->getBeginLoc(), FirstStr->getSourceRange(), - StaticAssertMessage); - ODRDiagNote(SecondStr->getBeginLoc(), SecondStr->getSourceRange(), - StaticAssertMessage); + ODRDiagDeclError(FirstRecord, FirstModule, FirstStr->getBeginLoc(), + FirstStr->getSourceRange(), StaticAssertMessage); + ODRDiagDeclNote(SecondModule, SecondStr->getBeginLoc(), + SecondStr->getSourceRange(), StaticAssertMessage); Diagnosed = true; break; } break; } case Field: { - FieldDecl *FirstField = cast(FirstDecl); - FieldDecl *SecondField = cast(SecondDecl); - IdentifierInfo *FirstII = FirstField->getIdentifier(); - IdentifierInfo *SecondII = SecondField->getIdentifier(); - if (FirstII->getName() != SecondII->getName()) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldName) - << FirstII; - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldName) - << SecondII; - - Diagnosed = true; - break; - } - - assert(getContext().hasSameType(FirstField->getType(), - SecondField->getType())); - - QualType FirstType = FirstField->getType(); - QualType SecondType = SecondField->getType(); - if (ComputeQualTypeODRHash(FirstType) != - ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldTypeName) - << FirstII << FirstType; - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldTypeName) - << SecondII << SecondType; - - Diagnosed = true; - break; - } - - const bool IsFirstBitField = FirstField->isBitField(); - const bool IsSecondBitField = SecondField->isBitField(); - if (IsFirstBitField != IsSecondBitField) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldSingleBitField) - << FirstII << IsFirstBitField; - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldSingleBitField) - << SecondII << IsSecondBitField; - Diagnosed = true; - break; - } - - if (IsFirstBitField && IsSecondBitField) { - unsigned FirstBitWidthHash = - ComputeODRHash(FirstField->getBitWidth()); - unsigned SecondBitWidthHash = - ComputeODRHash(SecondField->getBitWidth()); - if (FirstBitWidthHash != SecondBitWidthHash) { - ODRDiagError(FirstField->getLocation(), - FirstField->getSourceRange(), - FieldDifferentWidthBitField) - << FirstII << FirstField->getBitWidth()->getSourceRange(); - ODRDiagNote(SecondField->getLocation(), - SecondField->getSourceRange(), - FieldDifferentWidthBitField) - << SecondII << SecondField->getBitWidth()->getSourceRange(); - Diagnosed = true; - break; - } - } - - const bool IsFirstMutable = FirstField->isMutable(); - const bool IsSecondMutable = SecondField->isMutable(); - if (IsFirstMutable != IsSecondMutable) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldSingleMutable) - << FirstII << IsFirstMutable; - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldSingleMutable) - << SecondII << IsSecondMutable; - Diagnosed = true; - break; - } - - const Expr *FirstInitializer = FirstField->getInClassInitializer(); - const Expr *SecondInitializer = SecondField->getInClassInitializer(); - if ((!FirstInitializer && SecondInitializer) || - (FirstInitializer && !SecondInitializer)) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldSingleInitializer) - << FirstII << (FirstInitializer != nullptr); - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldSingleInitializer) - << SecondII << (SecondInitializer != nullptr); - Diagnosed = true; - break; - } - - if (FirstInitializer && SecondInitializer) { - unsigned FirstInitHash = ComputeODRHash(FirstInitializer); - unsigned SecondInitHash = ComputeODRHash(SecondInitializer); - if (FirstInitHash != SecondInitHash) { - ODRDiagError(FirstField->getLocation(), - FirstField->getSourceRange(), - FieldDifferentInitializers) - << FirstII << FirstInitializer->getSourceRange(); - ODRDiagNote(SecondField->getLocation(), - SecondField->getSourceRange(), - FieldDifferentInitializers) - << SecondII << SecondInitializer->getSourceRange(); - Diagnosed = true; - break; - } - } - + Diagnosed = ODRDiagField(FirstRecord, FirstModule, SecondModule, + cast(FirstDecl), + cast(SecondDecl)); break; } case CXXMethod: { @@ -10188,11 +10337,11 @@ void ASTReader::diagnoseOdrViolations() { auto FirstName = FirstMethod->getDeclName(); auto SecondName = SecondMethod->getDeclName(); if (FirstMethodType != SecondMethodType || FirstName != SecondName) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodName) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodName) << FirstMethodType << FirstName; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodName) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodName) << SecondMethodType << SecondName; Diagnosed = true; @@ -10202,12 +10351,12 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstDeleted = FirstMethod->isDeletedAsWritten(); const bool SecondDeleted = SecondMethod->isDeletedAsWritten(); if (FirstDeleted != SecondDeleted) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodDeleted) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDeleted) << FirstMethodType << FirstName << FirstDeleted; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodDeleted) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodDeleted) << SecondMethodType << SecondName << SecondDeleted; Diagnosed = true; break; @@ -10216,12 +10365,12 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted(); const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted(); if (FirstDefaulted != SecondDefaulted) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodDefaulted) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDefaulted) << FirstMethodType << FirstName << FirstDefaulted; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodDefaulted) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodDefaulted) << SecondMethodType << SecondName << SecondDefaulted; Diagnosed = true; break; @@ -10233,11 +10382,11 @@ void ASTReader::diagnoseOdrViolations() { const bool SecondPure = SecondMethod->isPure(); if ((FirstVirtual || SecondVirtual) && (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodVirtual) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodVirtual) << FirstMethodType << FirstName << FirstPure << FirstVirtual; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodVirtual) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodVirtual) << SecondMethodType << SecondName << SecondPure << SecondVirtual; Diagnosed = true; break; @@ -10251,11 +10400,11 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstStatic = FirstStorage == SC_Static; const bool SecondStatic = SecondStorage == SC_Static; if (FirstStatic != SecondStatic) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodStatic) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodStatic) << FirstMethodType << FirstName << FirstStatic; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodStatic) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodStatic) << SecondMethodType << SecondName << SecondStatic; Diagnosed = true; break; @@ -10264,11 +10413,11 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstVolatile = FirstMethod->isVolatile(); const bool SecondVolatile = SecondMethod->isVolatile(); if (FirstVolatile != SecondVolatile) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodVolatile) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodVolatile) << FirstMethodType << FirstName << FirstVolatile; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodVolatile) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodVolatile) << SecondMethodType << SecondName << SecondVolatile; Diagnosed = true; break; @@ -10277,11 +10426,11 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstConst = FirstMethod->isConst(); const bool SecondConst = SecondMethod->isConst(); if (FirstConst != SecondConst) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodConst) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodConst) << FirstMethodType << FirstName << FirstConst; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodConst) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodConst) << SecondMethodType << SecondName << SecondConst; Diagnosed = true; break; @@ -10290,11 +10439,11 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstInline = FirstMethod->isInlineSpecified(); const bool SecondInline = SecondMethod->isInlineSpecified(); if (FirstInline != SecondInline) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodInline) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodInline) << FirstMethodType << FirstName << FirstInline; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodInline) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodInline) << SecondMethodType << SecondName << SecondInline; Diagnosed = true; break; @@ -10303,11 +10452,13 @@ void ASTReader::diagnoseOdrViolations() { const unsigned FirstNumParameters = FirstMethod->param_size(); const unsigned SecondNumParameters = SecondMethod->param_size(); if (FirstNumParameters != SecondNumParameters) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodNumberParameters) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodNumberParameters) << FirstMethodType << FirstName << FirstNumParameters; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodNumberParameters) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodNumberParameters) << SecondMethodType << SecondName << SecondNumParameters; Diagnosed = true; break; @@ -10326,27 +10477,31 @@ void ASTReader::diagnoseOdrViolations() { ComputeQualTypeODRHash(SecondParamType)) { if (const DecayedType *ParamDecayedType = FirstParamType->getAs()) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodParameterType) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodParameterType) << FirstMethodType << FirstName << (I + 1) << FirstParamType << true << ParamDecayedType->getOriginalType(); } else { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodParameterType) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodParameterType) << FirstMethodType << FirstName << (I + 1) << FirstParamType << false; } if (const DecayedType *ParamDecayedType = SecondParamType->getAs()) { - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodParameterType) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodParameterType) << SecondMethodType << SecondName << (I + 1) << SecondParamType << true << ParamDecayedType->getOriginalType(); } else { - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodParameterType) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodParameterType) << SecondMethodType << SecondName << (I + 1) << SecondParamType << false; } @@ -10357,11 +10512,12 @@ void ASTReader::diagnoseOdrViolations() { DeclarationName FirstParamName = FirstParam->getDeclName(); DeclarationName SecondParamName = SecondParam->getDeclName(); if (FirstParamName != SecondParamName) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodParameterName) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodParameterName) << FirstMethodType << FirstName << (I + 1) << FirstParamName; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodParameterName) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodParameterName) << SecondMethodType << SecondName << (I + 1) << SecondParamName; ParameterMismatch = true; break; @@ -10370,15 +10526,16 @@ void ASTReader::diagnoseOdrViolations() { const Expr *FirstInit = FirstParam->getInit(); const Expr *SecondInit = SecondParam->getInit(); if ((FirstInit == nullptr) != (SecondInit == nullptr)) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), - MethodParameterSingleDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodParameterSingleDefaultArgument) << FirstMethodType << FirstName << (I + 1) << (FirstInit == nullptr) << (FirstInit ? FirstInit->getSourceRange() : SourceRange()); - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), - MethodParameterSingleDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodParameterSingleDefaultArgument) << SecondMethodType << SecondName << (I + 1) << (SecondInit == nullptr) << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); @@ -10388,14 +10545,15 @@ void ASTReader::diagnoseOdrViolations() { if (FirstInit && SecondInit && ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), - MethodParameterDifferentDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodParameterDifferentDefaultArgument) << FirstMethodType << FirstName << (I + 1) << FirstInit->getSourceRange(); - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), - MethodParameterDifferentDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodParameterDifferentDefaultArgument) << SecondMethodType << SecondName << (I + 1) << SecondInit->getSourceRange(); ParameterMismatch = true; @@ -10416,11 +10574,13 @@ void ASTReader::diagnoseOdrViolations() { if ((FirstTemplateArgs && !SecondTemplateArgs) || (!FirstTemplateArgs && SecondTemplateArgs)) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodNoTemplateArguments) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodNoTemplateArguments) << FirstMethodType << FirstName << (FirstTemplateArgs != nullptr); - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodNoTemplateArguments) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodNoTemplateArguments) << SecondMethodType << SecondName << (SecondTemplateArgs != nullptr); @@ -10450,14 +10610,15 @@ void ASTReader::diagnoseOdrViolations() { ExpandTemplateArgumentList(SecondTemplateArgs); if (FirstExpandedList.size() != SecondExpandedList.size()) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), - MethodDifferentNumberTemplateArguments) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodDifferentNumberTemplateArguments) << FirstMethodType << FirstName << (unsigned)FirstExpandedList.size(); - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), - MethodDifferentNumberTemplateArguments) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodDifferentNumberTemplateArguments) << SecondMethodType << SecondName << (unsigned)SecondExpandedList.size(); @@ -10474,13 +10635,13 @@ void ASTReader::diagnoseOdrViolations() { continue; } - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), - MethodDifferentTemplateArgument) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDifferentTemplateArgument) << FirstMethodType << FirstName << FirstTA << i + 1; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), - MethodDifferentTemplateArgument) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodDifferentTemplateArgument) << SecondMethodType << SecondName << SecondTA << i + 1; TemplateArgumentMismatch = true; @@ -10509,22 +10670,22 @@ void ASTReader::diagnoseOdrViolations() { ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash(); if (HasFirstBody != HasSecondBody) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodSingleBody) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodSingleBody) << FirstMethodType << FirstName << HasFirstBody; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodSingleBody) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodSingleBody) << SecondMethodType << SecondName << HasSecondBody; Diagnosed = true; break; } if (HasFirstBody && HasSecondBody) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodDifferentBody) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDifferentBody) << FirstMethodType << FirstName; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodDifferentBody) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodDifferentBody) << SecondMethodType << SecondName; Diagnosed = true; break; @@ -10534,105 +10695,16 @@ void ASTReader::diagnoseOdrViolations() { } case TypeAlias: case TypeDef: { - TypedefNameDecl *FirstTD = cast(FirstDecl); - TypedefNameDecl *SecondTD = cast(SecondDecl); - auto FirstName = FirstTD->getDeclName(); - auto SecondName = SecondTD->getDeclName(); - if (FirstName != SecondName) { - ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(), - TypedefName) - << (FirstDiffType == TypeAlias) << FirstName; - ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(), - TypedefName) - << (FirstDiffType == TypeAlias) << SecondName; - Diagnosed = true; - break; - } - - QualType FirstType = FirstTD->getUnderlyingType(); - QualType SecondType = SecondTD->getUnderlyingType(); - if (ComputeQualTypeODRHash(FirstType) != - ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(), - TypedefType) - << (FirstDiffType == TypeAlias) << FirstName << FirstType; - ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(), - TypedefType) - << (FirstDiffType == TypeAlias) << SecondName << SecondType; - Diagnosed = true; - break; - } + Diagnosed = ODRDiagTypeDefOrAlias( + FirstRecord, FirstModule, SecondModule, + cast(FirstDecl), cast(SecondDecl), + FirstDiffType == TypeAlias); break; } case Var: { - VarDecl *FirstVD = cast(FirstDecl); - VarDecl *SecondVD = cast(SecondDecl); - auto FirstName = FirstVD->getDeclName(); - auto SecondName = SecondVD->getDeclName(); - if (FirstName != SecondName) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarName) - << FirstName; - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarName) - << SecondName; - Diagnosed = true; - break; - } - - QualType FirstType = FirstVD->getType(); - QualType SecondType = SecondVD->getType(); - if (ComputeQualTypeODRHash(FirstType) != - ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarType) - << FirstName << FirstType; - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarType) - << SecondName << SecondType; - Diagnosed = true; - break; - } - - const Expr *FirstInit = FirstVD->getInit(); - const Expr *SecondInit = SecondVD->getInit(); - if ((FirstInit == nullptr) != (SecondInit == nullptr)) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarSingleInitializer) - << FirstName << (FirstInit == nullptr) - << (FirstInit ? FirstInit->getSourceRange(): SourceRange()); - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarSingleInitializer) - << SecondName << (SecondInit == nullptr) - << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); - Diagnosed = true; - break; - } - - if (FirstInit && SecondInit && - ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarDifferentInitializer) - << FirstName << FirstInit->getSourceRange(); - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarDifferentInitializer) - << SecondName << SecondInit->getSourceRange(); - Diagnosed = true; - break; - } - - const bool FirstIsConstexpr = FirstVD->isConstexpr(); - const bool SecondIsConstexpr = SecondVD->isConstexpr(); - if (FirstIsConstexpr != SecondIsConstexpr) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarConstexpr) - << FirstName << FirstIsConstexpr; - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarConstexpr) - << SecondName << SecondIsConstexpr; - Diagnosed = true; - break; - } + Diagnosed = + ODRDiagVar(FirstRecord, FirstModule, SecondModule, + cast(FirstDecl), cast(SecondDecl)); break; } case Friend: { @@ -10646,11 +10718,12 @@ void ASTReader::diagnoseOdrViolations() { TypeSourceInfo *SecondTSI = SecondFriend->getFriendType(); if (FirstND && SecondND) { - ODRDiagError(FirstFriend->getFriendLoc(), - FirstFriend->getSourceRange(), FriendFunction) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstFriend->getFriendLoc(), + FirstFriend->getSourceRange(), FriendFunction) << FirstND; - ODRDiagNote(SecondFriend->getFriendLoc(), - SecondFriend->getSourceRange(), FriendFunction) + ODRDiagDeclNote(SecondModule, SecondFriend->getFriendLoc(), + SecondFriend->getSourceRange(), FriendFunction) << SecondND; Diagnosed = true; @@ -10662,21 +10735,22 @@ void ASTReader::diagnoseOdrViolations() { QualType SecondFriendType = SecondTSI->getType(); assert(ComputeQualTypeODRHash(FirstFriendType) != ComputeQualTypeODRHash(SecondFriendType)); - ODRDiagError(FirstFriend->getFriendLoc(), - FirstFriend->getSourceRange(), FriendType) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstFriend->getFriendLoc(), + FirstFriend->getSourceRange(), FriendType) << FirstFriendType; - ODRDiagNote(SecondFriend->getFriendLoc(), - SecondFriend->getSourceRange(), FriendType) + ODRDiagDeclNote(SecondModule, SecondFriend->getFriendLoc(), + SecondFriend->getSourceRange(), FriendType) << SecondFriendType; Diagnosed = true; break; } - ODRDiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(), - FriendTypeFunction) + ODRDiagDeclError(FirstRecord, FirstModule, FirstFriend->getFriendLoc(), + FirstFriend->getSourceRange(), FriendTypeFunction) << (FirstTSI == nullptr); - ODRDiagNote(SecondFriend->getFriendLoc(), - SecondFriend->getSourceRange(), FriendTypeFunction) + ODRDiagDeclNote(SecondModule, SecondFriend->getFriendLoc(), + SecondFriend->getSourceRange(), FriendTypeFunction) << (SecondTSI == nullptr); Diagnosed = true; @@ -10694,14 +10768,15 @@ void ASTReader::diagnoseOdrViolations() { SecondTemplate->getTemplateParameters(); if (FirstTPL->size() != SecondTPL->size()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateDifferentNumberParameters) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateDifferentNumberParameters) << FirstTemplate << FirstTPL->size(); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateDifferentNumberParameters) - << SecondTemplate << SecondTPL->size(); + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateDifferentNumberParameters) + << SecondTemplate << SecondTPL->size(); Diagnosed = true; break; @@ -10731,13 +10806,14 @@ void ASTReader::diagnoseOdrViolations() { } }; - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentKind) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentKind) << FirstTemplate << (i + 1) << GetParamType(FirstParam); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentKind) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentKind) << SecondTemplate << (i + 1) << GetParamType(SecondParam); ParameterMismatch = true; @@ -10745,14 +10821,14 @@ void ASTReader::diagnoseOdrViolations() { } if (FirstParam->getName() != SecondParam->getName()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterName) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), FunctionTemplateParameterName) << FirstTemplate << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterName) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterName) << SecondTemplate << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam; ParameterMismatch = true; @@ -10772,13 +10848,14 @@ void ASTReader::diagnoseOdrViolations() { SecondTTPD->hasDefaultArgument() && !SecondTTPD->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << FirstTemplate << (i + 1) << HasFirstDefaultArgument; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << SecondTemplate << (i + 1) << HasSecondDefaultArgument; ParameterMismatch = true; break; @@ -10789,13 +10866,15 @@ void ASTReader::diagnoseOdrViolations() { QualType SecondType = SecondTTPD->getDefaultArgument(); if (ComputeQualTypeODRHash(FirstType) != ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << FirstTemplate << (i + 1) << FirstType; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclNote( + SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << SecondTemplate << (i + 1) << SecondType; ParameterMismatch = true; break; @@ -10804,13 +10883,14 @@ void ASTReader::diagnoseOdrViolations() { if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplatePackParameter) << FirstTemplate << (i + 1) << FirstTTPD->isParameterPack(); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplatePackParameter) << SecondTemplate << (i + 1) << SecondTTPD->isParameterPack(); ParameterMismatch = true; break; @@ -10831,13 +10911,14 @@ void ASTReader::diagnoseOdrViolations() { if (ComputeTemplateParameterListODRHash(FirstTPL) != ComputeTemplateParameterListODRHash(SecondTPL)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentType) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentType) << FirstTemplate << (i + 1); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentType) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentType) << SecondTemplate << (i + 1); ParameterMismatch = true; break; @@ -10850,13 +10931,14 @@ void ASTReader::diagnoseOdrViolations() { SecondTTPD->hasDefaultArgument() && !SecondTTPD->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << FirstTemplate << (i + 1) << HasFirstDefaultArgument; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << SecondTemplate << (i + 1) << HasSecondDefaultArgument; ParameterMismatch = true; break; @@ -10869,13 +10951,15 @@ void ASTReader::diagnoseOdrViolations() { SecondTTPD->getDefaultArgument().getArgument(); if (ComputeTemplateArgumentODRHash(FirstTA) != ComputeTemplateArgumentODRHash(SecondTA)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << FirstTemplate << (i + 1) << FirstTA; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclNote( + SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << SecondTemplate << (i + 1) << SecondTA; ParameterMismatch = true; break; @@ -10884,13 +10968,14 @@ void ASTReader::diagnoseOdrViolations() { if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplatePackParameter) << FirstTemplate << (i + 1) << FirstTTPD->isParameterPack(); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplatePackParameter) << SecondTemplate << (i + 1) << SecondTTPD->isParameterPack(); ParameterMismatch = true; break; @@ -10908,13 +10993,14 @@ void ASTReader::diagnoseOdrViolations() { QualType SecondType = SecondNTTPD->getType(); if (ComputeQualTypeODRHash(FirstType) != ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentType) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentType) << FirstTemplate << (i + 1); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentType) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentType) << SecondTemplate << (i + 1); ParameterMismatch = true; break; @@ -10927,13 +11013,14 @@ void ASTReader::diagnoseOdrViolations() { SecondNTTPD->hasDefaultArgument() && !SecondNTTPD->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << FirstTemplate << (i + 1) << HasFirstDefaultArgument; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << SecondTemplate << (i + 1) << HasSecondDefaultArgument; ParameterMismatch = true; break; @@ -10944,13 +11031,15 @@ void ASTReader::diagnoseOdrViolations() { Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument(); if (ComputeODRHash(FirstDefaultArgument) != ComputeODRHash(SecondDefaultArgument)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << FirstTemplate << (i + 1) << FirstDefaultArgument; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclNote( + SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << SecondTemplate << (i + 1) << SecondDefaultArgument; ParameterMismatch = true; break; @@ -10959,13 +11048,14 @@ void ASTReader::diagnoseOdrViolations() { if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplatePackParameter) << FirstTemplate << (i + 1) << FirstNTTPD->isParameterPack(); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplatePackParameter) << SecondTemplate << (i + 1) << SecondNTTPD->isParameterPack(); ParameterMismatch = true;