teak-llvm/clang/test/SemaCXX/linkage-spec.cpp
Alp Toker dd551fc3ae Retain previous language linkage of friend function declarations
With this extension, friend function declarations will retain the language
linkage specified for previous declarations instead of emitting an error
diagnostic.

The feature is known to be compatible with GCC and MSVC and permits a
language to be specified indirectly where it cannot otherwise be written
directly in class scope.

Work is ongoing to improve linkage spec diagnostics.

Fixes PR17337.

Reviewed by Richard Smith.

llvm-svn: 193206
2013-10-22 22:53:01 +00:00

176 lines
3.0 KiB
C++

// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -Wretained-language-linkage -DW_RETAINED_LANGUAGE_LINKAGE %s
extern "C" {
extern "C" void f(int);
}
extern "C++" {
extern "C++" int& g(int);
float& g();
}
double& g(double);
void test(int x, double d) {
f(x);
float &f1 = g();
int& i1 = g(x);
double& d1 = g(d);
}
extern "C" int foo;
extern "C" int foo;
extern "C" const int bar;
extern "C" int const bar;
// <rdar://problem/6895431>
extern "C" struct bar d;
extern struct bar e;
extern "C++" {
namespace N0 {
struct X0 {
int foo(int x) { return x; }
};
}
}
// PR5430
namespace pr5430 {
extern "C" void func(void);
}
using namespace pr5430;
extern "C" void pr5430::func(void) { }
// PR5405
int f2(char *)
{
return 0;
}
extern "C"
{
int f2(int)
{
return f2((char *)0);
}
}
namespace PR5405 {
int f2b(char *) {
return 0;
}
extern "C" {
int f2b(int) {
return f2b((char *)0); // ok
}
}
}
// PR6991
extern "C" typedef int (*PutcFunc_t)(int);
// PR7859
extern "C" void pr7859_a(int) {} // expected-note {{previous definition}}
extern "C" void pr7859_a(int) {} // expected-error {{redefinition}}
extern "C" void pr7859_b() {} // expected-note {{previous definition}}
extern "C" void pr7859_b(int) {} // expected-error {{conflicting}}
extern "C" void pr7859_c(short) {} // expected-note {{previous definition}}
extern "C" void pr7859_c(int) {} // expected-error {{conflicting}}
// <rdar://problem/8318976>
extern "C" {
struct s0 {
private:
s0();
s0(const s0 &);
};
}
//PR7754
extern "C++" template <class T> int pr7754(T param);
namespace N {
int value;
}
extern "C++" using N::value;
// PR7076
extern "C" const char *Version_string = "2.9";
extern "C" {
extern const char *Version_string2 = "2.9";
}
namespace PR9162 {
extern "C" {
typedef struct _ArtsSink ArtsSink;
struct _ArtsSink {
int sink;
};
}
int arts_sink_get_type()
{
return sizeof(ArtsSink);
}
}
namespace pr14958 {
namespace js { extern int ObjectClass; }
extern "C" {
namespace js {}
}
int js::ObjectClass;
}
extern "C" void PR16167; // expected-error {{variable has incomplete type 'void'}}
extern void PR16167_0; // expected-error {{variable has incomplete type 'void'}}
// PR7927
enum T_7927 {
E_7927
};
extern "C" void f_pr7927(int);
namespace {
extern "C" void f_pr7927(int);
void foo_pr7927() {
f_pr7927(E_7927);
f_pr7927(0);
::f_pr7927(E_7927);
::f_pr7927(0);
}
}
void bar_pr7927() {
f_pr7927(E_7927);
f_pr7927(0);
::f_pr7927(E_7927);
::f_pr7927(0);
}
namespace PR17337 {
extern "C++" {
class Foo;
extern "C" int bar3(Foo *y);
class Foo {
int x;
friend int bar3(Foo *y);
#ifdef W_RETAINED_LANGUAGE_LINKAGE
// expected-note@-5 {{previous declaration is here}}
// expected-warning@-3 {{retaining previous language linkage}}
#endif
};
extern "C" int bar3(Foo *y) {
return y->x;
}
}
}