]> granicus.if.org Git - clang/commitdiff
Support decltype as a simple-type-specifier.
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 24 Jan 2012 05:47:35 +0000 (05:47 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 24 Jan 2012 05:47:35 +0000 (05:47 +0000)
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

lib/Parse/ParseExpr.cpp
lib/Parse/ParseExprCXX.cpp
lib/Parse/ParseTentative.cpp
test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp [new file with mode: 0644]
test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp [new file with mode: 0644]

index bdebb5e6b9492a06859b0383606d1728390fd2e5..606c108d7d29b6727000c8a0b15df42523edc57b 100644 (file)
@@ -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:
index 8046f6b88c7a69d58069562b112d2ec44657e162..37d9b5b2b9ab7f5a4dad0d2226e2a13de8951325 100644 (file)
@@ -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);
index fe464560403b299be67783610e17ceb63df06a37..4f80da2dc998cfcfb5657ce829ea4a38190aed5d 100644 (file)
@@ -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 (file)
index 0000000..253744e
--- /dev/null
@@ -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 (file)
index 0000000..81e8e25
--- /dev/null
@@ -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);
+}