r357394 - [ASTImporter] Make ODR error handling configurable

Gabor Marton via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 1 07:46:53 PDT 2019


Author: martong
Date: Mon Apr  1 07:46:53 2019
New Revision: 357394

URL: http://llvm.org/viewvc/llvm-project?rev=357394&view=rev
Log:
[ASTImporter] Make ODR error handling configurable

Summary:
ODR errors are not necessarily true errors during the import of ASTs.
ASTMerge and CrossTU should use the warning equivalent of every CTU error,
while Sema should emit errors as before.

Reviewers: martong, a_sidorin, shafik, a.sidorin

Reviewed By: a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58897

Patch by Endre Fulop!

Modified:
    cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h
    cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp

Modified: cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h?rev=357394&r1=357393&r2=357394&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h (original)
+++ cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h Mon Apr  1 07:46:53 2019
@@ -111,6 +111,10 @@ struct StructuralEquivalenceContext {
   static llvm::Optional<unsigned>
   findUntaggedStructOrUnionIndex(RecordDecl *Anon);
 
+  // If ErrorOnTagTypeMismatch is set, return the the error, otherwise get the
+  // relevant warning for the input error diagnostic.
+  unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
+
 private:
   /// Finish checking all of the structural equivalences.
   ///

Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=357394&r1=357393&r2=357394&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Mon Apr  1 07:46:53 2019
@@ -224,20 +224,31 @@ let CategoryName = "VTable ABI Issue" in
 def err_odr_variable_type_inconsistent : Error<
   "external variable %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
+def warn_odr_variable_type_inconsistent : Warning<
+  "external variable %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup<ODR>;
 def err_odr_variable_multiple_def : Error<
   "external variable %0 defined in multiple translation units">;
+def warn_odr_variable_multiple_def : Warning<
+  "external variable %0 defined in multiple translation units">,
+  InGroup<ODR>;
 def note_odr_value_here : Note<"declared here with type %0">;
 def note_odr_defined_here : Note<"also defined here">;
 def err_odr_function_type_inconsistent : Error<
   "external function %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
-def warn_odr_tag_type_inconsistent
-    : Warning<"type %0 has incompatible definitions in different translation "
-              "units">,
-      InGroup<DiagGroup<"odr">>;
+def warn_odr_function_type_inconsistent : Warning<
+  "external function %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup<ODR>;
 def err_odr_tag_type_inconsistent
     : Error<"type %0 has incompatible definitions in different translation "
             "units">;
+def warn_odr_tag_type_inconsistent
+    : Warning<"type %0 has incompatible definitions in different translation "
+              "units">,
+      InGroup<ODR>;
 def note_odr_tag_kind_here: Note<
   "%0 is a %select{struct|interface|union|class|enum}1 here">;
 def note_odr_field : Note<"field %0 has type %1 here">;
@@ -253,44 +264,82 @@ def note_odr_number_of_bases : Note<
   "class has %0 base %plural{1:class|:classes}0">;
 def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
 def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
-
 def err_odr_field_type_inconsistent : Error<
   "field %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
+def warn_odr_field_type_inconsistent : Warning<
+  "field %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup<ODR>;
 
 // Importing Objective-C ASTs
 def err_odr_ivar_type_inconsistent : Error<
   "instance variable %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
+def warn_odr_ivar_type_inconsistent : Warning<
+  "instance variable %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup<ODR>;
 def err_odr_objc_superclass_inconsistent : Error<
   "class %0 has incompatible superclasses">;
+def warn_odr_objc_superclass_inconsistent : Warning<
+  "class %0 has incompatible superclasses">,
+  InGroup<ODR>;
 def note_odr_objc_superclass : Note<"inherits from superclass %0 here">;
 def note_odr_objc_missing_superclass : Note<"no corresponding superclass here">;
 def err_odr_objc_method_result_type_inconsistent : Error<
   "%select{class|instance}0 method %1 has incompatible result types in "
   "different translation units (%2 vs. %3)">;
+def warn_odr_objc_method_result_type_inconsistent : Warning<
+  "%select{class|instance}0 method %1 has incompatible result types in "
+  "different translation units (%2 vs. %3)">,
+  InGroup<ODR>;
 def err_odr_objc_method_num_params_inconsistent : Error<
   "%select{class|instance}0 method %1 has a different number of parameters in "
   "different translation units (%2 vs. %3)">;
+def warn_odr_objc_method_num_params_inconsistent : Warning<
+  "%select{class|instance}0 method %1 has a different number of parameters in "
+  "different translation units (%2 vs. %3)">,
+  InGroup<ODR>;
 def err_odr_objc_method_param_type_inconsistent : Error<
   "%select{class|instance}0 method %1 has a parameter with a different types "
   "in different translation units (%2 vs. %3)">;
+def warn_odr_objc_method_param_type_inconsistent : Warning<
+  "%select{class|instance}0 method %1 has a parameter with a different types "
+  "in different translation units (%2 vs. %3)">,
+  InGroup<ODR>;
 def err_odr_objc_method_variadic_inconsistent : Error<
   "%select{class|instance}0 method %1 is variadic in one translation unit "
   "and not variadic in another">;
+def warn_odr_objc_method_variadic_inconsistent : Warning<
+  "%select{class|instance}0 method %1 is variadic in one translation unit "
+  "and not variadic in another">,
+  InGroup<ODR>;
 def note_odr_objc_method_here : Note<
   "%select{class|instance}0 method %1 also declared here">;
 def err_odr_objc_property_type_inconsistent : Error<
   "property %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
+def warn_odr_objc_property_type_inconsistent : Warning<
+  "property %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup<ODR>;
 def err_odr_objc_property_impl_kind_inconsistent : Error<
   "property %0 is implemented with %select{@synthesize|@dynamic}1 in one "
   "translation but %select{@dynamic|@synthesize}1 in another translation unit">;
+def warn_odr_objc_property_impl_kind_inconsistent : Warning<
+  "property %0 is implemented with %select{@synthesize|@dynamic}1 in one "
+  "translation but %select{@dynamic|@synthesize}1 in another translation unit">,
+  InGroup<ODR>;
 def note_odr_objc_property_impl_kind : Note<
   "property %0 is implemented with %select{@synthesize|@dynamic}1 here">;
 def err_odr_objc_synthesize_ivar_inconsistent : Error<
   "property %0 is synthesized to different ivars in different translation "
   "units (%1 vs. %2)">;
+def warn_odr_objc_synthesize_ivar_inconsistent : Warning<
+  "property %0 is synthesized to different ivars in different translation "
+  "units (%1 vs. %2)">,
+  InGroup<ODR>;
 def note_odr_objc_synthesize_ivar_here : Note<
   "property is synthesized to ivar %0 here">;
 
@@ -299,19 +348,32 @@ def note_odr_friend : Note<"friend decla
 def note_odr_missing_friend : Note<"no corresponding friend here">;
 def err_odr_different_num_template_parameters : Error<
   "template parameter lists have a different number of parameters (%0 vs %1)">;
+def warn_odr_different_num_template_parameters : Warning<
+  "template parameter lists have a different number of parameters (%0 vs %1)">,
+  InGroup<ODR>;
 def note_odr_template_parameter_list : Note<
   "template parameter list also declared here">;
 def err_odr_different_template_parameter_kind : Error<
   "template parameter has different kinds in different translation units">;
+def warn_odr_different_template_parameter_kind : Warning<
+  "template parameter has different kinds in different translation units">,
+  InGroup<ODR>;
 def note_odr_template_parameter_here : Note<
   "template parameter declared here">;
 def err_odr_parameter_pack_non_pack : Error<
   "parameter kind mismatch; parameter is %select{not a|a}0 parameter pack">;
+def warn_odr_parameter_pack_non_pack : Warning<
+  "parameter kind mismatch; parameter is %select{not a|a}0 parameter pack">,
+  InGroup<ODR>;
 def note_odr_parameter_pack_non_pack : Note<
   "%select{parameter|parameter pack}0 declared here">;
 def err_odr_non_type_parameter_type_inconsistent : Error<
   "non-type template parameter declared with incompatible types in different "
   "translation units (%0 vs. %1)">;
+def warn_odr_non_type_parameter_type_inconsistent : Warning<
+  "non-type template parameter declared with incompatible types in different "
+  "translation units (%0 vs. %1)">,
+  InGroup<ODR>;
 def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
 
 def remark_sanitize_address_insert_extra_padding_accepted : Remark<

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=357394&r1=357393&r2=357394&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Mon Apr  1 07:46:53 2019
@@ -16,6 +16,7 @@ def Implicit : DiagGroup<"implicit", [
 ]>;
 
 // Empty DiagGroups are recognized by clang but ignored.
+def ODR : DiagGroup<"odr">;
 def : DiagGroup<"abi">;
 def AbsoluteValue : DiagGroup<"absolute-value">;
 def AddressOfTemporary : DiagGroup<"address-of-temporary">;

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=357394&r1=357393&r2=357394&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Mon Apr  1 07:46:53 2019
@@ -860,10 +860,9 @@ static bool IsStructurallyEquivalent(Str
   IdentifierInfo *Name2 = Field2->getIdentifier();
   if (!::IsStructurallyEquivalent(Name1, Name2)) {
     if (Context.Complain) {
-      Context.Diag2(Owner2->getLocation(),
-                    Context.ErrorOnTagTypeMismatch
-                        ? diag::err_odr_tag_type_inconsistent
-                        : diag::warn_odr_tag_type_inconsistent)
+      Context.Diag2(
+          Owner2->getLocation(),
+          Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
           << Context.ToCtx.getTypeDeclType(Owner2);
       Context.Diag2(Field2->getLocation(), diag::note_odr_field_name)
           << Field2->getDeclName();
@@ -876,10 +875,9 @@ static bool IsStructurallyEquivalent(Str
   if (!IsStructurallyEquivalent(Context, Field1->getType(),
                                 Field2->getType())) {
     if (Context.Complain) {
-      Context.Diag2(Owner2->getLocation(),
-                    Context.ErrorOnTagTypeMismatch
-                        ? diag::err_odr_tag_type_inconsistent
-                        : diag::warn_odr_tag_type_inconsistent)
+      Context.Diag2(
+          Owner2->getLocation(),
+          Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
           << Context.ToCtx.getTypeDeclType(Owner2);
       Context.Diag2(Field2->getLocation(), diag::note_odr_field)
           << Field2->getDeclName() << Field2->getType();
@@ -891,10 +889,9 @@ static bool IsStructurallyEquivalent(Str
 
   if (Field1->isBitField() != Field2->isBitField()) {
     if (Context.Complain) {
-      Context.Diag2(Owner2->getLocation(),
-                    Context.ErrorOnTagTypeMismatch
-                        ? diag::err_odr_tag_type_inconsistent
-                        : diag::warn_odr_tag_type_inconsistent)
+      Context.Diag2(
+          Owner2->getLocation(),
+          Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
           << Context.ToCtx.getTypeDeclType(Owner2);
       if (Field1->isBitField()) {
         Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
@@ -921,9 +918,8 @@ static bool IsStructurallyEquivalent(Str
     if (Bits1 != Bits2) {
       if (Context.Complain) {
         Context.Diag2(Owner2->getLocation(),
-                      Context.ErrorOnTagTypeMismatch
-                          ? diag::err_odr_tag_type_inconsistent
-                          : diag::warn_odr_tag_type_inconsistent)
+                      Context.getApplicableDiagnostic(
+                          diag::err_odr_tag_type_inconsistent))
             << Context.ToCtx.getTypeDeclType(Owner2);
         Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
             << Field2->getDeclName() << Field2->getType() << Bits2;
@@ -992,10 +988,8 @@ static bool IsStructurallyEquivalent(Str
                                      RecordDecl *D1, RecordDecl *D2) {
   if (D1->isUnion() != D2->isUnion()) {
     if (Context.Complain) {
-      Context.Diag2(D2->getLocation(),
-                    Context.ErrorOnTagTypeMismatch
-                        ? diag::err_odr_tag_type_inconsistent
-                        : diag::warn_odr_tag_type_inconsistent)
+      Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+                                           diag::err_odr_tag_type_inconsistent))
           << Context.ToCtx.getTypeDeclType(D2);
       Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
           << D1->getDeclName() << (unsigned)D1->getTagKind();
@@ -1072,7 +1066,9 @@ static bool IsStructurallyEquivalent(Str
 
       if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
         if (Context.Complain) {
-          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+          Context.Diag2(D2->getLocation(),
+                        Context.getApplicableDiagnostic(
+                            diag::err_odr_tag_type_inconsistent))
               << Context.ToCtx.getTypeDeclType(D2);
           Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
               << D2CXX->getNumBases();
@@ -1091,7 +1087,8 @@ static bool IsStructurallyEquivalent(Str
                                       Base2->getType())) {
           if (Context.Complain) {
             Context.Diag2(D2->getLocation(),
-                          diag::warn_odr_tag_type_inconsistent)
+                          Context.getApplicableDiagnostic(
+                              diag::err_odr_tag_type_inconsistent))
                 << Context.ToCtx.getTypeDeclType(D2);
             Context.Diag2(Base2->getBeginLoc(), diag::note_odr_base)
                 << Base2->getType() << Base2->getSourceRange();
@@ -1105,7 +1102,8 @@ static bool IsStructurallyEquivalent(Str
         if (Base1->isVirtual() != Base2->isVirtual()) {
           if (Context.Complain) {
             Context.Diag2(D2->getLocation(),
-                          diag::warn_odr_tag_type_inconsistent)
+                          Context.getApplicableDiagnostic(
+                              diag::err_odr_tag_type_inconsistent))
                 << Context.ToCtx.getTypeDeclType(D2);
             Context.Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
                 << Base2->isVirtual() << Base2->getSourceRange();
@@ -1118,15 +1116,16 @@ static bool IsStructurallyEquivalent(Str
 
       // Check the friends for consistency.
       CXXRecordDecl::friend_iterator Friend2 = D2CXX->friend_begin(),
-              Friend2End = D2CXX->friend_end();
+                                     Friend2End = D2CXX->friend_end();
       for (CXXRecordDecl::friend_iterator Friend1 = D1CXX->friend_begin(),
-                   Friend1End = D1CXX->friend_end();
+                                          Friend1End = D1CXX->friend_end();
            Friend1 != Friend1End; ++Friend1, ++Friend2) {
         if (Friend2 == Friend2End) {
           if (Context.Complain) {
             Context.Diag2(D2->getLocation(),
-                          diag::warn_odr_tag_type_inconsistent)
-                    << Context.ToCtx.getTypeDeclType(D2CXX);
+                          Context.getApplicableDiagnostic(
+                              diag::err_odr_tag_type_inconsistent))
+                << Context.ToCtx.getTypeDeclType(D2CXX);
             Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
             Context.Diag2(D2->getLocation(), diag::note_odr_missing_friend);
           }
@@ -1135,8 +1134,10 @@ static bool IsStructurallyEquivalent(Str
 
         if (!IsStructurallyEquivalent(Context, *Friend1, *Friend2)) {
           if (Context.Complain) {
-            Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-              << Context.ToCtx.getTypeDeclType(D2CXX);
+            Context.Diag2(D2->getLocation(),
+                          Context.getApplicableDiagnostic(
+                              diag::err_odr_tag_type_inconsistent))
+                << Context.ToCtx.getTypeDeclType(D2CXX);
             Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
             Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
           }
@@ -1146,8 +1147,10 @@ static bool IsStructurallyEquivalent(Str
 
       if (Friend2 != Friend2End) {
         if (Context.Complain) {
-          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-                  << Context.ToCtx.getTypeDeclType(D2);
+          Context.Diag2(D2->getLocation(),
+                        Context.getApplicableDiagnostic(
+                            diag::err_odr_tag_type_inconsistent))
+              << Context.ToCtx.getTypeDeclType(D2);
           Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
           Context.Diag1(D1->getLocation(), diag::note_odr_missing_friend);
         }
@@ -1155,7 +1158,9 @@ static bool IsStructurallyEquivalent(Str
       }
     } else if (D1CXX->getNumBases() > 0) {
       if (Context.Complain) {
-        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+        Context.Diag2(D2->getLocation(),
+                      Context.getApplicableDiagnostic(
+                          diag::err_odr_tag_type_inconsistent))
             << Context.ToCtx.getTypeDeclType(D2);
         const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
         Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
@@ -1175,9 +1180,8 @@ static bool IsStructurallyEquivalent(Str
     if (Field2 == Field2End) {
       if (Context.Complain) {
         Context.Diag2(D2->getLocation(),
-                      Context.ErrorOnTagTypeMismatch
-                          ? diag::err_odr_tag_type_inconsistent
-                          : diag::warn_odr_tag_type_inconsistent)
+                      Context.getApplicableDiagnostic(
+                          diag::err_odr_tag_type_inconsistent))
             << Context.ToCtx.getTypeDeclType(D2);
         Context.Diag1(Field1->getLocation(), diag::note_odr_field)
             << Field1->getDeclName() << Field1->getType();
@@ -1192,10 +1196,8 @@ static bool IsStructurallyEquivalent(Str
 
   if (Field2 != Field2End) {
     if (Context.Complain) {
-      Context.Diag2(D2->getLocation(),
-                    Context.ErrorOnTagTypeMismatch
-                        ? diag::err_odr_tag_type_inconsistent
-                        : diag::warn_odr_tag_type_inconsistent)
+      Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+                                           diag::err_odr_tag_type_inconsistent))
           << Context.ToCtx.getTypeDeclType(D2);
       Context.Diag2(Field2->getLocation(), diag::note_odr_field)
           << Field2->getDeclName() << Field2->getType();
@@ -1226,9 +1228,8 @@ static bool IsStructurallyEquivalent(Str
     if (EC2 == EC2End) {
       if (Context.Complain) {
         Context.Diag2(D2->getLocation(),
-                      Context.ErrorOnTagTypeMismatch
-                          ? diag::err_odr_tag_type_inconsistent
-                          : diag::warn_odr_tag_type_inconsistent)
+                      Context.getApplicableDiagnostic(
+                          diag::err_odr_tag_type_inconsistent))
             << Context.ToCtx.getTypeDeclType(D2);
         Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
             << EC1->getDeclName() << EC1->getInitVal().toString(10);
@@ -1243,9 +1244,8 @@ static bool IsStructurallyEquivalent(Str
         !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
       if (Context.Complain) {
         Context.Diag2(D2->getLocation(),
-                      Context.ErrorOnTagTypeMismatch
-                          ? diag::err_odr_tag_type_inconsistent
-                          : diag::warn_odr_tag_type_inconsistent)
+                      Context.getApplicableDiagnostic(
+                          diag::err_odr_tag_type_inconsistent))
             << Context.ToCtx.getTypeDeclType(D2);
         Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
             << EC2->getDeclName() << EC2->getInitVal().toString(10);
@@ -1258,10 +1258,8 @@ static bool IsStructurallyEquivalent(Str
 
   if (EC2 != EC2End) {
     if (Context.Complain) {
-      Context.Diag2(D2->getLocation(),
-                    Context.ErrorOnTagTypeMismatch
-                        ? diag::err_odr_tag_type_inconsistent
-                        : diag::warn_odr_tag_type_inconsistent)
+      Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+                                           diag::err_odr_tag_type_inconsistent))
           << Context.ToCtx.getTypeDeclType(D2);
       Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
           << EC2->getDeclName() << EC2->getInitVal().toString(10);
@@ -1279,7 +1277,8 @@ static bool IsStructurallyEquivalent(Str
   if (Params1->size() != Params2->size()) {
     if (Context.Complain) {
       Context.Diag2(Params2->getTemplateLoc(),
-                    diag::err_odr_different_num_template_parameters)
+                    Context.getApplicableDiagnostic(
+                        diag::err_odr_different_num_template_parameters))
           << Params1->size() << Params2->size();
       Context.Diag1(Params1->getTemplateLoc(),
                     diag::note_odr_template_parameter_list);
@@ -1291,7 +1290,8 @@ static bool IsStructurallyEquivalent(Str
     if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
       if (Context.Complain) {
         Context.Diag2(Params2->getParam(I)->getLocation(),
-                      diag::err_odr_different_template_parameter_kind);
+                      Context.getApplicableDiagnostic(
+                          diag::err_odr_different_template_parameter_kind));
         Context.Diag1(Params1->getParam(I)->getLocation(),
                       diag::note_odr_template_parameter_here);
       }
@@ -1311,7 +1311,9 @@ static bool IsStructurallyEquivalent(Str
                                      TemplateTypeParmDecl *D2) {
   if (D1->isParameterPack() != D2->isParameterPack()) {
     if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+      Context.Diag2(D2->getLocation(),
+                    Context.getApplicableDiagnostic(
+                        diag::err_odr_parameter_pack_non_pack))
           << D2->isParameterPack();
       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
           << D1->isParameterPack();
@@ -1327,7 +1329,9 @@ static bool IsStructurallyEquivalent(Str
                                      NonTypeTemplateParmDecl *D2) {
   if (D1->isParameterPack() != D2->isParameterPack()) {
     if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+      Context.Diag2(D2->getLocation(),
+                    Context.getApplicableDiagnostic(
+                        diag::err_odr_parameter_pack_non_pack))
           << D2->isParameterPack();
       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
           << D1->isParameterPack();
@@ -1339,7 +1343,8 @@ static bool IsStructurallyEquivalent(Str
   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
     if (Context.Complain) {
       Context.Diag2(D2->getLocation(),
-                    diag::err_odr_non_type_parameter_type_inconsistent)
+                    Context.getApplicableDiagnostic(
+                        diag::err_odr_non_type_parameter_type_inconsistent))
           << D2->getType() << D1->getType();
       Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
           << D1->getType();
@@ -1355,7 +1360,9 @@ static bool IsStructurallyEquivalent(Str
                                      TemplateTemplateParmDecl *D2) {
   if (D1->isParameterPack() != D2->isParameterPack()) {
     if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+      Context.Diag2(D2->getLocation(),
+                    Context.getApplicableDiagnostic(
+                        diag::err_odr_parameter_pack_non_pack))
           << D2->isParameterPack();
       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
           << D1->isParameterPack();
@@ -1511,6 +1518,51 @@ StructuralEquivalenceContext::findUntagg
   return Index;
 }
 
+unsigned StructuralEquivalenceContext::getApplicableDiagnostic(
+    unsigned ErrorDiagnostic) {
+  if (ErrorOnTagTypeMismatch)
+    return ErrorDiagnostic;
+
+  switch (ErrorDiagnostic) {
+  case diag::err_odr_variable_type_inconsistent:
+    return diag::warn_odr_variable_type_inconsistent;
+  case diag::err_odr_variable_multiple_def:
+    return diag::warn_odr_variable_multiple_def;
+  case diag::err_odr_function_type_inconsistent:
+    return diag::warn_odr_function_type_inconsistent;
+  case diag::err_odr_tag_type_inconsistent:
+    return diag::warn_odr_tag_type_inconsistent;
+  case diag::err_odr_field_type_inconsistent:
+    return diag::warn_odr_field_type_inconsistent;
+  case diag::err_odr_ivar_type_inconsistent:
+    return diag::warn_odr_ivar_type_inconsistent;
+  case diag::err_odr_objc_superclass_inconsistent:
+    return diag::warn_odr_objc_superclass_inconsistent;
+  case diag::err_odr_objc_method_result_type_inconsistent:
+    return diag::warn_odr_objc_method_result_type_inconsistent;
+  case diag::err_odr_objc_method_num_params_inconsistent:
+    return diag::warn_odr_objc_method_num_params_inconsistent;
+  case diag::err_odr_objc_method_param_type_inconsistent:
+    return diag::warn_odr_objc_method_param_type_inconsistent;
+  case diag::err_odr_objc_method_variadic_inconsistent:
+    return diag::warn_odr_objc_method_variadic_inconsistent;
+  case diag::err_odr_objc_property_type_inconsistent:
+    return diag::warn_odr_objc_property_type_inconsistent;
+  case diag::err_odr_objc_property_impl_kind_inconsistent:
+    return diag::warn_odr_objc_property_impl_kind_inconsistent;
+  case diag::err_odr_objc_synthesize_ivar_inconsistent:
+    return diag::warn_odr_objc_synthesize_ivar_inconsistent;
+  case diag::err_odr_different_num_template_parameters:
+    return diag::warn_odr_different_num_template_parameters;
+  case diag::err_odr_different_template_parameter_kind:
+    return diag::warn_odr_different_template_parameter_kind;
+  case diag::err_odr_parameter_pack_non_pack:
+    return diag::warn_odr_parameter_pack_non_pack;
+  case diag::err_odr_non_type_parameter_type_inconsistent:
+    return diag::warn_odr_non_type_parameter_type_inconsistent;
+  }
+}
+
 bool StructuralEquivalenceContext::IsEquivalent(Decl *D1, Decl *D2) {
 
   // Ensure that the implementation functions (all static functions in this TU)




More information about the cfe-commits mailing list