linkage2.cpp revision 5eab8d733ce7867fda4e6d5f5afa6dfe8a105c79
1// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++11 %s
2// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions -Wno-local-type-template-args %s
3// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions -Wno-local-type-template-args -fmodules %s
4
5namespace test1 {
6  int x; // expected-note {{previous definition is here}}
7  static int y;
8  void f() {} // expected-note {{previous definition is here}}
9
10  extern "C" {
11    extern int x; // expected-error {{declaration of 'x' has a different language linkage}}
12    extern int y; // OK, has internal linkage, so no language linkage.
13    void f(); // expected-error {{declaration of 'f' has a different language linkage}}
14  }
15}
16
17// This is OK. Both test2_f don't have language linkage since they have
18// internal linkage.
19extern "C" {
20  static void test2_f() {
21  }
22  static void test2_f(int x) {
23  }
24}
25
26namespace test3 {
27  extern "C" {
28    namespace {
29      extern int x2;
30      void f2();
31    }
32  }
33  namespace {
34    int x2;
35    void f2() {}
36  }
37}
38
39namespace test4 {
40  void dummy() {
41    void Bar();
42    class A {
43      friend void Bar();
44    };
45  }
46}
47
48namespace test5 {
49  static void g();
50  void f()
51  {
52    void g();
53  }
54}
55
56// pr14898
57namespace test6 {
58  template <class _Rp>
59  class __attribute__ ((__visibility__("default"))) shared_future;
60  template <class _Rp>
61  class future {
62    template <class> friend class shared_future;
63    shared_future<_Rp> share();
64  };
65  template <class _Rp> future<_Rp>
66  get_future();
67  template <class _Rp>
68  struct shared_future<_Rp&> {
69    shared_future(future<_Rp&>&& __f);
70  };
71  void f() {
72    typedef int T;
73    get_future<int>();
74    typedef int& U;
75    shared_future<int&> f1 = get_future<int&>();
76  }
77}
78
79// This is OK. The variables have internal linkage and therefore no language
80// linkage.
81extern "C" {
82  static int test7_x;
83}
84extern "C++" {
85  extern int test7_x;
86}
87extern "C++" {
88  static int test7_y;
89}
90extern "C" {
91  extern int test7_y;
92}
93extern "C" { typedef int test7_F(); static test7_F test7_f; }
94extern "C++" { extern test7_F test7_f; }
95
96// FIXME: This should be invalid. The function has no language linkage, but
97// the function type has, so this is redeclaring the function with a different
98// type.
99extern "C++" {
100  static void test8_f();
101}
102extern "C" {
103  extern void test8_f();
104}
105extern "C" {
106  static void test8_g();
107}
108extern "C++" {
109  extern void test8_g();
110}
111
112extern "C" {
113  void __attribute__((overloadable)) test9_f(int c); // expected-note {{previous declaration is here}}
114}
115extern "C++" {
116  void __attribute__((overloadable)) test9_f(int c); // expected-error {{declaration of 'test9_f' has a different language linkage}}
117}
118
119extern "C" {
120  void __attribute__((overloadable)) test10_f(int);
121  void __attribute__((overloadable)) test10_f(double);
122}
123
124extern "C" {
125  void test11_f() {
126    void  __attribute__((overloadable)) test11_g(int);
127    void  __attribute__((overloadable)) test11_g(double);
128  }
129}
130
131namespace test12 {
132  const int n = 0;
133  extern const int n;
134  void f() {
135    extern const int n;
136  }
137}
138
139namespace test13 {
140  static void a(void);
141  extern void a();
142  static void a(void) {}
143}
144
145namespace test14 {
146  namespace {
147    void a(void); // expected-note {{previous declaration is here}}
148    static void a(void) {} // expected-error {{static declaration of 'a' follows non-static declaration}}
149  }
150}
151
152namespace test15 {
153  const int a = 5; // expected-note {{previous definition is here}}
154  static const int a; // expected-error {{redefinition of 'a'}}
155}
156
157namespace test16 {
158  extern "C" {
159    class Foo {
160      int x;
161      friend int bar(Foo *y);
162    };
163    int bar(Foo *y) {
164      return y->x;
165    }
166  }
167}
168
169namespace test17 {
170  namespace {
171    struct I {
172    };
173  }
174  template <typename T1, typename T2> void foo() {}
175  template <typename T, T x> void bar() {} // expected-note {{candidate function}}
176  inline void *g() {
177    struct L {
178    };
179    // foo<L, I>'s linkage should be the merge of UniqueExternalLinkage (or
180    // InternalLinkage in c++11) and VisibleNoLinkage. The correct answer is
181    // NoLinkage in both cases. This means that using foo<L, I> as a template
182    // argument should fail.
183    return reinterpret_cast<void*>(bar<typeof(foo<L, I>), foo<L, I> >); // expected-error {{reinterpret_cast cannot resolve overloaded function 'bar' to type 'void *}}
184  }
185  void h() {
186    g();
187  }
188}
189
190namespace test18 {
191  template <typename T> struct foo {
192    template <T *P> static void f() {}
193    static void *g() { return (void *)f<&x>; }
194    static T x;
195  };
196  template <typename T> T foo<T>::x;
197  inline void *f() {
198    struct S {
199    };
200    return foo<S>::g();
201  }
202  void *h() { return f(); }
203}
204
205extern "C" void pr16247_foo(int); // expected-note {{here}}
206static void pr16247_foo(double); // expected-error {{conflicts with declaration with C language linkage}}
207void pr16247_foo(int) {}
208void pr16247_foo(double) {}
209
210namespace PR16247 {
211  extern "C" void pr16247_bar(int);
212  static void pr16247_bar(double);
213  void pr16247_bar(int) {}
214  void pr16247_bar(double) {}
215}
216