1// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
2// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
3
4namespace PR5557 {
5template <class T> struct A {
6  A(); // expected-note{{instantiation}}
7  virtual int a(T x);
8};
9template<class T> A<T>::A() {}
10
11template<class T> int A<T>::a(T x) {
12  return *x; // expected-error{{requires pointer operand}}
13}
14
15void f() {
16  A<int> x; // expected-note{{instantiation}}
17}
18
19template<typename T>
20struct X {
21  virtual void f();
22};
23
24template<>
25void X<int>::f() { }
26}
27
28// Like PR5557, but with a defined destructor instead of a defined constructor.
29namespace PR5557_dtor {
30template <class T> struct A {
31  A(); // Don't have an implicit constructor.
32  ~A(); // expected-note{{instantiation}}
33  virtual int a(T x);
34};
35template<class T> A<T>::~A() {}
36
37template<class T> int A<T>::a(T x) {
38  return *x; // expected-error{{requires pointer operand}}
39}
40
41void f() {
42  A<int> x; // expected-note{{instantiation}}
43}
44}
45
46template<typename T>
47struct Base {
48  virtual ~Base() {
49    int *ptr = 0;
50    T t = ptr; // expected-error{{cannot initialize}}
51  }
52};
53
54template<typename T>
55struct Derived : Base<T> {
56  virtual void foo() { }
57};
58
59template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
60
61template<typename T>
62struct HasOutOfLineKey {
63  HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
64  virtual T *f(float *fp);
65};
66
67template<typename T>
68T *HasOutOfLineKey<T>::f(float *fp) {
69  return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
70}
71
72HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
73
74namespace std {
75  class type_info;
76}
77
78namespace PR7114 {
79  class A { virtual ~A(); }; // expected-note{{declared private here}}
80
81  template<typename T>
82  class B {
83  public:
84    class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
85    static Inner i;
86    static const unsigned value = sizeof(i) == 4;
87  };
88
89  int f() { return B<int>::value; }
90
91#ifdef MSABI
92  void test_typeid(B<float>::Inner bfi) { // expected-note{{implicit destructor}}
93    (void)typeid(bfi);
94#else
95  void test_typeid(B<float>::Inner bfi) {
96    (void)typeid(bfi); // expected-note{{implicit destructor}}
97#endif
98  }
99
100  template<typename T>
101  struct X : A {
102    void f() { }
103  };
104
105  void test_X(X<int> &xi, X<float> &xf) {
106    xi.f();
107  }
108}
109
110namespace DynamicCast {
111  struct Y {};
112  template<typename T> struct X : virtual Y {
113    virtual void foo() { T x; }
114  };
115  template<typename T> struct X2 : virtual Y {
116    virtual void foo() { T x; }
117  };
118  Y* f(X<void>* x) { return dynamic_cast<Y*>(x); }
119  Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
120}
121
122namespace avoid_using_vtable {
123// We shouldn't emit the vtable for this code, in any ABI.  If we emit the
124// vtable, we emit an implicit virtual dtor, which calls ~RefPtr, which requires
125// a complete type for DeclaredOnly.
126//
127// Previously we would reference the vtable in the MS C++ ABI, even though we
128// don't need to emit either the ctor or the dtor.  In the Itanium C++ ABI, the
129// 'trace' method is the key function, so even though we use the vtable, we
130// don't emit it.
131
132template <typename T>
133struct RefPtr {
134  T *m_ptr;
135  ~RefPtr() { m_ptr->deref(); }
136};
137struct DeclaredOnly;
138struct Base {
139  virtual ~Base();
140};
141
142struct AvoidVTable : Base {
143  RefPtr<DeclaredOnly> m_insertionStyle;
144  virtual void trace();
145  AvoidVTable();
146};
147// Don't call the dtor, because that will emit an implicit dtor, and require a
148// complete type for DeclaredOnly.
149void foo() { new AvoidVTable; }
150}
151
152namespace vtable_uses_incomplete {
153// Opposite of the previous test that avoids a vtable, this one tests that we
154// use the vtable when the ctor is defined inline.
155template <typename T>
156struct RefPtr {
157  T *m_ptr;
158  ~RefPtr() { m_ptr->deref(); }  // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}}
159};
160struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}}
161struct Base {
162  virtual ~Base();
163};
164
165struct UsesVTable : Base {
166  RefPtr<DeclaredOnly> m_insertionStyle;
167  virtual void trace();
168  UsesVTable() {} // expected-note {{in instantiation of member function 'vtable_uses_incomplete::RefPtr<vtable_uses_incomplete::DeclaredOnly>::~RefPtr' requested here}}
169};
170}
171