forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			172 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
// 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);
 | 
						|
  template<typename T> T* vd<T*> = new T();
 | 
						|
}
 | 
						|
 | 
						|
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);
 | 
						|
  template<typename T> extern T* vd<T*>;
 | 
						|
}
 | 
						|
 | 
						|
#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
 | 
						|
    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}}
 | 
						|
#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;
 | 
						|
  template<typename T> T* vd<T*> = new T();
 | 
						|
}
 | 
						|
 | 
						|
#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, "");
 | 
						|
 | 
						|
  template<typename T> T* vb<T*> = new T();
 | 
						|
  int* intpb = vb<int*>;
 | 
						|
  static_assert(vb<float> == 1.5, "");
 | 
						|
 | 
						|
  template<typename T> T* vc<T*> = new T();
 | 
						|
  template<> constexpr float vc<float> = 1.5;
 | 
						|
  int* intpc = vc<int*>;
 | 
						|
  static_assert(vc<float> == 1.5, "");
 | 
						|
 | 
						|
  char* intpd = vd<char*>;
 | 
						|
}
 | 
						|
 | 
						|
namespace spec_join1 {
 | 
						|
  template int va<int>;
 | 
						|
  int a = va<int>;
 | 
						|
 | 
						|
  template<typename T> extern T vb;
 | 
						|
  int b = vb<int>;
 | 
						|
 | 
						|
  int* intpb = vd<int*>;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |