diff options
author | David Blaikie <dblaikie@gmail.com> | 2012-01-24 05:47:35 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2012-01-24 05:47:35 +0000 |
commit | 5e089fe1affb63d670ea02010b104bd9fa3477a1 (patch) | |
tree | efbc3d4783da036bfecb38b64b8c1a23f276296f | |
parent | 495f42a32610c03591b49cd06ac09c5408742f86 (diff) |
Support decltype as a simple-type-specifier.
This makes all sorts of fun examples work with decltype.
Reviewed by Richard Smith.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148787 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 5 | ||||
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 5 | ||||
-rw-r--r-- | test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp | 12 | ||||
-rw-r--r-- | test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp | 40 |
5 files changed, 58 insertions, 5 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index bdebb5e6b9..606c108d7d 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -914,6 +914,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, } // Fall through + case tok::annot_decltype: case tok::kw_char: case tok::kw_wchar_t: case tok::kw_char16_t: diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 8046f6b88c..37d9b5b2b9 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -1418,8 +1418,11 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { case tok::kw_bool: DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID); break; + case tok::annot_decltype: + case tok::kw_decltype: + DS.SetRangeEnd(ParseDecltypeSpecifier(DS)); + return DS.Finish(Diags, PP); - // FIXME: C++0x decltype support. // GNU typeof support. case tok::kw_typeof: ParseTypeofSpecifier(DS); diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index fe46456040..4f80da2dc9 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -1009,6 +1009,7 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { case tok::kw_float: case tok::kw_double: case tok::kw_void: + case tok::annot_decltype: if (NextToken().is(tok::l_paren)) return TPResult::Ambiguous(); @@ -1038,10 +1039,6 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { return TPResult::True(); } - // C++0x decltype support. - case tok::annot_decltype: - return TPResult::True(); - // C++0x type traits support case tok::kw___underlying_type: return TPResult::True(); diff --git a/test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp b/test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp new file mode 100644 index 0000000000..253744e23f --- /dev/null +++ b/test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct foo { + foo(); + foo(int); +}; + +int func(foo& f) { + decltype(foo())(); + f = (decltype(foo()))5; + return decltype(3)(5); +} diff --git a/test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp b/test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp new file mode 100644 index 0000000000..81e8e25b4c --- /dev/null +++ b/test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct T { + struct x { + int m; + }; + x* operator->(); + void operator++(int); + void operator<<(int); + T(); + T(int); + T(int, int); +}; + +template<typename A, typename B, typename C, typename D, typename E> +void func(A, B, C, D, E); + +void func(int a, int c) { + T(a)->m = 7; + T(a)++; + T(a,5)<<c; + + T(*d)(int); + T(e)[5]; + T(f) = {1, 2}; + T(*g)(double(3)); // expected-error{{cannot initialize a variable of type 'T (*)' with an rvalue of type 'double'}} + func(a, d, e, f, g); +} + +void func2(int a, int c) { + decltype(T())(a)->m = 7; + decltype(T())(a)++; + decltype(T())(a,5)<<c; + + decltype(T())(*d)(int); + decltype(T())(e)[5]; + decltype(T())(f) = {1, 2}; + decltype(T())(*g)(double(3)); // expected-error{{cannot initialize a variable of type 'decltype(T()) (*)' (aka 'T *') with an rvalue of type 'double'}} + func(a, d, e, f, g); +} |