[cfe-commits] r74118 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/Sema/SemaType.cpp test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp

Anders Carlsson andersca at mac.com
Wed Jun 24 14:25:30 PDT 2009


Author: andersca
Date: Wed Jun 24 16:24:56 2009
New Revision: 74118

URL: http://llvm.org/viewvc/llvm-project?rev=74118&view=rev
Log:
C++ decltype support (N2343)

Added:
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=74118&r1=74117&r2=74118&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Jun 24 16:24:56 2009
@@ -1663,15 +1663,43 @@
   return QualType(tot, 0);
 }
 
+/// getDecltypeForExpr - Given an expr, will return the decltype for that
+/// expression, according to the rules in C++0x [dcl.type.simple]p4
+static QualType getDecltypeForExpr(const Expr *e, ASTContext &Context) {
+  // If e is an id expression or a class member access, decltype(e) is defined
+  // as the type of the entity named by e.
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(e)) {
+    if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl()))
+      return VD->getType();
+  }
+  if (const MemberExpr *ME = dyn_cast<MemberExpr>(e)) {
+    if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
+      return FD->getType();
+  }
+  // If e is a function call or an invocation of an overloaded operator,
+  // (parentheses around e are ignored), decltype(e) is defined as the
+  // return type of that function.
+  if (const CallExpr *CE = dyn_cast<CallExpr>(e->IgnoreParens()))
+    return CE->getCallReturnType();
+  
+  QualType T = e->getType();
+  
+  // Otherwise, where T is the type of e, if e is an lvalue, decltype(e) is 
+  // defined as T&, otherwise decltype(e) is defined as T.
+  if (e->isLvalue(Context) == Expr::LV_Valid)
+    T = Context.getLValueReferenceType(T);
+  
+  return T;
+}
+
 /// getDecltypeType -  Unlike many "get<Type>" functions, we don't unique
 /// DecltypeType AST's. The only motivation to unique these nodes would be
 /// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
 /// an issue. This doesn't effect the type checker, since it operates 
 /// on canonical type's (which are always unique).
 QualType ASTContext::getDecltypeType(Expr *e) {
-  // FIXME: Use the right type here!
-  QualType Canonical = getCanonicalType(e->getType());
-  DecltypeType *dt = new (*this, 8) DecltypeType(e, Canonical);
+  QualType T = getDecltypeForExpr(e, *this);
+  DecltypeType *dt = new (*this, 8) DecltypeType(e, getCanonicalType(T));
   Types.push_back(dt);
   return QualType(dt, 0);
 }

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=74118&r1=74117&r2=74118&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Jun 24 16:24:56 2009
@@ -240,10 +240,7 @@
     Expr *E = static_cast<Expr *>(DS.getTypeRep());
     assert(E && "Didn't get an expression for decltype?");
     // TypeQuals handled by caller.
-    
-    // FIXME: Use the right type!
-    Result = Context.IntTy;
-    isInvalid = true;
+    Result = Context.getDecltypeType(E);
     break;
   }
     

Added: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp?rev=74118&view=auto

==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp (added)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp Wed Jun 24 16:24:56 2009
@@ -0,0 +1,21 @@
+// RUN: clang-cc -fsyntax-only -std=c++0x -verify %s
+
+template<typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+const int&& foo();
+int i;
+struct A { double x; };
+const A* a = new A();
+
+static_assert(is_same<decltype(foo()), const int&&>::value, "");
+static_assert(is_same<decltype(i), int>::value, "");
+static_assert(is_same<decltype(a->x), double>::value, "");
+static_assert(is_same<decltype((a->x)), const double&>::value, "");





More information about the cfe-commits mailing list