[cfe-commits] r71405 - in /cfe/trunk: include/clang/AST/ include/clang/Frontend/ include/clang/Parse/ lib/AST/ lib/CodeGen/ lib/Frontend/ lib/Parse/ lib/Sema/ test/SemaCXX/ www/

Sebastian Redl sebastian.redl at getdesigned.at
Sun May 10 11:38:12 PDT 2009


Author: cornedbee
Date: Sun May 10 13:38:11 2009
New Revision: 71405

URL: http://llvm.org/viewvc/llvm-project?rev=71405&view=rev
Log:
Implement C++0x nullptr.

Added:
    cfe/trunk/test/SemaCXX/nullptr.cpp   (with props)
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/AST/StmtNodes.def
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaNamedCast.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sun May 10 13:38:11 2009
@@ -174,7 +174,7 @@
   QualType UnsignedLongLongTy, UnsignedInt128Ty;
   QualType FloatTy, DoubleTy, LongDoubleTy;
   QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
-  QualType VoidPtrTy;
+  QualType VoidPtrTy, NullPtrTy;
   QualType OverloadTy;
   QualType DependentTy;
 

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Sun May 10 13:38:11 2009
@@ -222,6 +222,24 @@
   virtual child_iterator child_end();
 };
 
+/// CXXNullPtrLiteralExpr - [C++0x 2.14.7] C++ Pointer Literal
+class CXXNullPtrLiteralExpr : public Expr {
+  SourceLocation Loc;
+public:
+  CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
+    Expr(CXXNullPtrLiteralExprClass, Ty), Loc(l) {}
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXNullPtrLiteralExprClass;
+  }
+  static bool classof(const CXXNullPtrLiteralExpr *) { return true; }
+
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
 /// CXXTypeidExpr - A C++ @c typeid expression (C++ [expr.typeid]), which gets
 /// the type_info that corresponds to the supplied type, or the (possibly
 /// dynamic) type of the supplied expression.

Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Sun May 10 13:38:11 2009
@@ -107,6 +107,7 @@
 STMT(CXXFunctionalCastExpr  , ExplicitCastExpr)
 STMT(CXXTypeidExpr          , Expr)
 STMT(CXXBoolLiteralExpr     , Expr)
+STMT(CXXNullPtrLiteralExpr  , Expr)
 STMT(CXXThisExpr            , Expr)
 STMT(CXXThrowExpr           , Expr)
 STMT(CXXDefaultArgExpr      , Expr)

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sun May 10 13:38:11 2009
@@ -394,6 +394,7 @@
   bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
   bool isObjCQualifiedIdType() const;           // id<foo>
   bool isTemplateTypeParmType() const;          // C++ template type parameter
+  bool isNullPtrType() const;                   // C++0x nullptr_t
 
   /// isDependentType - Whether this type is a dependent type, meaning
   /// that its definition somehow depends on a template parameter 
@@ -404,7 +405,7 @@
   /// hasPointerRepresentation - Whether this type is represented
   /// natively as a pointer; this includes pointers, references, block
   /// pointers, and Objective-C interface, qualified id, and qualified
-  /// interface types.
+  /// interface types, as well as nullptr_t.
   bool hasPointerRepresentation() const;
 
   /// hasObjCPointerRepresentation - Whether this type can represent
@@ -559,6 +560,8 @@
     
     Float, Double, LongDouble,
 
+    NullPtr,  // This is the type of C++0x 'nullptr'.
+
     Overload,  // This represents the type of an overloaded function declaration.
     Dependent  // This represents the type of a type-dependent expression.
   };
@@ -1926,7 +1929,7 @@
 inline bool Type::hasPointerRepresentation() const {
   return (isPointerType() || isReferenceType() || isBlockPointerType() ||
           isObjCInterfaceType() || isObjCQualifiedIdType() || 
-          isObjCQualifiedInterfaceType());
+          isObjCQualifiedInterfaceType() || isNullPtrType());
 }
 
 inline bool Type::hasObjCPointerRepresentation() const {

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Sun May 10 13:38:11 2009
@@ -319,7 +319,9 @@
       /// \brief The '__uint128_t' type.
       PREDEF_TYPE_UINT128_ID    = 21,
       /// \brief The '__int128_t' type.
-      PREDEF_TYPE_INT128_ID     = 22
+      PREDEF_TYPE_INT128_ID     = 22,
+      /// \brief The type of 'nullptr'.
+      PREDEF_TYPE_NULLPTR_ID    = 23
     };
 
     /// \brief The number of predefined type IDs that are reserved for

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Sun May 10 13:38:11 2009
@@ -963,7 +963,12 @@
 
   /// ActOnCXXBoolLiteral - Parse {true,false} literals.
   virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
