Support for C++11 (non-template) alias declarations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129567 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp b/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp
new file mode 100644
index 0000000..751c0df
--- /dev/null
+++ b/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// Classes.
+namespace Class {
+ namespace NS {
+ class C {}; // expected-note {{candidate}}
+ }
+ using namespace NS;
+ class C : C {}; // expected-error {{reference to 'C' is ambiguous}} \
+ expected-note {{candidate}}
+}
+
+// Enumerations.
+enum E {
+ EPtrSize = sizeof((E*)0) // ok, E is already declared
+};
+
+// Alias declarations. clang implements the proposed resolution to N1044.
+namespace Alias {
+ namespace NS {
+ class C;
+ }
+ using namespace NS;
+ using C = C; // ok, C = B::C
+ using C = NS::C; // ok, same type
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
index 6482771..c00d4b7 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
@@ -63,7 +63,7 @@
struct F : auto {}; // expected-error{{expected class name}}
template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed here}}
-using A = auto; // expected-error{{expected ';'}} expected-error{{requires a qualified name}}
+using A = auto; // expected-error{{'auto' not allowed in type alias}}
// FIXME: don't issue the second diagnostic for this error.
auto k() -> auto; // expected-error{{'auto' not allowed here}} unexpected-error{{without trailing return type}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
new file mode 100644
index 0000000..a51cfbf
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
@@ -0,0 +1,161 @@
+// RUN: %clang_cc1 -verify -std=c++0x %s
+
+namespace RedeclAliasTypedef {
+ typedef int T;
+ using T = int;
+ using T = int;
+ typedef T T;
+ using T = T;
+ typedef int T;
+}
+
+namespace IllegalTypeIds {
+ using A = void(int n = 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}}
+ using B = inline void(int n); // expected-error {{type name does not allow function specifier}}
+ using C = virtual void(int n); // expected-error {{type name does not allow function specifier}}
+ using D = explicit void(int n); // expected-error {{type name does not allow function specifier}}
+ using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}}
+ // FIXME: this is illegal; we incorrectly accept it for typedefs too.
+ using F = void(*)(int n) &&; // expected-err
+ using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}}
+
+ using H = void(int n); // ok
+ using I = void(int n) &&; // ok
+}
+
+namespace IllegalSyntax {
+ using ::T = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ using operator int = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}}
+ using typename ::V = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ using typename ::operator bool = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+}
+
+namespace VariableLengthArrays {
+ using T = int[42]; // ok
+
+ int n = 32;
+ using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}}
+
+ const int m = 42;
+ using U = int[m]; // expected-note {{previous definition}}
+ using U = int[42]; // ok
+ using U = int; // expected-error {{type alias redefinition with different types ('int' vs 'int [42]')}}
+
+ void f() {
+ int n = 42;
+ goto foo; // expected-error {{goto into protected scope}}
+ using T = int[n]; // expected-note {{bypasses initialization of VLA type alias}}
+ foo: ;
+ }
+}
+
+namespace RedeclFunc {
+ int f(int, char**);
+ using T = int;
+ T f(int, char **); // ok
+}
+
+namespace LookupFilter {
+ namespace N { struct S; }
+ using namespace N;
+ using S = S*; // ok
+}
+
+namespace InFunctions {
+ template<typename...T> void f0() {
+ using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+ U u;
+ }
+ template void f0<int, char>();
+
+ void f1() {
+ using T = int;
+ }
+ void f2() {
+ using T = int[-1]; // expected-error {{array size is negative}}
+ }
+
+ template<typename...T> void f3() { // expected-note {{template parameter is declared here}}
+ using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+ }
+}
+
+namespace ClassNameRedecl {
+ class C0 {
+ // FIXME: this diagnostic is pretty poor
+ using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}}
+ };
+ class C1 {
+ // FIXME: this diagnostic is pretty poor
+ using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}}
+ };
+ class C2 {
+ using C0 = C1; // ok
+ };
+ template<typename...T> class C3 {
+ using f = T; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+ };
+ template<typename T> class C4 { // expected-note {{template parameter is declared here}}
+ using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ class C5 {
+ class c; // expected-note {{previous definition}}
+ using c = int; // expected-error {{typedef redefinition with different types}}
+ class d;
+ using d = d; // ok
+ };
+ class C6 {
+ class c { using C6 = int; }; // ok
+ };
+}
+
+class CtorDtorName {
+ using X = CtorDtorName;
+ X(); // expected-error {{expected member name}}
+ ~X(); // expected-error {{destructor cannot be declared using a type alias}}
+};
+
+namespace TagName {
+ using S = struct { int n; };
+ using T = class { int n; };
+ using U = enum { a, b, c };
+ using V = struct V { int n; };
+}
+
+namespace CWG1044 {
+ // FIXME: this is terrible. one error is plenty.
+ using T = T; // expected-error {{type name requires a specifier}} \
+ expected-error {{C++ requires a type specifier}} \
+ expected-error {{expected ';' after alias declaration}}
+}
+
+namespace StdExample {
+ template<typename T, typename U> struct pair;
+
+ using handler_t = void (*)(int);
+ extern handler_t ignore;
+ extern void (*ignore)(int);
+ // FIXME: we know we're parsing a type here; don't recover as if we were
+ // using operator*.
+ using cell = pair<void*, cell*>; // expected-error {{use of undeclared identifier 'cell'}} \
+ expected-error {{expected expression}}
+}
+
+namespace Access {
+ class C0 {
+ using U = int; // expected-note {{declared private here}}
+ };
+ C0::U v; // expected-error {{'U' is a private member}}
+ class C1 {
+ public:
+ using U = int;
+ };
+ C1::U w; // ok
+}
+
+namespace VoidArg {
+ using V = void;
+ V f(int); // ok
+ V g(V); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
+}
diff --git a/test/FixIt/fixit-cxx0x.cpp b/test/FixIt/fixit-cxx0x.cpp
index d8a858d..90bf9f5 100644
--- a/test/FixIt/fixit-cxx0x.cpp
+++ b/test/FixIt/fixit-cxx0x.cpp
@@ -14,3 +14,6 @@
}
}
+using ::T = void; // expected-error {{name defined in alias declaration must be an identifier}}
+using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}}
+using typename ::V = void; // expected-error {{name defined in alias declaration must be an identifier}}