Fixed bug for CaseStmt where the child_begin/child_end methods were not
including the expressions in the case statement itself (not the body of
the case).

This required moving SubStmt out of SwitchCase into CaseStmt and DefaultStmt
respectively.  getSubStmt() now is a virtual call for SwitchCase, but is
a direct (static) call for CaseStmt and DefaultStmt.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41609 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/Stmt.cpp b/AST/Stmt.cpp
index e218eda..17f59a4 100644
--- a/AST/Stmt.cpp
+++ b/AST/Stmt.cpp
@@ -97,9 +97,13 @@
 Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
 Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+Body.size(); }
 
-// SwitchCase
-Stmt::child_iterator SwitchCase::child_begin() { return &SubStmt; }
-Stmt::child_iterator SwitchCase::child_end() { return &SubStmt+1; }
+// CaseStmt
+Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
+Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; }
+
+// DefaultStmt
+Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; }
+Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; }
 
 // LabelStmt
 Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 6b0d587..025be37 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -199,10 +199,8 @@
   // A pointer to the following CaseStmt or DefaultStmt class,
   // used by SwitchStmt.
   SwitchCase *NextSwitchCase;
-  Stmt *SubStmt;
 protected:
-  SwitchCase(StmtClass SC, Stmt* substmt) : Stmt(SC), NextSwitchCase(0),
-                                            SubStmt(substmt) {}
+  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
   
 public:
   const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
@@ -210,48 +208,64 @@
   SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
 
   void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
-  
-  Stmt *getSubStmt() { return SubStmt; }
+
+  virtual Stmt* v_getSubStmt() = 0;  
+  Stmt *getSubStmt() { return v_getSubStmt(); }
   
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CaseStmtClass || 
     T->getStmtClass() == DefaultStmtClass;
   }
   static bool classof(const SwitchCase *) { return true; }
+};
+
+class CaseStmt : public SwitchCase {
+  enum { SUBSTMT, LHS, RHS, END_EXPR };
+  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for 
+                             // GNU "case 1 ... 4" extension
+public:
+  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt) 
+    : SwitchCase(CaseStmtClass) {
+    SubExprs[SUBSTMT] = substmt;
+    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
+    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
+  }
+  
+  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
+  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
+  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
+  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
+
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == CaseStmtClass; 
+  }
+  static bool classof(const CaseStmt *) { return true; }
   
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
 };
 
-class CaseStmt : public SwitchCase {
-  Expr *LHSVal;
-  Expr *RHSVal;  // Non-null for GNU "case 1 ... 4" extension
-public:
-  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt) 
-    : SwitchCase(CaseStmtClass,substmt), LHSVal(lhs), RHSVal(rhs) {}
-  
-  Expr *getLHS() { return LHSVal; }
-  Expr *getRHS() { return RHSVal; }
-
-  static bool classof(const Stmt *T) { 
-    return T->getStmtClass() == CaseStmtClass; 
-  }
-  static bool classof(const CaseStmt *) { return true; }
-};
-
 class DefaultStmt : public SwitchCase {
+  Stmt* SubStmt;
   SourceLocation DefaultLoc;
 public:
   DefaultStmt(SourceLocation DL, Stmt *substmt) : 
-    SwitchCase(DefaultStmtClass,substmt), DefaultLoc(DL) {}
-  
+    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
+
+  Stmt *getSubStmt() { return SubStmt; }
+  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
+    
   SourceLocation getDefaultLoc() const { return DefaultLoc; }
 
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == DefaultStmtClass; 
   }
   static bool classof(const DefaultStmt *) { return true; }
+  
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
 };
 
 class LabelStmt : public Stmt {