-                                         tok::TokenKind Kind) {
+                                               tok::TokenKind Kind) {
+    return ExprEmpty();
+  }
+
+  /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+  virtual OwningExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc) {
     return ExprEmpty();
   }
 

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun May 10 13:38:11 2009
@@ -276,6 +276,9 @@
   
   // void * type
   VoidPtrTy = getPointerType(VoidTy);
+
+  // nullptr type (C++0x 2.14.7)
+  InitBuiltinType(NullPtrTy,           BuiltinType::NullPtr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -431,6 +434,9 @@
       Width = Target.getLongDoubleWidth();
       Align = Target.getLongDoubleAlign();
       break;
+    case BuiltinType::NullPtr:
+      Width = Target.getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
+      Align = Target.getPointerAlign(0); //   == sizeof(void*)
     }
     break;
   case Type::FixedWidthInt:

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

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sun May 10 13:38:11 2009
@@ -1377,6 +1377,10 @@
     return true;
   }
 
+  // C++0x nullptr_t is always a null pointer constant.
+  if (getType()->isNullPtrType())
+    return true;
+
   // This expression must be an integer type.
   if (!getType()->isIntegerType())
     return false;

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

==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Sun May 10 13:38:11 2009
@@ -44,6 +44,14 @@
   return child_iterator();
 }
 
+// CXXNullPtrLiteralExpr
+Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() { 
+  return child_iterator();
+}
+Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
+  return child_iterator();
+}
+
 // CXXThisExpr
 Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
 Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }

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

==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun May 10 13:38:11 2009
@@ -299,7 +299,9 @@
       { return APValue((Expr*)0, 0); }
   APValue VisitConditionalOperator(ConditionalOperator *E);
   APValue VisitChooseExpr(ChooseExpr *E)
-    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
+      { return Visit(E->getChosenSubExpr(Info.Ctx)); }
+  APValue VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E)
+      { return APValue((Expr*)0, 0); }
   // FIXME: Missing: @protocol, @selector
 };
 } // end anonymous namespace

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

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Sun May 10 13:38:11 2009
@@ -996,6 +996,10 @@
   OS << (Node->getValue() ? "true" : "false");
 }
 
+void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
+  OS << "nullptr";
+}
+
 void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
   OS << "this";
 }

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

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sun May 10 13:38:11 2009
@@ -889,6 +889,12 @@
   return false;
 }
 
+bool Type::isNullPtrType() const {
+  if (const BuiltinType *BT = getAsBuiltinType())
+    return BT->getKind() == BuiltinType::NullPtr;
+  return false;
+}
+
 const char *BuiltinType::getName() const {
   switch (getKind()) {
   default: assert(0 && "Unknown builtin type!");
@@ -912,6 +918,7 @@
   case Double:            return "double";
   case LongDouble:        return "long double";
   case WChar:             return "wchar_t";
+  case NullPtr:           return "nullptr_t";
   case Overload:          return "<overloaded function type>";
   case Dependent:         return "<dependent type>";
   }

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Sun May 10 13:38:11 2009
@@ -499,6 +499,8 @@
   // UNSUPPORTED:    ::= Di # char32_t
   // UNSUPPORTED:    ::= Ds # char16_t
   //                 ::= u <source-name>    # vendor extended type
+  // From our point of view, std::nullptr_t is a builtin, but as far as mangling
+  // is concerned, it's a type called std::nullptr_t.
   switch (T->getKind()) {
   case BuiltinType::Void: Out << 'v'; break;
   case BuiltinType::Bool: Out << 'b'; break;
@@ -519,6 +521,7 @@
   case BuiltinType::Float: Out << 'f'; break;
   case BuiltinType::Double: Out << 'd'; break;
   case BuiltinType::LongDouble: Out << 'e'; break;
+  case BuiltinType::NullPtr: Out << "St9nullptr_t"; break;
 
   case BuiltinType::Overload:
   case BuiltinType::Dependent:

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Sun May 10 13:38:11 2009
@@ -1676,6 +1676,7 @@
     case pch::PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy;       break;
     case pch::PREDEF_TYPE_OVERLOAD_ID:   T = Context->OverloadTy;         break;
     case pch::PREDEF_TYPE_DEPENDENT_ID:  T = Context->DependentTy;        break;
+    case pch::PREDEF_TYPE_NULLPTR_ID:    T = Context->NullPtrTy;          break;
     }
 
     assert(!T.isNull() && "Unknown predefined type");

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Sun May 10 13:38:11 2009
@@ -1837,6 +1837,7 @@
     case BuiltinType::Float:      ID = pch::PREDEF_TYPE_FLOAT_ID;      break;
     case BuiltinType::Double:     ID = pch::PREDEF_TYPE_DOUBLE_ID;     break;
     case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
+    case BuiltinType::NullPtr:    ID = pch::PREDEF_TYPE_NULLPTR_ID;    break;
     case BuiltinType::Overload:   ID = pch::PREDEF_TYPE_OVERLOAD_ID;   break;
     case BuiltinType::Dependent:  ID = pch::PREDEF_TYPE_DEPENDENT_ID;  break;
     }

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sun May 10 13:38:11 2009
@@ -430,6 +430,7 @@
 ///         constant
 ///         string-literal
 /// [C++]   boolean-literal  [C++ 2.13.5]
