reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
// 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