diff options
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 133 |
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; } } |