gamesh411 created this revision.
Herald added subscribers: cfe-commits, Szelethus, martong, dkrupp.
Herald added a reviewer: a.sidorin.
Herald added a reviewer: shafik.

- Make ODR diagnostics warning by default

After this change all odr-related diagnostics are considered warnings belonging
to Diagnostic Group "OneDefinitionRule". They can be propagated to error level
with '-Werror=odr'.

- Remove unused ErrorOnTagTypeMismatch member


Repository:
  rC Clang

https://reviews.llvm.org/D55646

Files:
  include/clang/AST/ASTStructuralEquivalence.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticGroups.td
  lib/AST/ASTImporter.cpp
  lib/AST/ASTStructuralEquivalence.cpp
  lib/Sema/SemaType.cpp
  test/ASTMerge/category/test.m
  test/ASTMerge/class-template-partial-spec/test.cpp
  test/ASTMerge/class-template/test.cpp
  test/ASTMerge/enum/test.c
  test/ASTMerge/function/test.c
  test/ASTMerge/interface/test.m
  test/ASTMerge/namespace/test.cpp
  test/ASTMerge/property/test.m
  test/ASTMerge/struct/test.c
  test/ASTMerge/typedef/test.c
  test/ASTMerge/var/test.c
  test/Modules/elaborated-type-specifier-from-hidden-module.m
  test/Modules/redefinition-c-tagtypes.m

Index: test/Modules/redefinition-c-tagtypes.m
===================================================================
--- test/Modules/redefinition-c-tagtypes.m
+++ test/Modules/redefinition-c-tagtypes.m
@@ -15,7 +15,7 @@
   int b;
 #else
   int c; // expected-note {{field has name 'c' here}}
-  // expected-error@redefinition-c-tagtypes.m:12 {{type 'struct NS' has incompatible definitions}}
+  // expected-warning@redefinition-c-tagtypes.m:12 {{type 'struct NS' has incompatible definitions}}
   // expected-note@Inputs/F.framework/PrivateHeaders/NS.h:3 {{field has name 'b' here}}
 #endif
 };
@@ -26,7 +26,7 @@
   SND = 43,
 #else
   SND = 44, // expected-note {{enumerator 'SND' with value 44 here}}
-  // expected-error@redefinition-c-tagtypes.m:23 {{type 'enum NSE' has incompatible definitions}}
+  // expected-warning@redefinition-c-tagtypes.m:23 {{type 'enum NSE' has incompatible definitions}}
   // expected-note@Inputs/F.framework/PrivateHeaders/NS.h:8 {{enumerator 'SND' with value 43 here}}
 #endif
   TRD = 55
@@ -42,7 +42,7 @@
   MinXOther = MinX,
 #else
   MinXOther = TRD, // expected-note {{enumerator 'MinXOther' with value 55 here}}
-  // expected-error@redefinition-c-tagtypes.m:39 {{type 'enum NSMyEnum' has incompatible definitions}}
+  // expected-warning@redefinition-c-tagtypes.m:39 {{type 'enum NSMyEnum' has incompatible definitions}}
   // expected-note@Inputs/F.framework/PrivateHeaders/NS.h:18 {{enumerator 'MinXOther' with value 11 here}}
 #endif
 };
Index: test/Modules/elaborated-type-specifier-from-hidden-module.m
===================================================================
--- test/Modules/elaborated-type-specifier-from-hidden-module.m
+++ test/Modules/elaborated-type-specifier-from-hidden-module.m
@@ -7,7 +7,7 @@
 struct S2 { int x; };
 struct S3 *z;
 // Incompatible definition.
-struct S3 { float y; }; // expected-error {{has incompatible definitions}} // expected-note {{field has name}}
+struct S3 { float y; }; // expected-warning {{has incompatible definitions}} // expected-note {{field has name}}
 // expected-note@Inputs/elaborated-type-structs.h:3 {{field has name}}
 
 @import ElaboratedTypeStructs.Structs;
Index: test/ASTMerge/var/test.c
===================================================================
--- test/ASTMerge/var/test.c
+++ test/ASTMerge/var/test.c
@@ -1,12 +1,12 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/var1.c
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/var2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -fdiagnostics-show-note-include-stack %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -fdiagnostics-show-note-include-stack %s 2>&1 | FileCheck %s
 
-// CHECK: var2.c:2:9: error: external variable 'x1' declared with incompatible types in different translation units ('double *' vs. 'float **')
+// CHECK: var2.c:2:9: warning: external variable 'x1' declared with incompatible types in different translation units ('double *' vs. 'float **')
 // CHECK: var1.c:2:9: note: declared here with type 'float **'
-// CHECK: var2.c:3:5: error: external variable 'x2' declared with incompatible types in different translation units ('int' vs. 'double')
+// CHECK: var2.c:3:5: warning: external variable 'x2' declared with incompatible types in different translation units ('int' vs. 'double')
 // CHECK: In file included from{{.*}}var1.c:3:
 // CHECK: var1.h:1:8: note: declared here with type 'double'
-// CHECK: error: external variable 'xarray3' declared with incompatible types in different translation units ('int [17]' vs. 'int [18]')
+// CHECK: warning: external variable 'xarray3' declared with incompatible types in different translation units ('int [17]' vs. 'int [18]')
 // CHECK: var1.c:7:5: note: declared here with type 'int [18]'
