Implement the GNU __null extension

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60235 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 7a8119c..3c021c2 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1031,8 +1031,11 @@
                = dyn_cast<CXXDefaultArgExpr>(this)) {
     // See through default argument expressions
     return DefaultArg->getExpr()->isNullPointerConstant(Ctx);
+  } else if (isa<GNUNullExpr>(this)) {
+    // The GNU __null extension is always a null pointer constant.
+    return true;
   }
-  
+
   // This expression must be an integer type.
   if (!getType()->isIntegerType())
     return false;
@@ -1383,6 +1386,10 @@
 Stmt::child_iterator ChooseExpr::child_begin() { return &SubExprs[0]; }
 Stmt::child_iterator ChooseExpr::child_end() { return &SubExprs[0]+END_EXPR; }
 
+// GNUNullExpr
+Stmt::child_iterator GNUNullExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator GNUNullExpr::child_end() { return child_iterator(); }
+
 // OverloadExpr
 Stmt::child_iterator OverloadExpr::child_begin() { return &SubExprs[0]; }
 Stmt::child_iterator OverloadExpr::child_end() { return &SubExprs[0]+NumExprs; }
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index fcebdab..b6f0707 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -783,6 +783,10 @@
   OS << ")";
 }
 
+void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
+  OS << "__null";
+}
+
 void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
   OS << "__builtin_overload(";
   for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp
index 8bf7039..3cf1f54 100644
--- a/lib/AST/StmtSerialization.cpp
+++ b/lib/AST/StmtSerialization.cpp
@@ -61,6 +61,9 @@
     case CharacterLiteralClass:
       return CharacterLiteral::CreateImpl(D, C);
       
+    case ChooseExprClass:
+      return ChooseExpr::CreateImpl(D, C);
+
     case CompoundAssignOperatorClass:
       return CompoundAssignOperator::CreateImpl(D, C);
       
@@ -94,6 +97,9 @@
     case ForStmtClass:
       return ForStmt::CreateImpl(D, C);
     
+    case GNUNullExprClass:
+      return GNUNullExpr::CreateImpl(D, C);
+
     case GotoStmtClass:
       return GotoStmt::CreateImpl(D, C);
       
@@ -904,6 +910,17 @@
   return CE;
 }
 
+void GNUNullExpr::EmitImpl(llvm::Serializer &S) const {
+  S.Emit(getType());
+  S.Emit(TokenLoc);
+}
+
+GNUNullExpr *GNUNullExpr::CreateImpl(llvm::Deserializer &D, ASTContext &C) {
+  QualType T = QualType::ReadVal(D);
+  SourceLocation TL = SourceLocation::ReadVal(D);
+  return new GNUNullExpr(T, TL);
+}
+
 void OverloadExpr::EmitImpl(llvm::Serializer& S) const {
   S.Emit(getType());
   S.Emit(BuiltinLoc);