[AST] Only store the needed data in SwitchStmt

Don't store the data for the init statement and condition variable
if not needed. This cuts the size of SwitchStmt by up to 2 pointers.
The order of the children is intentionally kept the same.

Also use the newly available space in the bit-fields of Stmt
to store the bit representing whether all enums have been covered
instead of using a PointerIntPair.

Differential Revision: https://reviews.llvm.org/D53714

Reviewed By: rjmccall

llvm-svn: 345510
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 1ad33c5..3c63fe1 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -240,13 +240,21 @@
 
 void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
   VisitStmt(S);
-  S->setInit(Record.readSubStmt());
-  S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
+
+  bool HasInit = Record.readInt();
+  bool HasVar = Record.readInt();
+  bool AllEnumCasesCovered = Record.readInt();
+  if (AllEnumCasesCovered)
+    S->setAllEnumCasesCovered();
+
   S->setCond(Record.readSubExpr());
   S->setBody(Record.readSubStmt());
+  if (HasInit)
+    S->setInit(Record.readSubStmt());
+  if (HasVar)
+    S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
+
   S->setSwitchLoc(ReadSourceLocation());
-  if (Record.readInt())
-    S->setAllEnumCasesCovered();
 
   SwitchCase *PrevSC = nullptr;
   for (auto E = Record.size(); Record.getIdx() != E; ) {
@@ -2310,7 +2318,10 @@
       break;
 
     case STMT_SWITCH:
-      S = new (Context) SwitchStmt(Empty);
+      S = SwitchStmt::CreateEmpty(
+          Context,
+          /* HasInit=*/Record[ASTStmtReader::NumStmtFields + 0],
+          /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1]);
       break;
 
     case STMT_WHILE:
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index e7f9f35..396cc1c 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -159,12 +159,22 @@
 
 void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
   VisitStmt(S);
-  Record.AddStmt(S->getInit());
-  Record.AddDeclRef(S->getConditionVariable());
+
+  bool HasInit = S->getInit() != nullptr;
+  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
+  Record.push_back(HasInit);
+  Record.push_back(HasVar);
+  Record.push_back(S->isAllEnumCasesCovered());
+
   Record.AddStmt(S->getCond());
   Record.AddStmt(S->getBody());
+  if (HasInit)
+    Record.AddStmt(S->getInit());
+  if (HasVar)
+    Record.AddDeclRef(S->getConditionVariable());
+
   Record.AddSourceLocation(S->getSwitchLoc());
-  Record.push_back(S->isAllEnumCasesCovered());
+
   for (SwitchCase *SC = S->getSwitchCaseList(); SC;
        SC = SC->getNextSwitchCase())
     Record.push_back(Writer.RecordSwitchCaseID(SC));