1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -Wretained-language-linkage -DW_RETAINED_LANGUAGE_LINKAGE  %s
3 extern "C" {
4   extern "C" void f(int);
5 }
6 
7 extern "C++" {
8   extern "C++" int& g(int);
9   float& g();
10 }
11 double& g(double);
12 
test(int x,double d)13 void test(int x, double d) {
14   f(x);
15   float &f1 = g();
16   int& i1 = g(x);
17   double& d1 = g(d);
18 }
19 
20 extern "C" int foo;
21 extern "C" int foo;
22 
23 extern "C" const int bar;
24 extern "C" int const bar;
25 
26 // <rdar://problem/6895431>
27 extern "C" struct bar d;
28 extern struct bar e;
29 
30 extern "C++" {
31   namespace N0 {
32     struct X0 {
fooN0::X033       int foo(int x) { return x; }
34     };
35   }
36 }
37 
38 // PR5430
39 namespace pr5430 {
40   extern "C" void func(void);
41 }
42 using namespace pr5430;
func(void)43 extern "C" void pr5430::func(void) { }
44 
45 // PR5405
f2(char *)46 int f2(char *)
47 {
48         return 0;
49 }
50 
51 extern "C"
52 {
f2(int)53     int f2(int)
54     {
55         return f2((char *)0);
56     }
57 }
58 
59 namespace PR5405 {
f2b(char *)60   int f2b(char *) {
61     return 0;
62   }
63 
64   extern "C" {
f2b(int)65     int f2b(int) {
66       return f2b((char *)0); // ok
67     }
68   }
69 }
70 
71 // PR6991
72 extern "C" typedef int (*PutcFunc_t)(int);
73 
74 
75 // PR7859
pr7859_a(int)76 extern "C" void pr7859_a(int) {} // expected-note {{previous definition}}
pr7859_a(int)77 extern "C" void pr7859_a(int) {} // expected-error {{redefinition}}
78 
pr7859_b()79 extern "C" void pr7859_b() {} // expected-note {{previous definition}}
pr7859_b(int)80 extern "C" void pr7859_b(int) {} // expected-error {{conflicting}}
81 
pr7859_c(short)82 extern "C" void pr7859_c(short) {} // expected-note {{previous definition}}
pr7859_c(int)83 extern "C" void pr7859_c(int) {} // expected-error {{conflicting}}
84 
85 // <rdar://problem/8318976>
86 extern "C" {
87   struct s0 {
88   private:
89     s0();
90     s0(const s0 &);
91   };
92 }
93 
94 //PR7754
95 extern "C++" template <class T> int pr7754(T param);
96 
97 namespace N {
98   int value;
99 }
100 
101 extern "C++" using N::value;
102 
103 // PR7076
104 extern "C" const char *Version_string = "2.9";
105 
106 extern "C" {
107   extern const char *Version_string2 = "2.9";
108 }
109 
110 namespace PR9162 {
111   extern "C" {
112     typedef struct _ArtsSink ArtsSink;
113     struct _ArtsSink {
114       int sink;
115     };
116   }
arts_sink_get_type()117   int arts_sink_get_type()
118   {
119     return sizeof(ArtsSink);
120   }
121 }
122 
123 namespace pr14958 {
124   namespace js { extern int ObjectClass; }
125   extern "C" {
126     namespace js {}
127   }
128   int js::ObjectClass;
129 }
130 
131 extern "C" void PR16167; // expected-error {{variable has incomplete type 'void'}}
132 extern void PR16167_0; // expected-error {{variable has incomplete type 'void'}}
133 
134 // PR7927
135 enum T_7927 {
136   E_7927
137 };
138 
139 extern "C" void f_pr7927(int);
140 
141 namespace {
142   extern "C" void f_pr7927(int);
143 
foo_pr7927()144   void foo_pr7927() {
145     f_pr7927(E_7927);
146     f_pr7927(0);
147     ::f_pr7927(E_7927);
148     ::f_pr7927(0);
149   }
150 }
151 
bar_pr7927()152 void bar_pr7927() {
153   f_pr7927(E_7927);
154   f_pr7927(0);
155   ::f_pr7927(E_7927);
156   ::f_pr7927(0);
157 }
158 
159 namespace PR17337 {
160   extern "C++" {
161     class Foo;
162     extern "C" int bar3(Foo *y);
163     class Foo {
164       int x;
165       friend int bar3(Foo *y);
166 #ifdef W_RETAINED_LANGUAGE_LINKAGE
167 // expected-note@-5 {{previous declaration is here}}
168 // expected-warning@-3 {{retaining previous language linkage}}
169 #endif
170     };
bar3(Foo * y)171     extern "C" int bar3(Foo *y) {
172       return y->x;
173     }
174   }
175 }
176