Audit and finish the implementation of C++0x nullptr, fixing two
minor issues along the way:
  - Non-type template parameters of type 'std::nullptr_t' were not
  permitted.
  - We didn't properly introduce built-in operators for nullptr ==,
  !=, <, <=, >=, or > as candidate functions .

To my knowledge, there's only one (minor but annoying) part of nullptr
that hasn't been implemented: catching a thrown 'nullptr' as a pointer
or pointer-to-member, per C++0x [except.handle]p4.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131813 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index f3392e4..8e7e1a1 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -602,8 +602,10 @@
       T->isPointerType() ||
       //   -- reference to object or reference to function,
       T->isReferenceType() ||
-      //   -- pointer to member.
+      //   -- pointer to member,
       T->isMemberPointerType() ||
+      //   -- std::nullptr_t.
+      T->isNullPtrType() ||
       // If T is a dependent type, we can't do the check now, so we
       // assume that it is well-formed.
       T->isDependentType())
@@ -3756,10 +3758,17 @@
   // from a template argument of type std::nullptr_t to a non-type
   // template parameter of type pointer to object, pointer to
   // function, or pointer-to-member, respectively.
-  if (ArgType->isNullPtrType() &&
-      (ParamType->isPointerType() || ParamType->isMemberPointerType())) {
-    Converted = TemplateArgument((NamedDecl *)0);
-    return Owned(Arg);
+  if (ArgType->isNullPtrType()) {
+    if (ParamType->isPointerType() || ParamType->isMemberPointerType()) {
+      Converted = TemplateArgument((NamedDecl *)0);
+      return Owned(Arg);
+    }
+    
+    if (ParamType->isNullPtrType()) {
+      llvm::APSInt Zero(Context.getTypeSize(Context.NullPtrTy), true);
+      Converted = TemplateArgument(Zero, Context.NullPtrTy);
+      return Owned(Arg);
+    }
   }
 
   // Handle pointer-to-function, reference-to-function, and
@@ -4053,6 +4062,9 @@
                                             Arg.getAsIntegral()->getBoolValue(),
                                             T, Loc));
 
+  if (T->isNullPtrType())
+    return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
+  
   // If this is an enum type that we're instantiating, we need to use an integer
   // type the same size as the enumerator.  We don't want to build an
   // IntegerLiteral with enum type.