-// CHECK: 3 errors
+// CHECK: 3 warnings
Index: test/ASTMerge/typedef/test.c
===================================================================
--- test/ASTMerge/typedef/test.c
+++ test/ASTMerge/typedef/test.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/typedef1.c
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/typedef2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
-// CHECK: typedef2.c:4:10: error: external variable 'x2' declared with incompatible types in different translation units ('Typedef2' (aka 'double') vs. 'Typedef2' (aka 'int'))
+// CHECK: typedef2.c:4:10: warning: external variable 'x2' declared with incompatible types in different translation units ('Typedef2' (aka 'double') vs. 'Typedef2' (aka 'int'))
 // CHECK: typedef1.c:4:10: note: declared here with type 'Typedef2' (aka 'int')
-// CHECK: 1 error
+// CHECK: 1 warning
Index: test/ASTMerge/struct/test.c
===================================================================
--- test/ASTMerge/struct/test.c
+++ test/ASTMerge/struct/test.c
@@ -1,35 +1,35 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/struct1.c
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/struct2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
 // CHECK: struct1.c:13:8: warning: type 'struct S1' has incompatible definitions in different translation units
 // CHECK: struct1.c:15:7: note: field 'field2' has type 'int' here
 // CHECK: struct2.c:12:9: note: field 'field2' has type 'float' here
-// CHECK: struct2.c:15:11: error: external variable 'x1' declared with incompatible types in different translation units ('struct S1' vs. 'struct S1')
+// CHECK: struct2.c:15:11: warning: external variable 'x1' declared with incompatible types in different translation units ('struct S1' vs. 'struct S1')
 // CHECK: struct1.c:18:11: note: declared here with type 'struct S1'
 // CHECK: struct1.c:21:8: warning: type 'struct S2' has incompatible definitions in different translation units
 // CHECK: struct2.c:18:7: note: 'S2' is a union here
-// CHECK: struct2.c:18:30: error: external variable 'x2' declared with incompatible types in different translation units ('union S2' vs. 'struct S2')
+// CHECK: struct2.c:18:30: warning: external variable 'x2' declared with incompatible types in different translation units ('union S2' vs. 'struct S2')
 // CHECK: struct1.c:21:31: note: declared here with type 'struct S2'
 // CHECK: struct1.c:24:8: warning: type 'struct S3' has incompatible definitions in different translation units
 // CHECK: struct1.c:24:36: note: field 'd' has type 'double' here
 // CHECK: struct2.c:21:8: note: no corresponding field here
-// CHECK: struct2.c:21:31: error: external variable 'x3' declared with incompatible types in different translation units ('struct S3' vs. 'struct S3')
+// CHECK: struct2.c:21:31: warning: external variable 'x3' declared with incompatible types in different translation units ('struct S3' vs. 'struct S3')
 // CHECK: struct1.c:24:41: note: declared here with type 'struct S3'
 // CHECK: struct1.c:27:8: warning: type 'struct S4' has incompatible definitions in different translation units
 // CHECK: struct2.c:24:26: note: field 'f' has type 'float' here
 // CHECK: struct1.c:27:8: note: no corresponding field here
-// CHECK: struct2.c:24:31: error: external variable 'x4' declared with incompatible types in different translation units ('struct S4' vs. 'struct S4')
+// CHECK: struct2.c:24:31: warning: external variable 'x4' declared with incompatible types in different translation units ('struct S4' vs. 'struct S4')
 // CHECK: struct1.c:27:22: note: declared here with type 'struct S4'
 // CHECK: struct1.c:33:8: warning: type 'struct S6' has incompatible definitions in different translation units
 // CHECK: struct1.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 8 here
 // CHECK: struct2.c:30:33: note: field 'j' is not a bit-field
-// CHECK: struct2.c:30:38: error: external variable 'x6' declared with incompatible types in different translation units ('struct S6' vs. 'struct S6')
+// CHECK: struct2.c:30:38: warning: external variable 'x6' declared with incompatible types in different translation units ('struct S6' vs. 'struct S6')
 // CHECK: struct1.c:33:42: note: declared here with type 'struct S6'
 // CHECK: struct1.c:36:8: warning: type 'struct S7' has incompatible definitions in different translation units
 // CHECK: struct1.c:36:33: note: bit-field 'j' with type 'unsigned int' and length 8 here
 // CHECK: struct2.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 16 here
-// CHECK: struct2.c:33:43: error: external variable 'x7' declared with incompatible types in different translation units ('struct S7' vs. 'struct S7')
+// CHECK: struct2.c:33:43: warning: external variable 'x7' declared with incompatible types in different translation units ('struct S7' vs. 'struct S7')
 // CHECK: struct1.c:36:42: note: declared here with type 'struct S7'
 // CHECK: struct1.c:56:10: warning: type 'struct DeeperError' has incompatible definitions in different translation units
 // CHECK: struct1.c:56:35: note: field 'f' has type 'int' here
@@ -37,12 +37,12 @@
 // CHECK: struct1.c:54:8: warning: type 'struct DeepError' has incompatible definitions in different translation units
 // CHECK: struct1.c:56:41: note: field 'Deeper' has type 'struct DeeperError *' here
 // CHECK: struct2.c:53:43: note: field 'Deeper' has type 'struct DeeperError *' here
-// CHECK: struct2.c:54:3: error: external variable 'xDeep' declared with incompatible types in different translation units ('struct DeepError' vs. 'struct DeepError')
+// CHECK: struct2.c:54:3: warning: external variable 'xDeep' declared with incompatible types in different translation units ('struct DeepError' vs. 'struct DeepError')
 // CHECK: struct1.c:57:3: note: declared here with type 'struct DeepError'
 // CHECK: struct1.c:74:9: warning: type 'S13' has incompatible definitions in different translation units
 // CHECK: struct1.c:75:9: note: field 'i' has type 'Float' (aka 'float') here
 // CHECK: struct2.c:72:7: note: field 'i' has type 'int' here
