// No PCH: // RUN: %clang_cc1 -pedantic -std=c++1y -include %s -include %s -verify %s -DNONPCH // RUN: %clang_cc1 -pedantic -std=c++1y -include %s -include %s -verify %s -DNONPCH -DERROR // // With PCH: // RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t.a -DHEADER1 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch %s -o %t.b -DHEADER2 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s -DHEADERUSE // RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch -fpch-instantiate-templates %s -o %t.a -DHEADER1 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch -fpch-instantiate-templates %s -o %t.b -DHEADER2 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s -DHEADERUSE #ifndef ERROR // expected-no-diagnostics #endif #ifdef NONPCH #if !defined(HEADER1) #define HEADER1 #undef HEADER2 #undef HEADERUSE #elif !defined(HEADER2) #define HEADER2 #undef HEADERUSE #else #define HEADERUSE #undef HEADER1 #undef HEADER2 #endif #endif // *** HEADER1: First header file #if defined(HEADER1) && !defined(HEADER2) && !defined(HEADERUSE) template T var0a = T(); template extern T var0b; namespace join { template T va = T(100); template extern T vb; namespace diff_types { #ifdef ERROR template extern float err0; template extern T err1; #endif template extern T def; } } namespace spec { template constexpr T va = T(10); template<> constexpr float va = 1.5; template constexpr int va; template T vb = T(); template<> constexpr float vb = 1.5; template T vc = T(); template constexpr T vd = T(10); template T* vd = new T(); } namespace spec_join1 { template T va = T(10); template<> extern float va; extern template int va; template T vb = T(10); template<> extern float vb; template T vc = T(10); template T vd = T(10); template extern T* vd; } #endif // *** HEADER2: Second header file -- including HEADER1 #if defined(HEADER2) && !defined(HEADERUSE) namespace join { template extern T va; template<> constexpr float va = 2.5; template T vb = T(100); namespace diff_types { #ifdef ERROR template extern T err0; // expected-error {{redeclaration of 'err0' with a different type: 'T' vs 'float'}} // expected-note@46 {{previous declaration is here}} template extern float err1; // expected-error {{redeclaration of 'err1' with a different type: 'float' vs 'T'}} // expected-note@47 {{previous declaration is here}} #endif template extern T def; } } namespace spec_join1 { template extern T va; template<> float va = 1.5; extern template int va; template<> float vb = 1.5; template int vb; template<> float vc = 1.5; template int vc; template extern T vd; template T* vd = new T(); } #endif // *** HEADERUSE: File using both header files -- including HEADER2 #ifdef HEADERUSE template int var0a; float fvara = var0a; template extern T var0a; template T var0b = T(); template int var0b; float fvarb = var0b; namespace join { template const int va; template<> const int va = 50; static_assert(va == 2.5, ""); static_assert(va == 50, ""); template<> constexpr float vb = 2.5; template const int vb; static_assert(vb == 2.5, ""); static_assert(vb == 100, ""); namespace diff_types { template T def = T(); } } namespace spec { static_assert(va == 1.5, ""); static_assert(va == 10, ""); template T* vb = new T(); int* intpb = vb; static_assert(vb == 1.5, ""); template T* vc = new T(); template<> constexpr float vc = 1.5; int* intpc = vc; static_assert(vc == 1.5, ""); char* intpd = vd; } namespace spec_join1 { template int va; int a = va; template extern T vb; int b = vb; int* intpb = vd; } #endif