Implement C++0x nullptr.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71405 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 4aed59f..133e8c2 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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:
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 77a25f6..0d38dd2 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -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;
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index b05bf7d..8176db5 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -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(); }
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index aa4920f..34b0187 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -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
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 0f8284a..cf1a255 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -996,6 +996,10 @@
OS << (Node->getValue() ? "true" : "false");
}
+void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
+ OS << "nullptr";
+}
+
void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
OS << "this";
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index d6cf4bd..b5a8840 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -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>";
}