-// CHECK: struct2.c:76:5: error: external variable 'x13' declared with incompatible types in different translation units ('S13' vs. 'S13')
+// CHECK: struct2.c:76:5: warning: external variable 'x13' declared with incompatible types in different translation units ('S13' vs. 'S13')
 // CHECK: struct1.c:79:5: note: declared here with type 'S13'
 // CHECK: struct1.c:130:7: warning: type 'struct DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS:.+]]struct1.c:130:7)' has incompatible definitions in different translation units
 // CHECK: struct1.c:131:14: note: field 'i' has type 'long' here
@@ -50,6 +50,6 @@
 // CHECK: struct1.c:129:5: warning: type 'union DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS]]struct1.c:129:5)' has incompatible definitions in different translation units
 // CHECK: struct1.c:132:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]struct1.c:130:7)' here
 // CHECK: struct2.c:129:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]struct2.c:127:7)' here
-// CHECK: struct2.c:138:3: error: external variable 'x16' declared with incompatible types in different translation units ('struct DeepUnnamedError' vs. 'struct DeepUnnamedError')
+// CHECK: struct2.c:138:3: warning: external variable 'x16' declared with incompatible types in different translation units ('struct DeepUnnamedError' vs. 'struct DeepUnnamedError')
 // CHECK: struct1.c:141:3: note: declared here with type 'struct DeepUnnamedError'
-// CHECK: 11 warnings and 9 errors generated
+// CHECK: 20 warnings generated
Index: test/ASTMerge/property/test.m
===================================================================
--- test/ASTMerge/property/test.m
+++ test/ASTMerge/property/test.m
@@ -1,13 +1,13 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/property1.m
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/property2.m
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
-// CHECK: property2.m:12:26: error: property 'Prop1' declared with incompatible types in different translation units ('int' vs. 'float')
+// CHECK: property2.m:12:26: warning: property 'Prop1' declared with incompatible types in different translation units ('int' vs. 'float')
 // CHECK: property1.m:10:28: note: declared here with type 'float'
-// CHECK: property2.m:12:26: error: instance method 'Prop1' has incompatible result types in different translation units ('int' vs. 'float')
+// CHECK: property2.m:12:26: warning: instance method 'Prop1' has incompatible result types in different translation units ('int' vs. 'float')
 // CHECK: property1.m:10:28: note: instance method 'Prop1' also declared here
-// CHECK: property1.m:28:21: error: property 'Prop2' is synthesized to different ivars in different translation units ('ivar3' vs. 'ivar2')
+// CHECK: property1.m:28:21: warning: property 'Prop2' is synthesized to different ivars in different translation units ('ivar3' vs. 'ivar2')
 // CHECK: property2.m:29:21: note: property is synthesized to ivar 'ivar2' here
-// CHECK: property1.m:29:10: error: property 'Prop3' is implemented with @dynamic in one translation but @synthesize in another translation unit
+// CHECK: property1.m:29:10: warning: property 'Prop3' is implemented with @dynamic in one translation but @synthesize in another translation unit
 // CHECK: property2.m:31:13: note: property 'Prop3' is implemented with @synthesize here
-// CHECK: 4 errors generated.
+// CHECK: 4 warnings generated.
Index: test/ASTMerge/namespace/test.cpp
===================================================================
--- test/ASTMerge/namespace/test.cpp
+++ test/ASTMerge/namespace/test.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/namespace1.cpp
 // RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/namespace2.cpp
-// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
 static_assert(TestAliasName::z == 4);
 static_assert(ContainsInline::z == 10);
@@ -13,5 +13,5 @@
 }
 
 
-// CHECK: namespace2.cpp:16:17: error: external variable 'z' declared with incompatible types in different translation units ('double' vs. 'float')
+// CHECK: namespace2.cpp:16:17: warning: external variable 'z' declared with incompatible types in different translation units ('double' vs. 'float')
 // CHECK: namespace1.cpp:16:16: note: declared here with type 'float'
Index: test/ASTMerge/interface/test.m
===================================================================
--- test/ASTMerge/interface/test.m
+++ test/ASTMerge/interface/test.m
@@ -1,22 +1,22 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/interface1.m
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/interface2.m
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
-// CHECK: interface2.m:16:9: error: instance variable 'ivar2' declared with incompatible types in different translation units ('float' vs. 'int')
+// CHECK: interface2.m:16:9: warning: instance variable 'ivar2' declared with incompatible types in different translation units ('float' vs. 'int')
 // CHECK: interface1.m:16:7: note: declared here with type 'int'
-// CHECK: interface1.m:21:12: error: class 'I4' has incompatible superclasses
+// CHECK: interface1.m:21:12: warning: class 'I4' has incompatible superclasses
 // CHECK: interface1.m:21:17: note: inherits from superclass 'I2' here
 // CHECK: interface2.m:21:17: note: inherits from superclass 'I1' here
-// CHECK: interface2.m:33:1: error: class method 'foo' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: interface2.m:33:1: warning: class method 'foo' has incompatible result types in different translation units ('float' vs. 'int')
 // CHECK: interface1.m:34:1: note: class method 'foo' also declared here
-// CHECK: interface2.m:39:19: error: class method 'bar:' has a parameter with a different types in different translation units ('float' vs. 'int')
+// CHECK: interface2.m:39:19: warning: class method 'bar:' has a parameter with a different types in different translation units ('float' vs. 'int')
 // CHECK: interface1.m:40:17: note: declared here with type 'int'