+/// [C++0x] 'nullptr'        [C++0x 2.14.7]
 ///         '(' expression ')'
 ///         '__func__'        [C99 6.4.2.2]
 /// [GNU]   '__FUNCTION__'
@@ -569,6 +570,9 @@
   case tok::kw_false:
     return ParseCXXBoolLiteral();
 
+  case tok::kw_nullptr:
+    return Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
+
   case tok::identifier: {      // primary-expression: identifier
                                // unqualified-id: identifier
                                // constant: enumeration-constant

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sun May 10 13:38:11 2009
@@ -1534,6 +1534,9 @@
   virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
                                                tok::TokenKind Kind);
 
+  /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+  virtual OwningExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc);
+
   //// ActOnCXXThrow -  Parse throw expressions.
   virtual OwningExprResult ActOnCXXThrow(SourceLocation OpLoc,
                                          ExprArg expr);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun May 10 13:38:11 2009
@@ -3811,6 +3811,20 @@
     ImpCastExprToType(rex, lType); // promote the pointer to pointer
     return ResultTy;
   }
+  // C++ allows comparison of pointers with null pointer constants.
+  if (getLangOptions().CPlusPlus) {
+    if (lType->isPointerType() && RHSIsNull) {
+      ImpCastExprToType(rex, lType);
+      return ResultTy;
+    }
+    if (rType->isPointerType() && LHSIsNull) {
+      ImpCastExprToType(lex, rType);
+      return ResultTy;
+    }
+    // And comparison of nullptr_t with itself.
+    if (lType->isNullPtrType() && rType->isNullPtrType())
+      return ResultTy;
+  }
   // Handle block pointer types.
   if (!isRelational && lType->isBlockPointerType() && rType->isBlockPointerType()) {
     QualType lpointee = lType->getAsBlockPointerType()->getPointeeType();

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun May 10 13:38:11 2009
@@ -85,6 +85,12 @@
                                                 Context.BoolTy, OpLoc));
 }
 
+/// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+Action::OwningExprResult
+Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
+  return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
+}
+
 /// ActOnCXXThrow - Parse throw expressions.
 Action::OwningExprResult
 Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprArg E) {

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaNamedCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaNamedCast.cpp Sun May 10 13:38:11 2009
@@ -279,12 +279,26 @@
     return;
   }
 
+  // See below for the enumeral issue.
+  if (SrcType->isNullPtrType() && DestType->isIntegralType() &&
+      !DestType->isEnumeralType()) {
+    // C++0x 5.2.10p4: A pointer can be explicitly converted to any integral
+    //   type large enough to hold it. A value of std::nullptr_t can be
+    //   converted to an integral type; the conversion has the same meaning
+    //   and validity as a conversion of (void*)0 to the integral type.
+    if (Self.Context.getTypeSize(SrcType) >
+        Self.Context.getTypeSize(DestType)) {
+      Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_small_int)
+        << OrigDestType << DestRange;
+    }
+    return;
+  }
+
   bool destIsPtr = DestType->isPointerType();
   bool srcIsPtr = SrcType->isPointerType();
   if (!destIsPtr && !srcIsPtr) {
-    // Except for std::nullptr_t->integer, which is not supported yet, and
-    // lvalue->reference, which is handled above, at least one of the two
-    // arguments must be a pointer.
+    // Except for std::nullptr_t->integer and lvalue->reference, which are
+    // handled above, at least one of the two arguments must be a pointer.
     Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
       << "reinterpret_cast" << OrigDestType << OrigSrcType << OpRange;
     return;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun May 10 13:38:11 2009
@@ -621,7 +621,8 @@
             FromType->isEnumeralType() ||
             FromType->isPointerType() ||
             FromType->isBlockPointerType() ||
-            FromType->isMemberPointerType())) {
+            FromType->isMemberPointerType() ||
+            FromType->isNullPtrType())) {
     SCS.Second = ICK_Boolean_Conversion;
     FromType = Context.BoolTy;
   }
