aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/qual-id-test.cpp
blob: ad013990cac2ecef310a48efaec403820ef67898 (plain)
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
// RUN: clang-cc -fsyntax-only -verify %s 
namespace A
{
    namespace B
    {
        struct base
        {
            void x() {}
            void y() {}
        };
    }

    struct member
    {
        void foo();
    };

    struct middleman
    {
        member * operator->() { return 0; }
    };

    struct sub : B::base
    {
        void x() {}
        middleman operator->() { return middleman(); }
    };
}

struct bad
{
  int x();
};

namespace C
{
    void fun()
    {
        A::sub a;

        a.x();
    
        a.sub::x();
        a.base::x();

        a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}}

        a.A::sub::x();
        a.A::B::base::x();

        a.bad::x(); // expected-error{{type 'struct bad' is not a direct or virtual base of ''struct A::sub''}}

        a->foo();
        a->member::foo();
        a->A::member::foo();
    }

    void fun2()
    {
        A::sub *a;

        a->x();

        a->sub::x();
        a->base::x();

        a->B::base::x(); // expected-error{{use of undeclared identifier 'B'}}

        a->A::sub::x();
        a->A::B::base::x();

        a->bad::x(); // expected-error{{type 'struct bad' is not a direct or virtual base of ''struct A::sub''}}

        (*a)->foo();
        (*a)->member::foo();
        (*a)->A::member::foo();
    }

    void fun3()
    {
        int i;
        i.foo(); // expected-error{{member reference base type 'int' is not a structure or union}}
    }

    template<typename T>
    void fun4()
    {
        T a;
        a.x();
        a->foo();

        // Things that work for the wrong reason
        a.A::sub::x();
        a.A::B::base::x();
        a->A::member::foo();

        // Things that work, but shouldn't
        a.bad::x();

        // Things that fail, but shouldn't
        a.sub::x(); // expected-error{{use of undeclared identifier 'sub'}}
        a.base::x(); // expected-error{{use of undeclared identifier 'base'}}
        a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}}
        a->member::foo(); // expected-error{{use of undeclared identifier 'member'}}
    }
}