-// CHECK: interface2.m:45:1: error: class method 'bar:' is variadic in one translation unit and not variadic in another
+// CHECK: interface2.m:45:1: warning: class method 'bar:' is variadic in one translation unit and not variadic in another
 // CHECK: interface1.m:46:1: note: class method 'bar:' also declared here
-// CHECK: interface2.m:57:20: error: instance method 'bar:' has a parameter with a different types in different translation units ('double' vs. 'float')
+// CHECK: interface2.m:57:20: warning: instance method 'bar:' has a parameter with a different types in different translation units ('double' vs. 'float')
 // CHECK: interface1.m:58:19: note: declared here with type 'float'
-// CHECK: interface1.m:100:17: error: class 'I15' has incompatible superclasses
+// CHECK: interface1.m:100:17: warning: class 'I15' has incompatible superclasses
 // CHECK: interface1.m:100:17: note: inherits from superclass 'I12' here
 // CHECK: interface2.m:99:17: note: inherits from superclass 'I11' here
-// CHECK: 8 errors generated
+// CHECK: 8 warnings generated
 
Index: test/ASTMerge/function/test.c
===================================================================
--- test/ASTMerge/function/test.c
+++ test/ASTMerge/function/test.c
@@ -1,15 +1,15 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/function1.c
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/function2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 // RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
 
-// CHECK: function2.c:3:6: error: external function 'f1' declared with incompatible types in different translation units ('void (Int, double)' (aka 'void (int, double)') vs. 'void (int, float)')
+// CHECK: function2.c:3:6: warning: external function 'f1' declared with incompatible types in different translation units ('void (Int, double)' (aka 'void (int, double)') vs. 'void (int, float)')
 // CHECK: function1.c:2:6: note: declared here with type 'void (int, float)'
-// CHECK: function2.c:5:6: error: external function 'f3' declared with incompatible types in different translation units ('void (int)' vs. 'void (void)')
+// CHECK: function2.c:5:6: warning: external function 'f3' declared with incompatible types in different translation units ('void (int)' vs. 'void (void)')
 // CHECK: function1.c:4:6: note: declared here with type 'void (void)'
-// CHECK: 2 errors generated
+// CHECK: 2 warnings generated
 
-// expected-error@Inputs/function2.c:3 {{external function 'f1' declared with incompatible types}}
+// expected-warning@Inputs/function2.c:3 {{external function 'f1' declared with incompatible types}}
 // expected-note@Inputs/function1.c:2 {{declared here}}
-// expected-error@Inputs/function2.c:5 {{external function 'f3' declared with incompatible types}}
+// expected-warning@Inputs/function2.c:5 {{external function 'f3' declared with incompatible types}}
 // expected-note@Inputs/function1.c:4 {{declared here}}
Index: test/ASTMerge/enum/test.c
===================================================================
--- test/ASTMerge/enum/test.c
+++ test/ASTMerge/enum/test.c
@@ -1,25 +1,25 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/enum1.c
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/enum2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
 // CHECK: enum1.c:9:6: warning: type 'enum E2' has incompatible definitions in different translation units
 // CHECK: enum1.c:11:3: note: enumerator 'E2Enumerator2' with value 3 here
 // CHECK: enum2.c:11:3: note: enumerator 'E2Enumerator2' with value 4 here
-// CHECK: enum2.c:13:3: error: external variable 'x2' declared with incompatible types in different translation units ('enum E2' vs. 'enum E2')
+// CHECK: enum2.c:13:3: warning: external variable 'x2' declared with incompatible types in different translation units ('enum E2' vs. 'enum E2')
 // CHECK: enum1.c:13:3: note: declared here with type 'enum E2'
 // CHECK: enum1.c:16:6: warning: type 'enum E3' has incompatible definitions in different translation units
 // CHECK: enum1.c:18:3: note: enumerator 'E3Enumerator2' with value 3 here
 // CHECK: enum2.c:18:3: note: enumerator 'E3Enumerator' with value 3 here
-// CHECK: enum2.c:20:3: error: external variable 'x3' declared with incompatible types in different translation units ('enum E3' vs. 'enum E3')
+// CHECK: enum2.c:20:3: warning: external variable 'x3' declared with incompatible types in different translation units ('enum E3' vs. 'enum E3')
 // CHECK: enum1.c:20:3: note: declared here with type 'enum E3'
 // CHECK: enum1.c:23:6: warning: type 'enum E4' has incompatible definitions in different translation units
 // CHECK: enum1.c:26:3: note: enumerator 'E4Enumerator3' with value 2 here
 // CHECK: enum2.c:23:6: note: no corresponding enumerator here
-// CHECK: enum2.c:26:3: error: external variable 'x4' declared with incompatible types in different translation units ('enum E4' vs. 'enum E4')
+// CHECK: enum2.c:26:3: warning: external variable 'x4' declared with incompatible types in different translation units ('enum E4' vs. 'enum E4')
 // CHECK: enum1.c:27:3: note: declared here with type 'enum E4'
 // CHECK: enum1.c:30:6: warning: type 'enum E5' has incompatible definitions in different translation units
 // CHECK: enum2.c:33:3: note: enumerator 'E5Enumerator4' with value 3 here
 // CHECK: enum1.c:30:6: note: no corresponding enumerator here
-// CHECK: enum2.c:34:3: error: external variable 'x5' declared with incompatible types in different translation units ('enum E5' vs. 'enum E5')
+// CHECK: enum2.c:34:3: warning: external variable 'x5' declared with incompatible types in different translation units ('enum E5' vs. 'enum E5')
 // CHECK: enum1.c:34:3: note: declared here with type 'enum E5'
