Revert r298824 & r298816, recommit r298742 & r298754
r299989 fixes the underlying issue by waiting long enough to late parsed
arguments to be processed before doing an calculating the hash.
r298742
[ODRHash] Add error messages for mismatched parameters in methods.
r298754
[ODRHash] Add support for array and decayed types.
llvm-svn: 300001
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 322fc86..da29f69 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9282,6 +9282,11 @@
MethodVolatile,
MethodConst,
MethodInline,
+ MethodNumberParameters,
+ MethodParameterType,
+ MethodParameterName,
+ MethodParameterSingleDefaultArgument,
+ MethodParameterDifferentDefaultArguments,
};
// These lambdas have the common portions of the ODR diagnostics. This
@@ -9606,6 +9611,104 @@
break;
}
+ const unsigned FirstNumParameters = FirstMethod->param_size();
+ const unsigned SecondNumParameters = SecondMethod->param_size();
+ if (FirstNumParameters != SecondNumParameters) {
+ ODRDiagError(FirstMethod->getLocation(),
+ FirstMethod->getSourceRange(), MethodNumberParameters)
+ << FirstName << FirstNumParameters;
+ ODRDiagNote(SecondMethod->getLocation(),
+ SecondMethod->getSourceRange(), MethodNumberParameters)
+ << SecondName << SecondNumParameters;
+ Diagnosed = true;
+ break;
+ }
+
+ // Need this status boolean to know when break out of the switch.
+ bool ParameterMismatch = false;
+ for (unsigned I = 0; I < FirstNumParameters; ++I) {
+ const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
+ const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
+
+ QualType FirstParamType = FirstParam->getType();
+ QualType SecondParamType = SecondParam->getType();
+ if (FirstParamType != SecondParamType) {
+ if (const DecayedType *ParamDecayedType =
+ FirstParamType->getAs<DecayedType>()) {
+ ODRDiagError(FirstMethod->getLocation(),
+ FirstMethod->getSourceRange(), MethodParameterType)
+ << FirstName << (I + 1) << FirstParamType << true
+ << ParamDecayedType->getOriginalType();
+ } else {
+ ODRDiagError(FirstMethod->getLocation(),
+ FirstMethod->getSourceRange(), MethodParameterType)
+ << FirstName << (I + 1) << FirstParamType << false;
+ }
+
+ if (const DecayedType *ParamDecayedType =
+ SecondParamType->getAs<DecayedType>()) {
+ ODRDiagNote(SecondMethod->getLocation(),
+ SecondMethod->getSourceRange(), MethodParameterType)
+ << SecondName << (I + 1) << SecondParamType << true
+ << ParamDecayedType->getOriginalType();
+ } else {
+ ODRDiagNote(SecondMethod->getLocation(),
+ SecondMethod->getSourceRange(), MethodParameterType)
+ << SecondName << (I + 1) << SecondParamType << false;
+ }
+ ParameterMismatch = true;
+ break;
+ }
+
+ DeclarationName FirstParamName = FirstParam->getDeclName();
+ DeclarationName SecondParamName = SecondParam->getDeclName();
+ if (FirstParamName != SecondParamName) {
+ ODRDiagError(FirstMethod->getLocation(),
+ FirstMethod->getSourceRange(), MethodParameterName)
+ << FirstName << (I + 1) << FirstParamName;
+ ODRDiagNote(SecondMethod->getLocation(),
+ SecondMethod->getSourceRange(), MethodParameterName)
+ << SecondName << (I + 1) << SecondParamName;
+ ParameterMismatch = true;
+ break;
+ }
+
+ const Expr* FirstDefaultArg = FirstParam->getDefaultArg();
+ const Expr* SecondDefaultArg = SecondParam->getDefaultArg();
+ if ((!FirstDefaultArg && SecondDefaultArg) ||
+ (FirstDefaultArg && !SecondDefaultArg)) {
+ ODRDiagError(FirstMethod->getLocation(),
+ FirstMethod->getSourceRange(),
+ MethodParameterSingleDefaultArgument)
+ << FirstName << (I + 1) << (FirstDefaultArg != nullptr);
+ ODRDiagNote(SecondMethod->getLocation(),
+ SecondMethod->getSourceRange(),
+ MethodParameterSingleDefaultArgument)
+ << SecondName << (I + 1) << (SecondDefaultArg != nullptr);
+ ParameterMismatch = true;
+ break;
+ }
+
+ if (ComputeODRHash(FirstDefaultArg) !=
+ ComputeODRHash(SecondDefaultArg)) {
+ ODRDiagError(FirstMethod->getLocation(),
+ FirstMethod->getSourceRange(),
+ MethodParameterDifferentDefaultArguments)
+ << FirstName << (I + 1);
+ ODRDiagNote(SecondMethod->getLocation(),
+ SecondMethod->getSourceRange(),
+ MethodParameterDifferentDefaultArguments)
+ << SecondName << (I + 1);
+ ParameterMismatch = true;
+ break;
+ }
+ }
+
+ if (ParameterMismatch) {
+ Diagnosed = true;
+ break;
+ }
+
break;
}
}