@@ -898,6 +899,13 @@
     return true;
   }
 
+  // If the left-hand-side is nullptr_t, the right side can be a null
+  // pointer constant.
+  if (ToType->isNullPtrType() && From->isNullPointerConstant(Context)) {
+    ConvertedType = ToType;
+    return true;
+  }
+
   const PointerType* ToTypePtr = ToType->getAsPointerType();
   if (!ToTypePtr)
     return false;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sun May 10 13:38:11 2009
@@ -1198,6 +1198,10 @@
   if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
     Arg = Cast->getSubExpr();
 
+  // C++0x allows nullptr, and there's no further checking to be done for that.
+  if (Arg->getType()->isNullPtrType())
+    return false;
+
   // C++ [temp.arg.nontype]p1:
   // 
   //   A template-argument for a non-type, non-template
@@ -1296,6 +1300,10 @@
   if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
     Arg = Cast->getSubExpr();
 
+  // C++0x allows nullptr, and there's no further checking to be done for that.
+  if (Arg->getType()->isNullPtrType())
+    return false;
+
   // C++ [temp.arg.nontype]p1:
   // 
   //   A template-argument for a non-type, non-template
@@ -1485,6 +1493,7 @@
       //    applied. If the template-argument represents a set of
       //    overloaded functions (or a pointer to such), the matching
       //    function is selected from the set (13.4).
+      // In C++0x, any std::nullptr_t value can be converted.
       (ParamType->isPointerType() &&
        ParamType->getAsPointerType()->getPointeeType()->isFunctionType()) ||
       // -- For a non-type template-parameter of type reference to
@@ -1498,12 +1507,17 @@
       //    template-argument represents a set of overloaded member
       //    functions, the matching member function is selected from
       //    the set (13.4).