-// CHECK: 4 warnings and 4 errors generated
+// CHECK: 8 warnings generated
Index: test/ASTMerge/class-template/test.cpp
===================================================================
--- test/ASTMerge/class-template/test.cpp
+++ test/ASTMerge/class-template/test.cpp
@@ -1,28 +1,28 @@
 // RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class-template1.cpp
 // RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.2.ast %S/Inputs/class-template2.cpp
-// RUN: not %clang_cc1 -std=c++1z  -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z  -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
 static_assert(sizeof(X0<char>().getValue(1)) == sizeof(char));
 static_assert(sizeof(X0<int>().getValue(1)) == sizeof(int));
 
-// CHECK: class-template1.cpp:9:14: error: non-type template parameter declared with incompatible types in different translation units ('int' vs. 'long')
+// CHECK: class-template1.cpp:9:14: warning: non-type template parameter declared with incompatible types in different translation units ('int' vs. 'long')
 // CHECK: class-template2.cpp:9:15: note: declared here with type 'long'
 
-// CHECK: class-template1.cpp:12:14: error: template parameter has different kinds in different translation units
+// CHECK: class-template1.cpp:12:14: warning: template parameter has different kinds in different translation units
 // CHECK: class-template2.cpp:12:10: note: template parameter declared here
 
-// CHECK: class-template1.cpp:18:23: error: non-type template parameter declared with incompatible types in different translation units ('long' vs. 'int')
+// CHECK: class-template1.cpp:18:23: warning: non-type template parameter declared with incompatible types in different translation units ('long' vs. 'int')
 // CHECK: class-template2.cpp:18:23: note: declared here with type 'int'
 
-// CHECK: class-template1.cpp:21:10: error: template parameter has different kinds in different translation units
+// CHECK: class-template1.cpp:21:10: warning: template parameter has different kinds in different translation units
 // CHECK: class-template2.cpp:21:10: note: template parameter declared here
 
-// CHECK: class-template2.cpp:27:20: error: external variable 'x0r' declared with incompatible types in different translation units ('X0<double> *' vs. 'X0<float> *')
+// CHECK: class-template2.cpp:27:20: warning: external variable 'x0r' declared with incompatible types in different translation units ('X0<double> *' vs. 'X0<float> *')
 // CHECK: class-template1.cpp:26:19: note: declared here with type 'X0<float> *'
 
 // CHECK: class-template1.cpp:35:8: warning: type 'X0<wchar_t>' has incompatible definitions in different translation units
 // CHECK: class-template1.cpp:36:7: note: field 'member' has type 'int' here
 // CHECK: class-template2.cpp:36:9: note: field 'member' has type 'float' here
 
-// CHECK: 1 warning and 5 errors generated.
+// CHECK: 6 warnings generated.
 // CHECK-NOT: static_assert
Index: test/ASTMerge/class-template-partial-spec/test.cpp
===================================================================
--- test/ASTMerge/class-template-partial-spec/test.cpp
+++ test/ASTMerge/class-template-partial-spec/test.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/class-template-partial-spec1.cpp
 // RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/class-template-partial-spec2.cpp
-// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
 static_assert(sizeof(**SingleSource.member) == sizeof(**SingleDest.member));
 static_assert(sizeof(SecondDoubleSource.member) == sizeof(SecondDoubleDest.member));
@@ -9,17 +9,17 @@
 static_assert(sizeof(Dst::Z0Dst.member) == sizeof(double));
 static_assert(sizeof(One::Child1<double, One::Two::Three::Parent<double>>::member) == sizeof(double));
 
-// CHECK: class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate<int, double>' vs. 'TwoOptionTemplate<int, float>')
+// CHECK: class-template-partial-spec2.cpp:21:32: warning: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate<int, double>' vs. 'TwoOptionTemplate<int, float>')
 // CHECK: class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate<int, float>'
 
-// CHECK: class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate<int, int>' vs. 'TwoOptionTemplate<float, float>')
+// CHECK: class-template-partial-spec2.cpp:24:29: warning: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate<int, int>' vs. 'TwoOptionTemplate<float, float>')
 // CHECK: class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate<float, float>'
 
 // CHECK: class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units
 // CHECK: class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here
 // CHECK: class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here
 
-// CHECK: class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>')
+// CHECK: class-template-partial-spec2.cpp:52:25: warning: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>')
 // CHECK: class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>'
 
 // CHECK-NOT: static_assert
Index: test/ASTMerge/category/test.m
===================================================================
--- test/ASTMerge/category/test.m
+++ test/ASTMerge/category/test.m
@@ -1,11 +1,11 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/category1.m
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/category2.m
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
 
-// CHECK: category2.m:18:1: error: instance method 'method2' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: category2.m:18:1: warning: instance method 'method2' has incompatible result types in different translation units ('float' vs. 'int')
 // CHECK: category1.m:16:1: note: instance method 'method2' also declared here
-// CHECK: category2.m:26:1: error: instance method 'method3' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: category2.m:26:1: warning: instance method 'method3' has incompatible result types in different translation units ('float' vs. 'int')
 // CHECK: category1.m:24:1: note: instance method 'method3' also declared here
-// CHECK: category2.m:48:1: error: instance method 'blah' has incompatible result types in different translation units ('int' vs. 'float')
+// CHECK: category2.m:48:1: warning: instance method 'blah' has incompatible result types in different translation units ('int' vs. 'float')
 // CHECK: category1.m:46:1: note: instance method 'blah' also declared here
