Daniel Dunbar | a572887 | 2009-12-15 20:14:24 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 2 | namespace A |
| 3 | { |
| 4 | namespace B |
| 5 | { |
Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 6 | struct base // expected-note{{object type}} |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 7 | { |
| 8 | void x() {} |
| 9 | void y() {} |
| 10 | }; |
| 11 | } |
| 12 | |
| 13 | struct member |
| 14 | { |
| 15 | void foo(); |
| 16 | }; |
| 17 | |
| 18 | struct middleman |
| 19 | { |
| 20 | member * operator->() { return 0; } |
| 21 | }; |
| 22 | |
| 23 | struct sub : B::base |
| 24 | { |
| 25 | void x() {} |
| 26 | middleman operator->() { return middleman(); } |
| 27 | }; |
| 28 | } |
| 29 | |
| 30 | struct bad |
| 31 | { |
| 32 | int x(); |
| 33 | }; |
| 34 | |
| 35 | namespace C |
| 36 | { |
| 37 | void fun() |
| 38 | { |
| 39 | A::sub a; |
| 40 | |
| 41 | a.x(); |
| 42 | |
| 43 | a.sub::x(); |
| 44 | a.base::x(); |
| 45 | |
| 46 | a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}} |
| 47 | |
| 48 | a.A::sub::x(); |
| 49 | a.A::B::base::x(); |
| 50 | |
John McCall | 110acc1 | 2010-04-27 01:43:38 +0000 | [diff] [blame] | 51 | a.bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}} |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 52 | |
| 53 | a->foo(); |
| 54 | a->member::foo(); |
| 55 | a->A::member::foo(); |
| 56 | } |
| 57 | |
| 58 | void fun2() |
| 59 | { |
| 60 | A::sub *a; |
| 61 | |
| 62 | a->x(); |
| 63 | |
| 64 | a->sub::x(); |
| 65 | a->base::x(); |
| 66 | |
| 67 | a->B::base::x(); // expected-error{{use of undeclared identifier 'B'}} |
| 68 | |
| 69 | a->A::sub::x(); |
| 70 | a->A::B::base::x(); |
| 71 | |
John McCall | 110acc1 | 2010-04-27 01:43:38 +0000 | [diff] [blame] | 72 | a->bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}} |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 73 | |
| 74 | (*a)->foo(); |
| 75 | (*a)->member::foo(); |
| 76 | (*a)->A::member::foo(); |
| 77 | } |
| 78 | |
| 79 | void fun3() |
| 80 | { |
| 81 | int i; |
| 82 | i.foo(); // expected-error{{member reference base type 'int' is not a structure or union}} |
| 83 | } |
| 84 | |
Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 85 | void fun4a() { |
| 86 | A::sub *a; |
| 87 | |
| 88 | typedef A::member base; // expected-note{{current scope}} |
| 89 | a->base::x(); // expected-error{{ambiguous}} |
| 90 | } |
| 91 | |
| 92 | void fun4b() { |
| 93 | A::sub *a; |
| 94 | |
| 95 | typedef A::B::base base; |
| 96 | a->base::x(); |
| 97 | } |
| 98 | |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 99 | template<typename T> |
Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 100 | void fun5() |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 101 | { |
| 102 | T a; |
| 103 | a.x(); |
| 104 | a->foo(); |
| 105 | |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 106 | a.A::sub::x(); |
| 107 | a.A::B::base::x(); |
| 108 | a->A::member::foo(); |
| 109 | |
John McCall | 110acc1 | 2010-04-27 01:43:38 +0000 | [diff] [blame] | 110 | a.bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}} |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 111 | } |
Douglas Gregor | c68afe2 | 2009-09-03 21:38:09 +0000 | [diff] [blame] | 112 | |
Douglas Gregor | a38c687 | 2009-09-03 16:14:30 +0000 | [diff] [blame] | 113 | void test_fun5() { |
Douglas Gregor | c68afe2 | 2009-09-03 21:38:09 +0000 | [diff] [blame] | 114 | fun5<A::sub>(); // expected-note{{instantiation}} |
Douglas Gregor | a38c687 | 2009-09-03 16:14:30 +0000 | [diff] [blame] | 115 | } |
Douglas Gregor | c68afe2 | 2009-09-03 21:38:09 +0000 | [diff] [blame] | 116 | |
| 117 | template<typename T> |
| 118 | void fun6() { |
| 119 | T a; |
| 120 | a.sub::x(); |
| 121 | a.base::x(); |
| 122 | a->member::foo(); |
| 123 | a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}} |
| 124 | } |
| 125 | |
| 126 | void test_fun6() { |
| 127 | fun6<A::sub>(); // expected-note{{instantiation}} |
| 128 | } |
| 129 | |
Douglas Gregor | fe85ced | 2009-08-06 03:17:00 +0000 | [diff] [blame] | 130 | } |
Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 131 | |
| 132 | // PR4703 |
| 133 | struct a { |
| 134 | int a; |
| 135 | static int sa; |
| 136 | }; |
| 137 | |
| 138 | a a; |
| 139 | |
Richard Smith | a85cf39 | 2012-04-05 01:13:04 +0000 | [diff] [blame] | 140 | int a::sa = a.a; // expected-error {{invalid use of non-static data member 'a'}} |
Douglas Gregor | 9de672f | 2010-03-23 15:26:55 +0000 | [diff] [blame] | 141 | |
| 142 | |
| 143 | namespace PR6645 { |
| 144 | typedef int foo; |
| 145 | namespace Inner { |
| 146 | typedef int PR6645::foo; // expected-error{{typedef declarator cannot be qualified}} \ |
Richard Smith | a1c4f7c | 2012-04-13 04:07:40 +0000 | [diff] [blame] | 147 | // expected-error{{cannot define or redeclare 'foo' here because namespace 'Inner' does not enclose namespace 'PR6645'}} |
Douglas Gregor | 9de672f | 2010-03-23 15:26:55 +0000 | [diff] [blame] | 148 | } |
| 149 | } |