+      // Again, C++0x allows a std::nullptr_t value.
       (ParamType->isMemberPointerType() &&
        ParamType->getAsMemberPointerType()->getPointeeType()
          ->isFunctionType())) {
     if (Context.hasSameUnqualifiedType(ArgType, 
                                        ParamType.getNonReferenceType())) {
       // We don't have to do anything: the types already match.
+    } else if (ArgType->isNullPtrType() && (ParamType->isPointerType() ||
+                 ParamType->isMemberPointerType())) {
+      ArgType = ParamType;
+      ImpCastExprToType(Arg, ParamType);
     } else if (ArgType->isFunctionType() && ParamType->isPointerType()) {
       ArgType = Context.getPointerType(ArgType);
       ImpCastExprToType(Arg, ArgType);
@@ -1554,14 +1568,18 @@
     //   -- for a non-type template-parameter of type pointer to
     //      object, qualification conversions (4.4) and the
     //      array-to-pointer conversion (4.2) are applied.
+    // C++0x also allows a value of std::nullptr_t.
     assert(ParamType->getAsPointerType()->getPointeeType()->isObjectType() &&
            "Only object pointers allowed here");
 
-    if (ArgType->isArrayType()) {
+    if (ArgType->isNullPtrType()) {
+      ArgType = ParamType;
+      ImpCastExprToType(Arg, ParamType);
+    } else if (ArgType->isArrayType()) {
       ArgType = Context.getArrayDecayedType(ArgType);
       ImpCastExprToType(Arg, ArgType);
     }
-    
+
     if (IsQualificationConversion(ArgType, ParamType)) {
       ArgType = ParamType;
       ImpCastExprToType(Arg, ParamType);
@@ -1630,10 +1648,13 @@
 
   //     -- For a non-type template-parameter of type pointer to data
   //        member, qualification conversions (4.4) are applied.
+  // C++0x allows std::nullptr_t values.
   assert(ParamType->isMemberPointerType() && "Only pointers to members remain");
 
   if (Context.hasSameUnqualifiedType(ParamType, ArgType)) {
     // Types match exactly: nothing more to do here.
+  } else if (ArgType->isNullPtrType()) {
+    ImpCastExprToType(Arg, ParamType);
   } else if (IsQualificationConversion(ArgType, ParamType)) {
     ImpCastExprToType(Arg, ParamType);
   } else {

Added: cfe/trunk/test/SemaCXX/nullptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr.cpp?rev=71405&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/nullptr.cpp (added)
+++ cfe/trunk/test/SemaCXX/nullptr.cpp Sun May 10 13:38:11 2009
@@ -0,0 +1,67 @@
+// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s
+#include <stdint.h>
+
+// Don't have decltype yet.
+typedef __typeof__(nullptr) nullptr_t;
+
+struct A {};
+
+int o1(char*);
+void o1(uintptr_t);
+void o2(char*); // expected-note {{candidate}}
+void o2(int A::*); // expected-note {{candidate}}
+
+nullptr_t f(nullptr_t null)
+{
+  // Implicit conversions.
+  null = nullptr;
+  void *p = nullptr;
+  p = null;
+  int *pi = nullptr;
+  pi = null;
+  null = 0;
+  int A::*pm = nullptr;
+  pm = null;
+  void (*pf)() = nullptr;
+  pf = null;
+  void (A::*pmf)() = nullptr;
+  pmf = null;
+  bool b = nullptr;
+
+  // Can't convert nullptr to integral implicitly.
+  uintptr_t i = nullptr; // expected-error {{incompatible type initializing}}
+
+  // Operators
+  (void)(null == nullptr);
+  (void)(null <= nullptr);
+  (void)(null == (void*)0);
+  (void)((void*)0 == nullptr);
+  (void)(null <= (void*)0);
+  (void)((void*)0 <= nullptr);
+  (void)(1 > nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(1 != nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(1 + nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(0 ? nullptr : 0); // expected-error {{incompatible operand types}}
+  (void)(0 ? nullptr : (void*)0);
+
+  // Overloading
+  int t = o1(nullptr);
+  t = o1(null);
+  o2(nullptr); // expected-error {{ambiguous}}
+
+  // nullptr is an rvalue, null is an lvalue
+  (void)&nullptr; // expected-error {{address expression must be an lvalue}}
+  nullptr_t *pn = &null;
+
+  // You can reinterpret_cast nullptr to an integer.
+  (void)reinterpret_cast<uintptr_t>(nullptr);
+
+  // You can throw nullptr.
+  throw nullptr;
+}
+
+// Template arguments can be nullptr.
+template <int *PI, void (*PF)(), int A::*PM, void (A::*PMF)()>
+struct T {};
+
+typedef T<nullptr, nullptr, nullptr, nullptr> NT;

Propchange: cfe/trunk/test/SemaCXX/nullptr.cpp

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/SemaCXX/nullptr.cpp

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/SemaCXX/nullptr.cpp

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=71405&r1=71404&r2=71405&view=diff

==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Sun May 10 13:38:11 2009
@@ -1952,38 +1952,46 @@
 <tr><td>E [extendid]</td><td></td><td></td><td></td><td></td><td></td></tr>
 <tr>
   <td colspan="6" align="center" bgcolor="#ffffcc">C++0x Features</td>
-  <tr>
+</tr>
+<tr>
   <td>Explicit conversion operators (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf">N2437</a>)</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="medium" align="center"></td>
   <td class="advanced" align="center"></td>
   <td class="broken"></td>
   <td>No name mangling; ASTs don't contain calls to conversion operators</td>
-  </tr>
-  <tr>
+</tr>
+<tr>
   <td>Static assertions (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.pdf">N1720</a>)</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="na">N/A</td>
   <td></td>
-  </tr>
-  <tr>
+</tr>
+<tr>
   <td>Deleted functions (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">N2346</a>)</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="na">N/A</td>
   <td></td>
-  </tr>
-  <tr>
+</tr>
+<tr>
   <td>Rvalue references (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html">N2118</a> + <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2831.html">N2831</a>)</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="complete" align="center">&#x2713;</td>
   <td class="broken"></td>
   <td></td>
-  </tr>
+</tr>
+<tr>
+  <td>nullptr (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf">N2431</a>)</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="broken"></td>
+  <td></td>
 </tr>
 
 </table>





More information about the cfe-commits mailing list