-// CHECK: 3 errors generated.
+// CHECK: 3 warnings generated.
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -7605,9 +7605,8 @@
   // and isolate from other C++ specific checks.
   StructuralEquivalenceContext Ctx(
       D->getASTContext(), Suggested->getASTContext(), NonEquivalentDecls,
-      StructuralEquivalenceKind::Default,
-      false /*StrictTypeSpelling*/, true /*Complain*/,
-      true /*ErrorOnTagTypeMismatch*/);
+      StructuralEquivalenceKind::Default, false /*StrictTypeSpelling*/,
+      true /*Complain*/);
   return Ctx.IsEquivalent(D, Suggested);
 }
 
Index: lib/AST/ASTStructuralEquivalence.cpp
===================================================================
--- lib/AST/ASTStructuralEquivalence.cpp
+++ lib/AST/ASTStructuralEquivalence.cpp
@@ -834,10 +834,7 @@
   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(), diag::warn_odr_tag_type_inconsistent)
           << Context.ToCtx.getTypeDeclType(Owner2);
       Context.Diag2(Field2->getLocation(), diag::note_odr_field_name)
           << Field2->getDeclName();
@@ -850,10 +847,7 @@
   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(), diag::warn_odr_tag_type_inconsistent)
           << Context.ToCtx.getTypeDeclType(Owner2);
       Context.Diag2(Field2->getLocation(), diag::note_odr_field)
           << Field2->getDeclName() << Field2->getType();
@@ -865,10 +859,7 @@
 
   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(), diag::warn_odr_tag_type_inconsistent)
           << Context.ToCtx.getTypeDeclType(Owner2);
       if (Field1->isBitField()) {
         Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
@@ -895,9 +886,7 @@
     if (Bits1 != Bits2) {
       if (Context.Complain) {
         Context.Diag2(Owner2->getLocation(),
-                      Context.ErrorOnTagTypeMismatch
-                          ? diag::err_odr_tag_type_inconsistent
-                          : diag::warn_odr_tag_type_inconsistent)
+            diag::warn_odr_tag_type_inconsistent)
             << Context.ToCtx.getTypeDeclType(Owner2);
         Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
             << Field2->getDeclName() << Field2->getType() << Bits2;
@@ -966,10 +955,7 @@
                                      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(), diag::warn_odr_tag_type_inconsistent)
           << Context.ToCtx.getTypeDeclType(D2);
       Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
           << D1->getDeclName() << (unsigned)D1->getTagKind();
@@ -1148,10 +1134,7 @@
        Field1 != Field1End; ++Field1, ++Field2) {
     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(), diag::warn_odr_tag_type_inconsistent)
             << Context.ToCtx.getTypeDeclType(D2);
         Context.Diag1(Field1->getLocation(), diag::note_odr_field)
             << Field1->getDeclName() << Field1->getType();
@@ -1166,10 +1149,7 @@
 
   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(), diag::warn_odr_tag_type_inconsistent)
           << Context.ToCtx.getTypeDeclType(D2);
       Context.Diag2(Field2->getLocation(), diag::note_odr_field)
           << Field2->getDeclName() << Field2->getType();
@@ -1199,10 +1179,7 @@
        EC1 != EC1End; ++EC1, ++EC2) {
     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(), diag::warn_odr_tag_type_inconsistent)
             << Context.ToCtx.getTypeDeclType(D2);
         Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
             << EC1->getDeclName() << EC1->getInitVal().toString(10);
@@ -1216,10 +1193,7 @@
     if (!llvm::APSInt::isSameValue(Val1, Val2) ||
         !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.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
             << Context.ToCtx.getTypeDeclType(D2);
         Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
             << EC2->getDeclName() << EC2->getInitVal().toString(10);
@@ -1232,10 +1206,7 @@
 
   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(), diag::warn_odr_tag_type_inconsistent)
           << Context.ToCtx.getTypeDeclType(D2);
       Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
           << EC2->getDeclName() << EC2->getInitVal().toString(10);
@@ -1253,7 +1224,7 @@
   if (Params1->size() != Params2->size()) {
     if (Context.Complain) {
       Context.Diag2(Params2->getTemplateLoc(),
-                    diag::err_odr_different_num_template_parameters)
+                    diag::warn_odr_different_num_template_parameters)
           << Params1->size() << Params2->size();
       Context.Diag1(Params1->getTemplateLoc(),
                     diag::note_odr_template_parameter_list);
@@ -1265,7 +1236,7 @@
     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);
+                      diag::warn_odr_different_template_parameter_kind);
         Context.Diag1(Params1->getParam(I)->getLocation(),
                       diag::note_odr_template_parameter_here);
       }
@@ -1285,7 +1256,7 @@
                                      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(), diag::warn_odr_parameter_pack_non_pack)
           << D2->isParameterPack();
       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
           << D1->isParameterPack();
@@ -1301,7 +1272,7 @@
                                      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(), diag::warn_odr_parameter_pack_non_pack)
           << D2->isParameterPack();
       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
           << D1->isParameterPack();
@@ -1313,7 +1284,7 @@
   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
     if (Context.Complain) {
       Context.Diag2(D2->getLocation(),
-                    diag::err_odr_non_type_parameter_type_inconsistent)
+                    diag::warn_odr_non_type_parameter_type_inconsistent)
           << D2->getType() << D1->getType();
       Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
           << D1->getType();
@@ -1329,7 +1300,7 @@
                                      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(), diag::warn_odr_parameter_pack_non_pack)
           << D2->isParameterPack();
       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
           << D1->isParameterPack();
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -3079,7 +3079,7 @@
             continue;
 
           // Complain about inconsistent function types.
