From 15cb180dcbf84701f3af47983e223d0beaac3c9b Mon Sep 17 00:00:00 2001 From: Volodymyr Sapsai Date: Wed, 22 Jun 2022 20:18:42 -0700 Subject: [PATCH] [ODRHash diagnostics] Split `err_module_odr_violation_mismatch_decl_diff` into per-entity diagnostics. NFC. We'll need to add more cases for Objective-C entities and adding everything to `err_module_odr_violation_mismatch_decl_diff` makes it harder to work with over time. Differential Revision: https://reviews.llvm.org/D128488 --- .../clang/Basic/DiagnosticSerializationKinds.td | 87 ++++++++++++++-------- clang/lib/Serialization/ASTReader.cpp | 84 +++++++++++---------- 2 files changed, 103 insertions(+), 68 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td index 251242e..0bd3734 100644 --- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -177,20 +177,13 @@ def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found " "protected access specifier|static assert|field|method|type alias|typedef|" "data member|friend declaration|function template}1">; -def err_module_odr_violation_mismatch_decl_diff : Error< +def err_module_odr_violation_record : Error< "%q0 has different definitions in different modules; first difference is " "%select{definition in module '%2'|defined here}1 found " "%select{" "static assert with condition|" "static assert with message|" "static assert with %select{|no }4message|" - "field %4|" - "field %4 with type %5|" - "%select{non-|}5bitfield %4|" - "bitfield %4 with one width expression|" - "%select{non-|}5mutable field %4|" - "field %4 with %select{no|an}5 initalizer|" - "field %4 with an initializer|" "%select{method %5|constructor|destructor}4|" "%select{method %5|constructor|destructor}4 " "is %select{not deleted|deleted}6|" @@ -226,13 +219,6 @@ def err_module_odr_violation_mismatch_decl_diff : Error< "with %select{no body|body}6|" "%select{method %5|constructor|destructor}4 " "with body|" - "%select{typedef|type alias}4 name %5|" - "%select{typedef|type alias}4 %5 with underlying type %6|" - "data member with name %4|" - "data member %4 with type %5|" - "data member %4 with%select{out|}5 an initializer|" - "data member %4 with an initializer|" - "data member %4 %select{is constexpr|is not constexpr}5|" "friend %select{class|function}4|" "friend %4|" "friend function %4|" @@ -250,18 +236,11 @@ def err_module_odr_violation_mismatch_decl_diff : Error< "being a template parameter pack|" "}3">; -def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found " +def note_module_odr_violation_record : Note<"but in '%0' found " "%select{" "static assert with different condition|" "static assert with different message|" "static assert with %select{|no }2message|" - "field %2|" - "field %2 with type %3|" - "%select{non-|}3bitfield %2|" - "bitfield %2 with different width expression|" - "%select{non-|}3mutable field %2|" - "field %2 with %select{no|an}3 initializer|" - "field %2 with a different initializer|" "%select{method %3|constructor|destructor}2|" "%select{method %3|constructor|destructor}2 " "is %select{not deleted|deleted}4|" @@ -297,13 +276,6 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found " "with %select{no body|body}4|" "%select{method %3|constructor|destructor}2 " "with different body|" - "%select{typedef|type alias}2 name %3|" - "%select{typedef|type alias}2 %3 with different underlying type %4|" - "data member with name %2|" - "data member %2 with different type %3|" - "data member %2 with%select{out|}3 an initializer|" - "data member %2 with a different initializer|" - "data member %2 %select{is constexpr|is not constexpr}3|" "friend %select{class|function}2|" "friend %2|" "friend function %2|" @@ -321,6 +293,61 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found " "being a template parameter pack|" "}1">; +def err_module_odr_violation_field : Error< + "%q0 has different definitions in different modules; first difference is " + "%select{definition in module '%2'|defined here}1 found " + "%select{" + "field %4|" + "field %4 with type %5|" + "%select{non-|}5bitfield %4|" + "bitfield %4 with one width expression|" + "%select{non-|}5mutable field %4|" + "field %4 with %select{no|an}5 initalizer|" + "field %4 with an initializer" + "}3">; +def note_module_odr_violation_field : Note<"but in '%0' found " + "%select{" + "field %2|" + "field %2 with type %3|" + "%select{non-|}3bitfield %2|" + "bitfield %2 with different width expression|" + "%select{non-|}3mutable field %2|" + "field %2 with %select{no|an}3 initializer|" + "field %2 with a different initializer" + "}1">; + +def err_module_odr_violation_typedef : Error< + "%q0 has different definitions in different modules; first difference is " + "%select{definition in module '%2'|defined here}1 found " + "%select{" + "%select{typedef|type alias}4 name %5|" + "%select{typedef|type alias}4 %5 with underlying type %6" + "}3">; +def note_module_odr_violation_typedef : Note<"but in '%0' found " + "%select{" + "%select{typedef|type alias}2 name %3|" + "%select{typedef|type alias}2 %3 with different underlying type %4" + "}1">; + +def err_module_odr_violation_variable : Error< + "%q0 has different definitions in different modules; first difference is " + "%select{definition in module '%2'|defined here}1 found " + "%select{" + "data member with name %4|" + "data member %4 with type %5|" + "data member %4 with%select{out|}5 an initializer|" + "data member %4 with an initializer|" + "data member %4 %select{is constexpr|is not constexpr}5" + "}3">; +def note_module_odr_violation_variable : Note<"but in '%0' found " + "%select{" + "data member with name %2|" + "data member %2 with different type %3|" + "data member %2 with%select{out|}3 an initializer|" + "data member %2 with a different initializer|" + "data member %2 %select{is constexpr|is not constexpr}3" + "}1">; + def err_module_odr_violation_function : Error< "%q0 has different definitions in different modules; " "%select{definition in module '%2'|defined here}1 " diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 6bfd816..37371ef 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9637,19 +9637,12 @@ void ASTReader::diagnoseOdrViolations() { Other }; - // Used with err_module_odr_violation_mismatch_decl_diff and - // note_module_odr_violation_mismatch_decl_diff - enum ODRMismatchDeclDifference { + // Used with err_module_odr_violation_record and + // note_module_odr_violation_record + enum ODRCXXRecordDifference { StaticAssertCondition, StaticAssertMessage, StaticAssertOnlyMessage, - FieldName, - FieldTypeName, - FieldSingleBitField, - FieldDifferentWidthBitField, - FieldSingleMutable, - FieldSingleInitializer, - FieldDifferentInitializers, MethodName, MethodDeleted, MethodDefaulted, @@ -9668,13 +9661,6 @@ void ASTReader::diagnoseOdrViolations() { MethodDifferentTemplateArgument, MethodSingleBody, MethodDifferentBody, - TypedefName, - TypedefType, - VarName, - VarType, - VarSingleInitializer, - VarDifferentInitializer, - VarConstexpr, FriendTypeFunction, FriendType, FriendFunction, @@ -9694,17 +9680,27 @@ void ASTReader::diagnoseOdrViolations() { NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule, FieldDecl *FirstField, FieldDecl *SecondField) { + enum ODRFieldDifference { + FieldName, + FieldTypeName, + FieldSingleBitField, + FieldDifferentWidthBitField, + FieldSingleMutable, + FieldSingleInitializer, + FieldDifferentInitializers, + }; + auto DiagError = [FirstRecord, FirstField, FirstModule, - this](ODRMismatchDeclDifference DiffType) { + this](ODRFieldDifference DiffType) { return Diag(FirstField->getLocation(), - diag::err_module_odr_violation_mismatch_decl_diff) + diag::err_module_odr_violation_field) << FirstRecord << FirstModule.empty() << FirstModule << FirstField->getSourceRange() << DiffType; }; auto DiagNote = [SecondField, SecondModule, - this](ODRMismatchDeclDifference DiffType) { + this](ODRFieldDifference DiffType) { return Diag(SecondField->getLocation(), - diag::note_module_odr_violation_mismatch_decl_diff) + diag::note_module_odr_violation_field) << SecondModule << SecondField->getSourceRange() << DiffType; }; @@ -9792,17 +9788,22 @@ void ASTReader::diagnoseOdrViolations() { NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule, TypedefNameDecl *FirstTD, TypedefNameDecl *SecondTD, bool IsTypeAlias) { + enum ODRTypedefDifference { + TypedefName, + TypedefType, + }; + auto DiagError = [FirstRecord, FirstTD, FirstModule, - this](ODRMismatchDeclDifference DiffType) { + this](ODRTypedefDifference DiffType) { return Diag(FirstTD->getLocation(), - diag::err_module_odr_violation_mismatch_decl_diff) + diag::err_module_odr_violation_typedef) << FirstRecord << FirstModule.empty() << FirstModule << FirstTD->getSourceRange() << DiffType; }; auto DiagNote = [SecondTD, SecondModule, - this](ODRMismatchDeclDifference DiffType) { + this](ODRTypedefDifference DiffType) { return Diag(SecondTD->getLocation(), - diag::note_module_odr_violation_mismatch_decl_diff) + diag::note_module_odr_violation_typedef) << SecondModule << SecondTD->getSourceRange() << DiffType; }; @@ -9830,17 +9831,24 @@ void ASTReader::diagnoseOdrViolations() { this](NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule, VarDecl *FirstVD, VarDecl *SecondVD) { + enum ODRVarDifference { + VarName, + VarType, + VarSingleInitializer, + VarDifferentInitializer, + VarConstexpr, + }; + auto DiagError = [FirstRecord, FirstVD, FirstModule, - this](ODRMismatchDeclDifference DiffType) { + this](ODRVarDifference DiffType) { return Diag(FirstVD->getLocation(), - diag::err_module_odr_violation_mismatch_decl_diff) + diag::err_module_odr_violation_variable) << FirstRecord << FirstModule.empty() << FirstModule << FirstVD->getSourceRange() << DiffType; }; - auto DiagNote = [SecondVD, SecondModule, - this](ODRMismatchDeclDifference DiffType) { + auto DiagNote = [SecondVD, SecondModule, this](ODRVarDifference DiffType) { return Diag(SecondVD->getLocation(), - diag::note_module_odr_violation_mismatch_decl_diff) + diag::note_module_odr_violation_variable) << SecondModule << SecondVD->getSourceRange() << DiffType; }; @@ -10053,15 +10061,15 @@ void ASTReader::diagnoseOdrViolations() { std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord); auto ODRDiagDeclError = [FirstRecord, &FirstModule, this](SourceLocation Loc, SourceRange Range, - ODRMismatchDeclDifference DiffType) { - return Diag(Loc, diag::err_module_odr_violation_mismatch_decl_diff) + 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, - ODRMismatchDeclDifference DiffType) { - return Diag(Loc, diag::note_module_odr_violation_mismatch_decl_diff) + ODRCXXRecordDifference DiffType) { + return Diag(Loc, diag::note_module_odr_violation_record) << SecondModule << Range << DiffType; }; @@ -10388,13 +10396,13 @@ void ASTReader::diagnoseOdrViolations() { DeclarationName FirstName = FirstMethod->getDeclName(); DeclarationName SecondName = SecondMethod->getDeclName(); auto DiagMethodError = [&ODRDiagDeclError, FirstMethod, FirstMethodType, - FirstName](ODRMismatchDeclDifference DiffType) { + FirstName](ODRCXXRecordDifference DiffType) { return ODRDiagDeclError(FirstMethod->getLocation(), FirstMethod->getSourceRange(), DiffType) << FirstMethodType << FirstName; }; auto DiagMethodNote = [&ODRDiagDeclNote, SecondMethod, SecondMethodType, - SecondName](ODRMismatchDeclDifference DiffType) { + SecondName](ODRCXXRecordDifference DiffType) { return ODRDiagDeclNote(SecondMethod->getLocation(), SecondMethod->getSourceRange(), DiffType) << SecondMethodType << SecondName; @@ -10729,13 +10737,13 @@ void ASTReader::diagnoseOdrViolations() { SecondTemplate->getTemplateParameters(); auto DiagTemplateError = [&ODRDiagDeclError, FirstTemplate]( - ODRMismatchDeclDifference DiffType) { + ODRCXXRecordDifference DiffType) { return ODRDiagDeclError(FirstTemplate->getLocation(), FirstTemplate->getSourceRange(), DiffType) << FirstTemplate; }; auto DiagTemplateNote = [&ODRDiagDeclNote, SecondTemplate]( - ODRMismatchDeclDifference DiffType) { + ODRCXXRecordDifference DiffType) { return ODRDiagDeclNote(SecondTemplate->getLocation(), SecondTemplate->getSourceRange(), DiffType) << SecondTemplate; -- 2.7.4