2013-08-13 10:02:26 +08:00
// 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
# 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 < typename T > T var0a = T ( ) ;
template < typename T > extern T var0b ;
namespace join {
template < typename T > T va = T ( 100 ) ;
template < typename T > extern T vb ;
namespace diff_types {
# ifdef ERROR
template < typename T > extern float err0 ;
template < typename T > extern T err1 ;
# endif
template < typename T > extern T def ;
}
}
namespace spec {
template < typename T > constexpr T va = T ( 10 ) ;
template < > constexpr float va < float > = 1.5 ;
template constexpr int va < int > ;
template < typename T > T vb = T ( ) ;
template < > constexpr float vb < float > = 1.5 ;
template < typename T > T vc = T ( ) ;
template < typename T > constexpr T vd = T ( 10 ) ;
2013-09-24 12:49:23 +08:00
template < typename T > T * vd < T * > = new T ( ) ;
2013-08-13 10:02:26 +08:00
}
namespace spec_join1 {
template < typename T > T va = T ( 10 ) ;
template < > extern float va < float > ;
extern template int va < int > ;
template < typename T > T vb = T ( 10 ) ;
template < > extern float vb < float > ;
template < typename T > T vc = T ( 10 ) ;
template < typename T > T vd = T ( 10 ) ;
2013-09-24 12:49:23 +08:00
template < typename T > extern T * vd < T * > ;
2013-08-13 10:02:26 +08:00
}
# endif
// *** HEADER2: Second header file -- including HEADER1
# if defined(HEADER2) && !defined(HEADERUSE)
namespace join {
template < typename T > extern T va ;
template < > constexpr float va < float > = 2.5 ;
template < typename T > T vb = T ( 100 ) ;
namespace diff_types {
# ifdef ERROR
2015-07-15 04:08:49 +08:00
template < typename T > extern T err0 ; // expected-error {{redeclaration of 'err0' with a different type: 'T' vs 'float'}} // expected-note@42 {{previous declaration is here}}
template < typename T > extern float err1 ; // expected-error {{redeclaration of 'err1' with a different type: 'float' vs 'T'}} // expected-note@43 {{previous declaration is here}}
2013-08-13 10:02:26 +08:00
# endif
template < typename T > extern T def ;
}
}
namespace spec_join1 {
template < typename T > extern T va ;
template < > float va < float > = 1.5 ;
extern template int va < int > ;
template < > float vb < float > = 1.5 ;
template int vb < int > ;
template < > float vc < float > = 1.5 ;
template int vc < int > ;
template < typename T > extern T vd ;
2013-09-24 12:49:23 +08:00
template < typename T > T * vd < T * > = new T ( ) ;
2013-08-13 10:02:26 +08:00
}
# endif
// *** HEADERUSE: File using both header files -- including HEADER2
# ifdef HEADERUSE
template int var0a < int > ;
float fvara = var0a < float > ;
template < typename T > extern T var0a ;
template < typename T > T var0b = T ( ) ;
template int var0b < int > ;
float fvarb = var0b < float > ;
namespace join {
template const int va < const int > ;
template < > const int va < int > = 50 ;
static_assert ( va < float > = = 2.5 , " " ) ;
static_assert ( va < int > = = 50 , " " ) ;
template < > constexpr float vb < float > = 2.5 ;
template const int vb < const int > ;
static_assert ( vb < float > = = 2.5 , " " ) ;
static_assert ( vb < const int > = = 100 , " " ) ;
namespace diff_types {
template < typename T > T def = T ( ) ;
}
}
namespace spec {
static_assert ( va < float > = = 1.5 , " " ) ;
static_assert ( va < int > = = 10 , " " ) ;
2013-09-24 12:49:23 +08:00
template < typename T > T * vb < T * > = new T ( ) ;
int * intpb = vb < int * > ;
2013-08-13 10:02:26 +08:00
static_assert ( vb < float > = = 1.5 , " " ) ;
2013-09-24 12:49:23 +08:00
template < typename T > T * vc < T * > = new T ( ) ;
2013-08-13 10:02:26 +08:00
template < > constexpr float vc < float > = 1.5 ;
2013-09-24 12:49:23 +08:00
int * intpc = vc < int * > ;
2013-08-13 10:02:26 +08:00
static_assert ( vc < float > = = 1.5 , " " ) ;
2013-09-24 12:49:23 +08:00
char * intpd = vd < char * > ;
2013-08-13 10:02:26 +08:00
}
namespace spec_join1 {
template int va < int > ;
int a = va < int > ;
template < typename T > extern T vb ;
int b = vb < int > ;
2013-09-24 12:49:23 +08:00
int * intpb = vd < int * > ;
2013-08-13 10:02:26 +08:00
}
# endif