-          Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
+          Importer.ToDiag(Loc, diag::warn_odr_function_type_inconsistent)
             << Name << D->getType() << FoundFunction->getType();
           Importer.ToDiag(FoundFunction->getLocation(),
                           diag::note_odr_value_here)
@@ -3353,7 +3353,7 @@
       }
 
       // FIXME: Why is this case not handled with calling HandleNameConflict?
-      Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
+      Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
         << Name << D->getType() << FoundField->getType();
       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
         << FoundField->getType();
@@ -3425,7 +3425,7 @@
         continue;
 
       // FIXME: Why is this case not handled with calling HandleNameConflict?
-      Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
+      Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
         << Name << D->getType() << FoundField->getType();
       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
         << FoundField->getType();
@@ -3560,7 +3560,7 @@
         return FoundIvar;
       }
 
-      Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
+      Importer.ToDiag(Loc, diag::warn_odr_ivar_type_inconsistent)
         << Name << D->getType() << FoundIvar->getType();
       Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
         << FoundIvar->getType();
@@ -3675,7 +3675,7 @@
             }
           }
 
-          Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
+          Importer.ToDiag(Loc, diag::warn_odr_variable_type_inconsistent)
             << Name << D->getType() << FoundVar->getType();
           Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
             << FoundVar->getType();
@@ -3842,7 +3842,7 @@
       // Check return types.
       if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
                                              FoundMethod->getReturnType())) {
-        Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
+        Importer.ToDiag(Loc, diag::warn_odr_objc_method_result_type_inconsistent)
             << D->isInstanceMethod() << Name << D->getReturnType()
             << FoundMethod->getReturnType();
         Importer.ToDiag(FoundMethod->getLocation(),
@@ -3854,7 +3854,7 @@
 
       // Check the number of parameters.
       if (D->param_size() != FoundMethod->param_size()) {
-        Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
+        Importer.ToDiag(Loc, diag::warn_odr_objc_method_num_params_inconsistent)
           << D->isInstanceMethod() << Name
           << D->param_size() << FoundMethod->param_size();
         Importer.ToDiag(FoundMethod->getLocation(),
@@ -3871,7 +3871,7 @@
         if (!Importer.IsStructurallyEquivalent((*P)->getType(),
                                                (*FoundP)->getType())) {
           Importer.FromDiag((*P)->getLocation(),
-                            diag::err_odr_objc_method_param_type_inconsistent)
+                            diag::warn_odr_objc_method_param_type_inconsistent)
             << D->isInstanceMethod() << Name
             << (*P)->getType() << (*FoundP)->getType();
           Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
@@ -3884,7 +3884,7 @@
       // Check variadic/non-variadic.
       // Check the number of parameters.
       if (D->isVariadic() != FoundMethod->isVariadic()) {
-        Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
+        Importer.ToDiag(Loc, diag::warn_odr_objc_method_variadic_inconsistent)
           << D->isInstanceMethod() << Name;
         Importer.ToDiag(FoundMethod->getLocation(),
                         diag::note_odr_objc_method_here)
@@ -4430,7 +4430,7 @@
     if ((bool)FromSuper != (bool)ToSuper ||
         (FromSuper && !declaresSameEntity(FromSuper, ToSuper))) {
       Importer.ToDiag(To->getLocation(),
-                      diag::err_odr_objc_superclass_inconsistent)
+                      diag::warn_odr_objc_superclass_inconsistent)
         << To->getDeclName();
       if (ToSuper)
         Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass)
@@ -4700,7 +4700,7 @@
          !declaresSameEntity(Super->getCanonicalDecl(),
                              Impl->getSuperClass()))) {
       Importer.ToDiag(Impl->getLocation(),
-                      diag::err_odr_objc_superclass_inconsistent)
+                      diag::warn_odr_objc_superclass_inconsistent)
         << Iface->getDeclName();
       // FIXME: It would be nice to have the location of the superclass
       // below.
@@ -4749,7 +4749,7 @@
       // Check property types.
       if (!Importer.IsStructurallyEquivalent(D->getType(),
                                              FoundProp->getType())) {
-        Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
+        Importer.ToDiag(Loc, diag::warn_odr_objc_property_type_inconsistent)
           << Name << D->getType() << FoundProp->getType();
         Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
           << FoundProp->getType();
@@ -4856,7 +4856,7 @@
     // vs. @dynamic).
     if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) {
       Importer.ToDiag(ToImpl->getLocation(),
-                      diag::err_odr_objc_property_impl_kind_inconsistent)
+                      diag::warn_odr_objc_property_impl_kind_inconsistent)
         << Property->getDeclName()
         << (ToImpl->getPropertyImplementation()
                                               == ObjCPropertyImplDecl::Dynamic);
@@ -4872,7 +4872,7 @@
     if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize &&
         Ivar != ToImpl->getPropertyIvarDecl()) {
       Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(),
-                      diag::err_odr_objc_synthesize_ivar_inconsistent)
+                      diag::warn_odr_objc_synthesize_ivar_inconsistent)
         << Property->getDeclName()
         << ToImpl->getPropertyIvarDecl()->getDeclName()
         << Ivar->getDeclName();
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -397,6 +397,7 @@
 def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
 def ObjCMultipleMethodNames : DiagGroup<"objc-multiple-method-names">;
 def ObjCFlexibleArray : DiagGroup<"objc-flexible-array">;
+def OneDefinitionRule : DiagGroup<"odr">;
 def OpenCLUnsupportedRGBA: DiagGroup<"opencl-unsupported-rgba">;
 def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
 def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
