summaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r--lib/Serialization/ASTReader.cpp133
1 files changed, 109 insertions, 24 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 5312ad118d5bc..61b5a822c5520 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -5531,14 +5531,8 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
"Invalid data, not enough diag/map pairs");
while (Size--) {
unsigned DiagID = Record[Idx++];
- unsigned SeverityAndUpgradedFromWarning = Record[Idx++];
- bool WasUpgradedFromWarning =
- DiagnosticMapping::deserializeUpgradedFromWarning(
- SeverityAndUpgradedFromWarning);
DiagnosticMapping NewMapping =
- Diag.makeUserMapping(DiagnosticMapping::deserializeSeverity(
- SeverityAndUpgradedFromWarning),
- Loc);
+ DiagnosticMapping::deserialize(Record[Idx++]);
if (!NewMapping.isPragma() && !IncludeNonPragmaStates)
continue;
@@ -5547,14 +5541,12 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
// If this mapping was specified as a warning but the severity was
// upgraded due to diagnostic settings, simulate the current diagnostic
// settings (and use a warning).
- if (WasUpgradedFromWarning && !Mapping.isErrorOrFatal()) {
- Mapping = Diag.makeUserMapping(diag::Severity::Warning, Loc);
- continue;
+ if (NewMapping.wasUpgradedFromWarning() && !Mapping.isErrorOrFatal()) {
+ NewMapping.setSeverity(diag::Severity::Warning);
+ NewMapping.setUpgradedFromWarning(false);
}
- // Use the deserialized mapping verbatim.
Mapping = NewMapping;
- Mapping.setUpgradedFromWarning(WasUpgradedFromWarning);
}
return NewState;
};
@@ -5569,22 +5561,36 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
DiagStates.push_back(FirstState);
// Skip the initial diagnostic state from the serialized module.
- assert(Record[0] == 0 &&
+ assert(Record[1] == 0 &&
"Invalid data, unexpected backref in initial state");
- Idx = 2 + Record[1] * 2;
+ Idx = 3 + Record[2] * 2;
assert(Idx < Record.size() &&
"Invalid data, not enough state change pairs in initial state");
+ } else if (F.isModule()) {
+ // For an explicit module, preserve the flags from the module build
+ // command line (-w, -Weverything, -Werror, ...) along with any explicit
+ // -Wblah flags.
+ unsigned Flags = Record[Idx++];
+ DiagState Initial;
+ Initial.SuppressSystemWarnings = Flags & 1; Flags >>= 1;
+ Initial.ErrorsAsFatal = Flags & 1; Flags >>= 1;
+ Initial.WarningsAsErrors = Flags & 1; Flags >>= 1;
+ Initial.EnableAllWarnings = Flags & 1; Flags >>= 1;
+ Initial.IgnoreAllWarnings = Flags & 1; Flags >>= 1;
+ Initial.ExtBehavior = (diag::Severity)Flags;
+ FirstState = ReadDiagState(Initial, SourceLocation(), true);
+
+ // Set up the root buffer of the module to start with the initial
+ // diagnostic state of the module itself, to cover files that contain no
+ // explicit transitions (for which we did not serialize anything).
+ Diag.DiagStatesByLoc.Files[F.OriginalSourceFileID]
+ .StateTransitions.push_back({FirstState, 0});
} else {
- FirstState = ReadDiagState(
- F.isModule() ? DiagState() : *Diag.DiagStatesByLoc.CurDiagState,
- SourceLocation(), F.isModule());
-
- // For an explicit module, set up the root buffer of the module to start
- // with the initial diagnostic state of the module itself, to cover files
- // that contain no explicit transitions.
- if (F.isModule())
- Diag.DiagStatesByLoc.Files[F.OriginalSourceFileID]
- .StateTransitions.push_back({FirstState, 0});
+ // For prefix ASTs, start with whatever the user configured on the
+ // command line.
+ Idx++; // Skip flags.
+ FirstState = ReadDiagState(*Diag.DiagStatesByLoc.CurDiagState,
+ SourceLocation(), false);
}
// Read the state transitions.
@@ -9316,6 +9322,9 @@ void ASTReader::diagnoseOdrViolations() {
MethodVolatile,
MethodConst,
MethodInline,
+ MethodNumberParameters,
+ MethodParameterType,
+ MethodParameterName,
};
// These lambdas have the common portions of the ODR diagnostics. This
@@ -9346,6 +9355,12 @@ void ASTReader::diagnoseOdrViolations() {
return Hash.CalculateHash();
};
+ auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {
+ Hash.clear();
+ Hash.AddQualType(Ty);
+ return Hash.CalculateHash();
+ };
+
switch (FirstDiffType) {
case Other:
case EndOfClass:
@@ -9640,6 +9655,76 @@ void ASTReader::diagnoseOdrViolations() {
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 &&
+ ComputeQualTypeODRHash(FirstParamType) !=
+ ComputeQualTypeODRHash(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;
+ }
+ }
+
+ if (ParameterMismatch) {
+ Diagnosed = true;
+ break;
+ }
+
break;
}
}