[ODRHash diagnostics] Preparation to minimize subsequent diffs. NFC.

Specifically, making the following changes:
* Turn lambdas calculating ODR hashes into static functions.
* Move `ODRCXXRecordDifference` where it is used.
* Rename some variables and move some lines of code.
* Replace `auto` with explicit type when the deduced type is not mentioned.
* Add `const` for unmodified objects, so we can pass them to more functions.

Differential Revision: https://reviews.llvm.org/D128690
This commit is contained in:
Volodymyr Sapsai 2022-06-27 16:53:36 -07:00
parent f84712f0b8
commit f693874c53
1 changed files with 240 additions and 266 deletions

View File

@ -9445,6 +9445,31 @@ void ASTReader::finishPendingActions() {
PendingMergedDefinitionsToDeduplicate.clear();
}
static unsigned computeODRHash(QualType Ty) {
ODRHash Hasher;
Hasher.AddQualType(Ty);
return Hasher.CalculateHash();
}
static unsigned computeODRHash(const Stmt *S) {
ODRHash Hasher;
Hasher.AddStmt(S);
return Hasher.CalculateHash();
}
static unsigned computeODRHash(const Decl *D) {
assert(D);
ODRHash Hasher;
Hasher.AddSubDecl(D);
return Hasher.CalculateHash();
}
static unsigned computeODRHash(const TemplateArgument &TA) {
ODRHash Hasher;
Hasher.AddTemplateArgument(TA);
return Hasher.CalculateHash();
}
void ASTReader::diagnoseOdrViolations() {
if (PendingOdrMergeFailures.empty() && PendingOdrMergeChecks.empty() &&
PendingFunctionOdrMergeFailures.empty() &&
@ -9584,42 +9609,6 @@ void ASTReader::diagnoseOdrViolations() {
// we're producing our diagnostics.
Deserializing RecursionGuard(this);
// Common code for hashing helpers.
ODRHash Hash;
auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {
Hash.clear();
Hash.AddQualType(Ty);
return Hash.CalculateHash();
};
auto ComputeODRHash = [&Hash](const Stmt *S) {
assert(S);
Hash.clear();
Hash.AddStmt(S);
return Hash.CalculateHash();
};
auto ComputeSubDeclODRHash = [&Hash](const Decl *D) {
assert(D);
Hash.clear();
Hash.AddSubDecl(D);
return Hash.CalculateHash();
};
auto ComputeTemplateArgumentODRHash = [&Hash](const TemplateArgument &TA) {
Hash.clear();
Hash.AddTemplateArgument(TA);
return Hash.CalculateHash();
};
auto ComputeTemplateParameterListODRHash =
[&Hash](const TemplateParameterList *TPL) {
assert(TPL);
Hash.clear();
Hash.AddTemplateParameterList(TPL);
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::isDeclToBeProcessed
@ -9639,49 +9628,13 @@ void ASTReader::diagnoseOdrViolations() {
Other
};
// Used with err_module_odr_violation_record and
// note_module_odr_violation_record
enum ODRCXXRecordDifference {
StaticAssertCondition,
StaticAssertMessage,
StaticAssertOnlyMessage,
MethodName,
MethodDeleted,
MethodDefaulted,
MethodVirtual,
MethodStatic,
MethodVolatile,
MethodConst,
MethodInline,
MethodNumberParameters,
MethodParameterType,
MethodParameterName,
MethodParameterSingleDefaultArgument,
MethodParameterDifferentDefaultArgument,
MethodNoTemplateArguments,
MethodDifferentNumberTemplateArguments,
MethodDifferentTemplateArgument,
MethodSingleBody,
MethodDifferentBody,
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 ODRDiagField = [this, &ComputeQualTypeODRHash, &ComputeODRHash](
NamedDecl *FirstRecord, StringRef FirstModule,
StringRef SecondModule, FieldDecl *FirstField,
FieldDecl *SecondField) {
auto ODRDiagField = [this](NamedDecl *FirstRecord, StringRef FirstModule,
StringRef SecondModule,
const FieldDecl *FirstField,
const FieldDecl *SecondField) {
enum ODRFieldDifference {
FieldName,
FieldTypeName,
@ -9719,8 +9672,7 @@ void ASTReader::diagnoseOdrViolations() {
QualType FirstType = FirstField->getType();
QualType SecondType = SecondField->getType();
if (ComputeQualTypeODRHash(FirstType) !=
ComputeQualTypeODRHash(SecondType)) {
if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
DiagError(FieldTypeName) << FirstII << FirstType;
DiagNote(FieldTypeName) << SecondII << SecondType;
return true;
@ -9735,10 +9687,8 @@ void ASTReader::diagnoseOdrViolations() {
}
if (IsFirstBitField && IsSecondBitField) {
unsigned FirstBitWidthHash =
ComputeODRHash(FirstField->getBitWidth());
unsigned SecondBitWidthHash =
ComputeODRHash(SecondField->getBitWidth());
unsigned FirstBitWidthHash = computeODRHash(FirstField->getBitWidth());
unsigned SecondBitWidthHash = computeODRHash(SecondField->getBitWidth());
if (FirstBitWidthHash != SecondBitWidthHash) {
DiagError(FieldDifferentWidthBitField)
<< FirstII << FirstField->getBitWidth()->getSourceRange();
@ -9771,8 +9721,8 @@ void ASTReader::diagnoseOdrViolations() {
}
if (FirstInitializer && SecondInitializer) {
unsigned FirstInitHash = ComputeODRHash(FirstInitializer);
unsigned SecondInitHash = ComputeODRHash(SecondInitializer);
unsigned FirstInitHash = computeODRHash(FirstInitializer);
unsigned SecondInitHash = computeODRHash(SecondInitializer);
if (FirstInitHash != SecondInitHash) {
DiagError(FieldDifferentInitializers)
<< FirstII << FirstInitializer->getSourceRange();
@ -9786,10 +9736,9 @@ void ASTReader::diagnoseOdrViolations() {
};
auto ODRDiagTypeDefOrAlias =
[this, &ComputeQualTypeODRHash](
NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
TypedefNameDecl *FirstTD, TypedefNameDecl *SecondTD,
bool IsTypeAlias) {
[this](NamedDecl *FirstRecord, StringRef FirstModule,
StringRef SecondModule, const TypedefNameDecl *FirstTD,
const TypedefNameDecl *SecondTD, bool IsTypeAlias) {
enum ODRTypedefDifference {
TypedefName,
TypedefType,
@ -9809,8 +9758,8 @@ void ASTReader::diagnoseOdrViolations() {
<< SecondModule << SecondTD->getSourceRange() << DiffType;
};
auto FirstName = FirstTD->getDeclName();
auto SecondName = SecondTD->getDeclName();
DeclarationName FirstName = FirstTD->getDeclName();
DeclarationName SecondName = SecondTD->getDeclName();
if (FirstName != SecondName) {
DiagError(TypedefName) << IsTypeAlias << FirstName;
DiagNote(TypedefName) << IsTypeAlias << SecondName;
@ -9819,8 +9768,7 @@ void ASTReader::diagnoseOdrViolations() {
QualType FirstType = FirstTD->getUnderlyingType();
QualType SecondType = SecondTD->getUnderlyingType();
if (ComputeQualTypeODRHash(FirstType) !=
ComputeQualTypeODRHash(SecondType)) {
if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
DiagError(TypedefType) << IsTypeAlias << FirstName << FirstType;
DiagNote(TypedefType) << IsTypeAlias << SecondName << SecondType;
return true;
@ -9829,10 +9777,9 @@ void ASTReader::diagnoseOdrViolations() {
return false;
};
auto ODRDiagVar = [&ComputeQualTypeODRHash, &ComputeODRHash,
this](NamedDecl *FirstRecord, StringRef FirstModule,
StringRef SecondModule, VarDecl *FirstVD,
VarDecl *SecondVD) {
auto ODRDiagVar = [this](NamedDecl *FirstRecord, StringRef FirstModule,
StringRef SecondModule, const VarDecl *FirstVD,
const VarDecl *SecondVD) {
enum ODRVarDifference {
VarName,
VarType,
@ -9854,8 +9801,8 @@ void ASTReader::diagnoseOdrViolations() {
<< SecondModule << SecondVD->getSourceRange() << DiffType;
};
auto FirstName = FirstVD->getDeclName();
auto SecondName = SecondVD->getDeclName();
DeclarationName FirstName = FirstVD->getDeclName();
DeclarationName SecondName = SecondVD->getDeclName();
if (FirstName != SecondName) {
DiagError(VarName) << FirstName;
DiagNote(VarName) << SecondName;
@ -9864,8 +9811,7 @@ void ASTReader::diagnoseOdrViolations() {
QualType FirstType = FirstVD->getType();
QualType SecondType = SecondVD->getType();
if (ComputeQualTypeODRHash(FirstType) !=
ComputeQualTypeODRHash(SecondType)) {
if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
DiagError(VarType) << FirstName << FirstType;
DiagNote(VarType) << SecondName << SecondType;
return true;
@ -9887,7 +9833,7 @@ void ASTReader::diagnoseOdrViolations() {
}
if (FirstInit && SecondInit &&
ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
DiagError(VarDifferentInitializer)
<< FirstName << FirstInit->getSourceRange();
DiagNote(VarDifferentInitializer)
@ -9905,6 +9851,25 @@ void ASTReader::diagnoseOdrViolations() {
return false;
};
using DeclHashes = llvm::SmallVector<std::pair<Decl *, unsigned>, 4>;
auto PopulateHashes = [](DeclHashes &Hashes, RecordDecl *Record,
const DeclContext *DC) {
for (auto *D : Record->decls()) {
if (!ODRHash::isDeclToBeProcessed(D, DC))
continue;
Hashes.emplace_back(D, computeODRHash(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 = [](DeclHashes &FirstHashes, DeclHashes &SecondHashes) {
auto DifferenceSelector = [](Decl *D) {
assert(D && "valid Decl required");
switch (D->getKind()) {
@ -9943,27 +9908,6 @@ void ASTReader::diagnoseOdrViolations() {
}
};
using DeclHashes = llvm::SmallVector<std::pair<Decl *, unsigned>, 4>;
auto PopulateHashes = [&ComputeSubDeclODRHash](DeclHashes &Hashes,
RecordDecl *Record,
const DeclContext *DC) {
for (auto *D : Record->decls()) {
if (!ODRHash::isDeclToBeProcessed(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();
@ -10062,19 +10006,6 @@ void ASTReader::diagnoseOdrViolations() {
continue;
std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
auto ODRDiagDeclError = [FirstRecord, &FirstModule,
this](SourceLocation Loc, SourceRange Range,
ODRCXXRecordDifference DiffType) {
return Diag(Loc, diag::err_module_odr_violation_record)
<< FirstRecord << FirstModule.empty() << FirstModule << Range
<< DiffType;
};
auto ODRDiagDeclNote = [&SecondModule,
this](SourceLocation Loc, SourceRange Range,
ODRCXXRecordDifference DiffType) {
return Diag(Loc, diag::note_module_odr_violation_record)
<< SecondModule << Range << DiffType;
};
auto *FirstDD = FirstRecord->DefinitionData;
auto *SecondDD = RecordPair.second;
@ -10103,20 +10034,18 @@ void ASTReader::diagnoseOdrViolations() {
return Diag(Loc, diag::note_module_odr_violation_definition_data)
<< SecondModule << Range << DiffType;
};
auto GetSourceRange = [](struct CXXRecordDecl::DefinitionData *DD) {
unsigned NumBases = DD->NumBases;
if (NumBases == 0) return SourceRange();
ArrayRef<CXXBaseSpecifier> bases = DD->bases();
return SourceRange(bases[0].getBeginLoc(),
bases[NumBases - 1].getEndLoc());
};
unsigned FirstNumBases = FirstDD->NumBases;
unsigned FirstNumVBases = FirstDD->NumVBases;
unsigned SecondNumBases = SecondDD->NumBases;
unsigned SecondNumVBases = SecondDD->NumVBases;
auto GetSourceRange = [](struct CXXRecordDecl::DefinitionData *DD) {
unsigned NumBases = DD->NumBases;
if (NumBases == 0) return SourceRange();
auto bases = DD->bases();
return SourceRange(bases[0].getBeginLoc(),
bases[NumBases - 1].getEndLoc());
};
if (FirstNumBases != SecondNumBases) {
ODRDiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
NumBases)
@ -10139,30 +10068,30 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
auto FirstBases = FirstDD->bases();
auto SecondBases = SecondDD->bases();
unsigned i = 0;
for (i = 0; i < FirstNumBases; ++i) {
auto FirstBase = FirstBases[i];
auto SecondBase = SecondBases[i];
if (ComputeQualTypeODRHash(FirstBase.getType()) !=
ComputeQualTypeODRHash(SecondBase.getType())) {
ArrayRef<CXXBaseSpecifier> FirstBases = FirstDD->bases();
ArrayRef<CXXBaseSpecifier> SecondBases = SecondDD->bases();
unsigned I = 0;
for (I = 0; I < FirstNumBases; ++I) {
const CXXBaseSpecifier FirstBase = FirstBases[I];
const CXXBaseSpecifier SecondBase = SecondBases[I];
if (computeODRHash(FirstBase.getType()) !=
computeODRHash(SecondBase.getType())) {
ODRDiagBaseError(FirstRecord->getLocation(),
FirstBase.getSourceRange(), BaseType)
<< (i + 1) << FirstBase.getType();
<< (I + 1) << FirstBase.getType();
ODRDiagBaseNote(SecondRecord->getLocation(),
SecondBase.getSourceRange(), BaseType)
<< (i + 1) << SecondBase.getType();
<< (I + 1) << SecondBase.getType();
break;
}
if (FirstBase.isVirtual() != SecondBase.isVirtual()) {
ODRDiagBaseError(FirstRecord->getLocation(),
FirstBase.getSourceRange(), BaseVirtual)
<< (i + 1) << FirstBase.isVirtual() << FirstBase.getType();
<< (I + 1) << FirstBase.isVirtual() << FirstBase.getType();
ODRDiagBaseNote(SecondRecord->getLocation(),
SecondBase.getSourceRange(), BaseVirtual)
<< (i + 1) << SecondBase.isVirtual() << SecondBase.getType();
<< (I + 1) << SecondBase.isVirtual() << SecondBase.getType();
break;
}
@ -10170,17 +10099,17 @@ void ASTReader::diagnoseOdrViolations() {
SecondBase.getAccessSpecifierAsWritten()) {
ODRDiagBaseError(FirstRecord->getLocation(),
FirstBase.getSourceRange(), BaseAccess)
<< (i + 1) << FirstBase.getType()
<< (I + 1) << FirstBase.getType()
<< (int)FirstBase.getAccessSpecifierAsWritten();
ODRDiagBaseNote(SecondRecord->getLocation(),
SecondBase.getSourceRange(), BaseAccess)
<< (i + 1) << SecondBase.getType()
<< (I + 1) << SecondBase.getType()
<< (int)SecondBase.getAccessSpecifierAsWritten();
break;
}
}
if (i != FirstNumBases) {
if (I != FirstNumBases) {
Diagnosed = true;
break;
}
@ -10198,11 +10127,10 @@ void ASTReader::diagnoseOdrViolations() {
DeclHashes FirstTemplateHashes;
DeclHashes SecondTemplateHashes;
auto PopulateTemplateParameterHashs =
[&ComputeSubDeclODRHash](DeclHashes &Hashes,
auto PopulateTemplateParameterHashs = [](DeclHashes &Hashes,
const ClassTemplateDecl *TD) {
for (auto *D : TD->getTemplateParameters()->asArray()) {
Hashes.emplace_back(D, ComputeSubDeclODRHash(D));
Hashes.emplace_back(D, computeODRHash(D));
}
};
@ -10288,11 +10216,11 @@ void ASTReader::diagnoseOdrViolations() {
PopulateHashes(FirstHashes, FirstRecord, DC);
PopulateHashes(SecondHashes, SecondRecord, DC);
auto DR = FindTypeDiffs(FirstHashes, SecondHashes);
DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
Decl *FirstDecl = DR.FirstDecl;
Decl *SecondDecl = DR.SecondDecl;
const Decl *FirstDecl = DR.FirstDecl;
const Decl *SecondDecl = DR.SecondDecl;
if (FirstDiffType == Other || SecondDiffType == Other) {
DiagnoseODRUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
@ -10308,8 +10236,56 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
assert(FirstDiffType == SecondDiffType);
// Used with err_module_odr_violation_record and
// note_module_odr_violation_record
enum ODRCXXRecordDifference {
StaticAssertCondition,
StaticAssertMessage,
StaticAssertOnlyMessage,
MethodName,
MethodDeleted,
MethodDefaulted,
MethodVirtual,
MethodStatic,
MethodVolatile,
MethodConst,
MethodInline,
MethodNumberParameters,
MethodParameterType,
MethodParameterName,
MethodParameterSingleDefaultArgument,
MethodParameterDifferentDefaultArgument,
MethodNoTemplateArguments,
MethodDifferentNumberTemplateArguments,
MethodDifferentTemplateArgument,
MethodSingleBody,
MethodDifferentBody,
FriendTypeFunction,
FriendType,
FriendFunction,
FunctionTemplateDifferentNumberParameters,
FunctionTemplateParameterDifferentKind,
FunctionTemplateParameterName,
FunctionTemplateParameterSingleDefaultArgument,
FunctionTemplateParameterDifferentDefaultArgument,
FunctionTemplateParameterDifferentType,
FunctionTemplatePackParameter,
};
auto ODRDiagDeclError = [FirstRecord, &FirstModule,
this](SourceLocation Loc, SourceRange Range,
ODRCXXRecordDifference DiffType) {
return Diag(Loc, diag::err_module_odr_violation_record)
<< FirstRecord << FirstModule.empty() << FirstModule << Range
<< DiffType;
};
auto ODRDiagDeclNote = [&SecondModule,
this](SourceLocation Loc, SourceRange Range,
ODRCXXRecordDifference DiffType) {
return Diag(Loc, diag::note_module_odr_violation_record)
<< SecondModule << Range << DiffType;
};
assert(FirstDiffType == SecondDiffType);
switch (FirstDiffType) {
case Other:
case EndOfClass:
@ -10319,13 +10295,13 @@ void ASTReader::diagnoseOdrViolations() {
llvm_unreachable("Invalid diff type");
case StaticAssert: {
StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
Expr *FirstExpr = FirstSA->getAssertExpr();
Expr *SecondExpr = SecondSA->getAssertExpr();
unsigned FirstODRHash = ComputeODRHash(FirstExpr);
unsigned SecondODRHash = ComputeODRHash(SecondExpr);
const Expr *FirstExpr = FirstSA->getAssertExpr();
const Expr *SecondExpr = SecondSA->getAssertExpr();
unsigned FirstODRHash = computeODRHash(FirstExpr);
unsigned SecondODRHash = computeODRHash(SecondExpr);
if (FirstODRHash != SecondODRHash) {
ODRDiagDeclError(FirstExpr->getBeginLoc(),
FirstExpr->getSourceRange(), StaticAssertCondition);
@ -10335,8 +10311,8 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
StringLiteral *FirstStr = FirstSA->getMessage();
StringLiteral *SecondStr = SecondSA->getMessage();
const StringLiteral *FirstStr = FirstSA->getMessage();
const StringLiteral *SecondStr = SecondSA->getMessage();
assert((FirstStr || SecondStr) && "Both messages cannot be empty");
if ((FirstStr && !SecondStr) || (!FirstStr && SecondStr)) {
SourceLocation FirstLoc, SecondLoc;
@ -10451,8 +10427,8 @@ void ASTReader::diagnoseOdrViolations() {
// CXXMethodDecl::isStatic uses the canonical Decl. With Decl merging,
// FirstDecl is the canonical Decl of SecondDecl, so the storage
// class needs to be checked instead.
const auto FirstStorage = FirstMethod->getStorageClass();
const auto SecondStorage = SecondMethod->getStorageClass();
StorageClass FirstStorage = FirstMethod->getStorageClass();
StorageClass SecondStorage = SecondMethod->getStorageClass();
const bool FirstStatic = FirstStorage == SC_Static;
const bool SecondStatic = SecondStorage == SC_Static;
if (FirstStatic != SecondStatic) {
@ -10507,8 +10483,8 @@ void ASTReader::diagnoseOdrViolations() {
QualType FirstParamType = FirstParam->getType();
QualType SecondParamType = SecondParam->getType();
if (FirstParamType != SecondParamType &&
ComputeQualTypeODRHash(FirstParamType) !=
ComputeQualTypeODRHash(SecondParamType)) {
computeODRHash(FirstParamType) !=
computeODRHash(SecondParamType)) {
if (const DecayedType *ParamDecayedType =
FirstParamType->getAs<DecayedType>()) {
DiagMethodError(MethodParameterType)
@ -10555,14 +10531,13 @@ void ASTReader::diagnoseOdrViolations() {
}
if (FirstInit && SecondInit &&
ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
DiagMethodError(MethodParameterDifferentDefaultArgument)
<< (I + 1) << FirstInit->getSourceRange();
DiagMethodNote(MethodParameterDifferentDefaultArgument)
<< (I + 1) << SecondInit->getSourceRange();
ParameterMismatch = true;
break;
}
}
@ -10571,9 +10546,9 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
const auto *FirstTemplateArgs =
const TemplateArgumentList *FirstTemplateArgs =
FirstMethod->getTemplateSpecializationArgs();
const auto *SecondTemplateArgs =
const TemplateArgumentList *SecondTemplateArgs =
SecondMethod->getTemplateSpecializationArgs();
if ((FirstTemplateArgs && !SecondTemplateArgs) ||
@ -10619,8 +10594,7 @@ void ASTReader::diagnoseOdrViolations() {
for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
const TemplateArgument &FirstTA = *FirstExpandedList[i],
&SecondTA = *SecondExpandedList[i];
if (ComputeTemplateArgumentODRHash(FirstTA) ==
ComputeTemplateArgumentODRHash(SecondTA)) {
if (computeODRHash(FirstTA) == computeODRHash(SecondTA)) {
continue;
}
@ -10639,10 +10613,10 @@ void ASTReader::diagnoseOdrViolations() {
}
// Compute the hash of the method as if it has no body.
auto ComputeCXXMethodODRHash = [&Hash](const CXXMethodDecl *D) {
Hash.clear();
Hash.AddFunctionDecl(D, true /*SkipBody*/);
return Hash.CalculateHash();
auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) {
ODRHash Hasher;
Hasher.AddFunctionDecl(D, true /*SkipBody*/);
return Hasher.CalculateHash();
};
// Compare the hash generated to the hash stored. A difference means
@ -10684,11 +10658,11 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
case Friend: {
FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
NamedDecl *FirstND = FirstFriend->getFriendDecl();
NamedDecl *SecondND = SecondFriend->getFriendDecl();
const NamedDecl *FirstND = FirstFriend->getFriendDecl();
const NamedDecl *SecondND = SecondFriend->getFriendDecl();
TypeSourceInfo *FirstTSI = FirstFriend->getFriendType();
TypeSourceInfo *SecondTSI = SecondFriend->getFriendType();
@ -10707,8 +10681,8 @@ void ASTReader::diagnoseOdrViolations() {
if (FirstTSI && SecondTSI) {
QualType FirstFriendType = FirstTSI->getType();
QualType SecondFriendType = SecondTSI->getType();
assert(ComputeQualTypeODRHash(FirstFriendType) !=
ComputeQualTypeODRHash(SecondFriendType));
assert(computeODRHash(FirstFriendType) !=
computeODRHash(SecondFriendType));
ODRDiagDeclError(FirstFriend->getFriendLoc(),
FirstFriend->getSourceRange(), FriendType)
<< FirstFriendType;
@ -10729,9 +10703,9 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
case FunctionTemplate: {
FunctionTemplateDecl *FirstTemplate =
const FunctionTemplateDecl *FirstTemplate =
cast<FunctionTemplateDecl>(FirstDecl);
FunctionTemplateDecl *SecondTemplate =
const FunctionTemplateDecl *SecondTemplate =
cast<FunctionTemplateDecl>(SecondDecl);
TemplateParameterList *FirstTPL =
@ -10826,8 +10800,7 @@ void ASTReader::diagnoseOdrViolations() {
if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
QualType FirstType = FirstTTPD->getDefaultArgument();
QualType SecondType = SecondTTPD->getDefaultArgument();
if (ComputeQualTypeODRHash(FirstType) !=
ComputeQualTypeODRHash(SecondType)) {
if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
DiagTemplateError(
FunctionTemplateParameterDifferentDefaultArgument)
<< (i + 1) << FirstType;
@ -10862,6 +10835,14 @@ void ASTReader::diagnoseOdrViolations() {
TemplateParameterList *SecondTPL =
SecondTTPD->getTemplateParameters();
auto ComputeTemplateParameterListODRHash =
[](const TemplateParameterList *TPL) {
assert(TPL);
ODRHash Hasher;
Hasher.AddTemplateParameterList(TPL);
return Hasher.CalculateHash();
};
if (ComputeTemplateParameterListODRHash(FirstTPL) !=
ComputeTemplateParameterListODRHash(SecondTPL)) {
DiagTemplateError(FunctionTemplateParameterDifferentType)
@ -10892,8 +10873,7 @@ void ASTReader::diagnoseOdrViolations() {
FirstTTPD->getDefaultArgument().getArgument();
TemplateArgument SecondTA =
SecondTTPD->getDefaultArgument().getArgument();
if (ComputeTemplateArgumentODRHash(FirstTA) !=
ComputeTemplateArgumentODRHash(SecondTA)) {
if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {
DiagTemplateError(
FunctionTemplateParameterDifferentDefaultArgument)
<< (i + 1) << FirstTA;
@ -10925,8 +10905,7 @@ void ASTReader::diagnoseOdrViolations() {
QualType FirstType = FirstNTTPD->getType();
QualType SecondType = SecondNTTPD->getType();
if (ComputeQualTypeODRHash(FirstType) !=
ComputeQualTypeODRHash(SecondType)) {
if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
DiagTemplateError(FunctionTemplateParameterDifferentType)
<< (i + 1);
DiagTemplateNote(FunctionTemplateParameterDifferentType)
@ -10953,8 +10932,8 @@ void ASTReader::diagnoseOdrViolations() {
if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
Expr *FirstDefaultArgument = FirstNTTPD->getDefaultArgument();
Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument();
if (ComputeODRHash(FirstDefaultArgument) !=
ComputeODRHash(SecondDefaultArgument)) {
if (computeODRHash(FirstDefaultArgument) !=
computeODRHash(SecondDefaultArgument)) {
DiagTemplateError(
FunctionTemplateParameterDifferentDefaultArgument)
<< (i + 1) << FirstDefaultArgument;
@ -11050,8 +11029,8 @@ void ASTReader::diagnoseOdrViolations() {
<< SecondModule << Range << DiffType;
};
if (ComputeQualTypeODRHash(FirstFunction->getReturnType()) !=
ComputeQualTypeODRHash(SecondFunction->getReturnType())) {
if (computeODRHash(FirstFunction->getReturnType()) !=
computeODRHash(SecondFunction->getReturnType())) {
ODRDiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),
FirstFunction->getReturnTypeSourceRange(), ReturnType)
<< FirstFunction->getReturnType();
@ -11065,11 +11044,11 @@ void ASTReader::diagnoseOdrViolations() {
assert(FirstFunction->param_size() == SecondFunction->param_size() &&
"Merged functions with different number of parameters");
auto ParamSize = FirstFunction->param_size();
size_t ParamSize = FirstFunction->param_size();
bool ParameterMismatch = false;
for (unsigned I = 0; I < ParamSize; ++I) {
auto *FirstParam = FirstFunction->getParamDecl(I);
auto *SecondParam = SecondFunction->getParamDecl(I);
const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I);
const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I);
assert(getContext().hasSameType(FirstParam->getType(),
SecondParam->getType()) &&
@ -11089,8 +11068,7 @@ void ASTReader::diagnoseOdrViolations() {
QualType FirstParamType = FirstParam->getType();
QualType SecondParamType = SecondParam->getType();
if (FirstParamType != SecondParamType &&
ComputeQualTypeODRHash(FirstParamType) !=
ComputeQualTypeODRHash(SecondParamType)) {
computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) {
if (const DecayedType *ParamDecayedType =
FirstParamType->getAs<DecayedType>()) {
ODRDiagError(FirstParam->getLocation(),
@ -11134,7 +11112,7 @@ void ASTReader::diagnoseOdrViolations() {
}
if (FirstInit && SecondInit &&
ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
ParameterDifferentDefaultArgument)
<< (I + 1) << FirstInit->getSourceRange();
@ -11145,8 +11123,7 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
assert(ComputeSubDeclODRHash(FirstParam) ==
ComputeSubDeclODRHash(SecondParam) &&
assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) &&
"Undiagnosed parameter difference.");
}
@ -11191,16 +11168,14 @@ void ASTReader::diagnoseOdrViolations() {
using DeclHashes =
llvm::SmallVector<std::pair<EnumConstantDecl *, unsigned>, 4>;
auto PopulateHashes = [&ComputeSubDeclODRHash, FirstEnum](
DeclHashes &Hashes, EnumDecl *Enum) {
auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, EnumDecl *Enum) {
for (auto *D : Enum->decls()) {
// Due to decl merging, the first EnumDecl is the parent of
// Decls in both records.
if (!ODRHash::isDeclToBeProcessed(D, FirstEnum))
continue;
assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");
Hashes.emplace_back(cast<EnumConstantDecl>(D),
ComputeSubDeclODRHash(D));
Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D));
}
};
DeclHashes FirstHashes;
@ -11266,8 +11241,8 @@ void ASTReader::diagnoseOdrViolations() {
}
if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {
if (ComputeQualTypeODRHash(FirstUnderlyingType) !=
ComputeQualTypeODRHash(SecondUnderlyingType)) {
if (computeODRHash(FirstUnderlyingType) !=
computeODRHash(SecondUnderlyingType)) {
ODRDiagError(FirstEnum, DifferentSpecifiedTypes)
<< FirstUnderlyingType;
ODRDiagNote(SecondEnum, DifferentSpecifiedTypes)
@ -11292,39 +11267,38 @@ void ASTReader::diagnoseOdrViolations() {
for (unsigned I = 0; I < FirstHashes.size(); ++I) {
if (FirstHashes[I].second == SecondHashes[I].second)
continue;
const EnumConstantDecl *FirstEnumConstant = FirstHashes[I].first;
const EnumConstantDecl *SecondEnumConstant = SecondHashes[I].first;
const EnumConstantDecl *FirstConstant = FirstHashes[I].first;
const EnumConstantDecl *SecondConstant = SecondHashes[I].first;
if (FirstEnumConstant->getDeclName() !=
SecondEnumConstant->getDeclName()) {
if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) {
ODRDiagError(FirstEnumConstant, EnumConstantName)
<< I + 1 << FirstEnumConstant;
ODRDiagNote(SecondEnumConstant, EnumConstantName)
<< I + 1 << SecondEnumConstant;
ODRDiagError(FirstConstant, EnumConstantName)
<< I + 1 << FirstConstant;
ODRDiagNote(SecondConstant, EnumConstantName)
<< I + 1 << SecondConstant;
Diagnosed = true;
break;
}
const Expr *FirstInit = FirstEnumConstant->getInitExpr();
const Expr *SecondInit = SecondEnumConstant->getInitExpr();
const Expr *FirstInit = FirstConstant->getInitExpr();
const Expr *SecondInit = SecondConstant->getInitExpr();
if (!FirstInit && !SecondInit)
continue;
if (!FirstInit || !SecondInit) {
ODRDiagError(FirstEnumConstant, EnumConstantSingleInitializer)
<< I + 1 << FirstEnumConstant << (FirstInit != nullptr);
ODRDiagNote(SecondEnumConstant, EnumConstantSingleInitializer)
<< I + 1 << SecondEnumConstant << (SecondInit != nullptr);
ODRDiagError(FirstConstant, EnumConstantSingleInitializer)
<< I + 1 << FirstConstant << (FirstInit != nullptr);
ODRDiagNote(SecondConstant, EnumConstantSingleInitializer)
<< I + 1 << SecondConstant << (SecondInit != nullptr);
Diagnosed = true;
break;
}
if (ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
ODRDiagError(FirstEnumConstant, EnumConstantDifferentInitializer)
<< I + 1 << FirstEnumConstant;
ODRDiagNote(SecondEnumConstant, EnumConstantDifferentInitializer)
<< I + 1 << SecondEnumConstant;
if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
ODRDiagError(FirstConstant, EnumConstantDifferentInitializer)
<< I + 1 << FirstConstant;
ODRDiagNote(SecondConstant, EnumConstantDifferentInitializer)
<< I + 1 << SecondConstant;
Diagnosed = true;
break;
}