Index: include/clang/Basic/DiagnosticASTKinds.td
===================================================================
--- include/clang/Basic/DiagnosticASTKinds.td
+++ include/clang/Basic/DiagnosticASTKinds.td
@@ -220,23 +220,20 @@
 }
 
 // Importing ASTs
-def err_odr_variable_type_inconsistent : Error<
+def warn_odr_variable_type_inconsistent : Warning<
   "external variable %0 declared with incompatible types in different "
-  "translation units (%1 vs. %2)">;
-def err_odr_variable_multiple_def : Error<
-  "external variable %0 defined in multiple translation units">;
+  "translation units (%1 vs. %2)">, InGroup<OneDefinitionRule>;
+def warn_odr_variable_multiple_def : Warning<
+  "external variable %0 defined in multiple translation units">,
+   InGroup<OneDefinitionRule>;
 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<
+def warn_odr_function_type_inconsistent : Warning<
   "external function %0 declared with incompatible types in different "
-  "translation units (%1 vs. %2)">;
+  "translation units (%1 vs. %2)">, InGroup<OneDefinitionRule>;
 def warn_odr_tag_type_inconsistent
     : Warning<"type %0 has incompatible definitions in different translation "
-              "units">,
-      InGroup<DiagGroup<"odr">>;
-def err_odr_tag_type_inconsistent
-    : Error<"type %0 has incompatible definitions in different translation "
-            "units">;
+              "units">, InGroup<OneDefinitionRule>;
 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,63 +250,67 @@
 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<
+def warn_odr_field_type_inconsistent : Warning<
   "field %0 declared with incompatible types in different "
-  "translation units (%1 vs. %2)">;
+  "translation units (%1 vs. %2)">, InGroup<OneDefinitionRule>;
 
 // Importing Objective-C ASTs
-def err_odr_ivar_type_inconsistent : Error<
+def warn_odr_ivar_type_inconsistent : Warning<
   "instance variable %0 declared with incompatible types in different "
-  "translation units (%1 vs. %2)">;
-def err_odr_objc_superclass_inconsistent : Error<
-  "class %0 has incompatible superclasses">;
+  "translation units (%1 vs. %2)">, InGroup<OneDefinitionRule>;
+def warn_odr_objc_superclass_inconsistent : Warning<
+  "class %0 has incompatible superclasses">, InGroup<OneDefinitionRule>;
 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<
+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)">;
-def err_odr_objc_method_num_params_inconsistent : Error<
+  "different translation units (%2 vs. %3)">, InGroup<OneDefinitionRule>;
+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)">;
-def err_odr_objc_method_param_type_inconsistent : Error<
+  "different translation units (%2 vs. %3)">, InGroup<OneDefinitionRule>;
+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)">;
-def err_odr_objc_method_variadic_inconsistent : Error<
+  "in different translation units (%2 vs. %3)">, InGroup<OneDefinitionRule>;
+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">;
+  "and not variadic in another">, InGroup<OneDefinitionRule>;
 def note_odr_objc_method_here : Note<
   "%select{class|instance}0 method %1 also declared here">;
-def err_odr_objc_property_type_inconsistent : Error<
+def warn_odr_objc_property_type_inconsistent : Warning<
   "property %0 declared with incompatible types in different "
-  "translation units (%1 vs. %2)">;
-def err_odr_objc_property_impl_kind_inconsistent : Error<
+  "translation units (%1 vs. %2)">, InGroup<OneDefinitionRule>;
+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">;
+  "translation but %select{@dynamic|@synthesize}1 in another translation unit">,
+   InGroup<OneDefinitionRule>;
 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<
+def warn_odr_objc_synthesize_ivar_inconsistent : Warning<
   "property %0 is synthesized to different ivars in different translation "
-  "units (%1 vs. %2)">;
+  "units (%1 vs. %2)">, InGroup<OneDefinitionRule>;
 def note_odr_objc_synthesize_ivar_here : Note<
   "property is synthesized to ivar %0 here">;
 
 // Importing C++ ASTs
 def note_odr_friend : Note<"friend declared here">;
 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<OneDefinitionRule>;
 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<OneDefinitionRule>;
 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<OneDefinitionRule>;
 def note_odr_parameter_pack_non_pack : Note<
   "%select{parameter|parameter pack}0 declared here">;
-def err_odr_non_type_parameter_type_inconsistent : Error<
+def warn_odr_non_type_parameter_type_inconsistent : Warning<
   "non-type template parameter declared with incompatible types in different "
-  "translation units (%0 vs. %1)">;
+  "translation units (%0 vs. %1)">, InGroup<OneDefinitionRule>;
 def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
 }
Index: include/clang/AST/ASTStructuralEquivalence.h
===================================================================
--- include/clang/AST/ASTStructuralEquivalence.h
+++ include/clang/AST/ASTStructuralEquivalence.h
@@ -61,9 +61,6 @@
   /// unifying two types.
   bool StrictTypeSpelling;
 
-  /// Whether warn or error on tag type mismatches.
-  bool ErrorOnTagTypeMismatch;
-
   /// Whether to complain about failures.
   bool Complain;
 
@@ -74,11 +71,10 @@
       ASTContext &FromCtx, ASTContext &ToCtx,
       llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
       StructuralEquivalenceKind EqKind,
-      bool StrictTypeSpelling = false, bool Complain = true,
-      bool ErrorOnTagTypeMismatch = false)
+      bool StrictTypeSpelling = false, bool Complain = true)
       : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
         EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
-        ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
+        Complain(Complain) {}
 
   DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
   DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to