MicrosoftSuper.cpp revision 0e2c34f92f00628d48968dfea096d36381f494cb
1// RUN: %clang_cc1 %s -fsyntax-only -fms-extensions -std=c++11 -verify
2
3struct Errors {
4  using __super::foo; // expected-error {{'__super' cannot be used with a using declaration}}
5  __super::XXX x; // expected-error {{invalid use of '__super', Errors has no base classes}} expected-error {{expected}}
6
7  void foo() {
8    // expected-note@+4 {{replace parentheses with an initializer to declare a variable}}
9    // expected-warning@+3 {{empty parentheses interpreted as a function declaration}}
10    // expected-error@+2 {{C++ requires a type specifier for all declarations}}
11    // expected-error@+1 {{use of '__super' inside a lambda is unsupported}}
12    auto lambda = []{ __super::foo(); };
13  }
14};
15
16struct Base1 {
17  void foo(int) {}
18
19  static void static_foo() {}
20
21  typedef int XXX;
22};
23
24struct Derived : Base1 {
25  __super::XXX x;
26  typedef __super::XXX Type;
27
28  enum E {
29    X = sizeof(__super::XXX)
30  };
31
32  void foo() {
33    __super::foo(1);
34
35    if (true) {
36      __super::foo(1);
37    }
38
39    return __super::foo(1);
40  }
41
42  static void bar() {
43    __super::static_foo();
44  }
45};
46
47struct Outer {
48  struct Inner : Base1 {
49    static const int x = sizeof(__super::XXX);
50  };
51};
52
53struct Base2 {
54  void foo(char) {}
55};
56
57struct MemberFunctionInMultipleBases : Base1, Base2 {
58  void foo() {
59    __super::foo('x');
60  }
61};
62
63struct Base3 {
64  void foo(int) {}
65  void foo(char) {}
66};
67
68struct OverloadedMemberFunction : Base3 {
69  void foo() {
70    __super::foo('x');
71  }
72};
73
74struct PointerToMember : Base1 {
75  template <void (Base1::*MP)(int)>
76  struct Wrapper {
77    static void bar() {}
78  };
79
80  void baz();
81};
82
83void PointerToMember::baz() {
84  Wrapper<&__super::foo>::bar();
85}
86
87template <typename T>
88struct BaseTemplate {
89  typedef int XXX;
90
91  int foo() { return 0; }
92};
93
94struct DerivedFromKnownSpecialization : BaseTemplate<int> {
95  __super::XXX a;
96  typedef __super::XXX b;
97
98  void foo() {
99    __super::XXX c;
100    typedef __super::XXX d;
101
102    __super::foo();
103  }
104};
105
106template <typename T>
107struct DerivedFromDependentBase : BaseTemplate<T> {
108  typename __super::XXX a;
109  typedef typename __super::XXX b;
110
111  __super::XXX c;         // expected-error {{missing 'typename'}}
112  typedef __super::XXX d; // expected-error {{missing 'typename'}}
113
114  void foo() {
115    typename __super::XXX e;
116    typedef typename __super::XXX f;
117
118    __super::XXX g;         // expected-error {{missing 'typename'}}
119    typedef __super::XXX h; // expected-error {{missing 'typename'}}
120
121    int x = __super::foo();
122  }
123};
124
125template <typename T>
126struct DerivedFromTemplateParameter : T {
127  typename __super::XXX a;
128  typedef typename __super::XXX b;
129
130  __super::XXX c;         // expected-error {{missing 'typename'}}
131  typedef __super::XXX d; // expected-error {{missing 'typename'}}
132
133  void foo() {
134    typename __super::XXX e;
135    typedef typename __super::XXX f;
136
137    __super::XXX g;         // expected-error {{missing 'typename'}}
138    typedef __super::XXX h; // expected-error {{missing 'typename'}}
139
140    __super::foo(1);
141  }
142};
143
144void instantiate() {
145  DerivedFromDependentBase<int> d;
146  d.foo();
147  DerivedFromTemplateParameter<Base1> t;
148  t.foo();
149}
150
151namespace {
152struct B { int a; };
153template <class C>
154struct A : B {
155  // Don't crash on dependent_type_var '->' '__super'
156  void f() { int a = this->__super::a; }
157};
158}
159