From 14f0d1a85a233947d7020263eddee8d52a2bbbec Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 30 Aug 2007 16:50:46 +0000 Subject: [PATCH] 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. llvm-svn: 41609 --- clang/AST/Stmt.cpp | 10 ++++-- clang/include/clang/AST/Stmt.h | 60 +++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/clang/AST/Stmt.cpp b/clang/AST/Stmt.cpp index e218eda7008d..17f59a48d0d4 100644 --- a/clang/AST/Stmt.cpp +++ b/clang/AST/Stmt.cpp @@ -97,9 +97,13 @@ Stmt::child_iterator NullStmt::child_end() { return NULL; } 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/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 6b0d58767cef..025be37b9506 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -199,10 +199,8 @@ class SwitchCase : public Stmt { // 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 @@ public: 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(lhs); + SubExprs[RHS] = reinterpret_cast(rhs); + } + + Expr *getLHS() { return reinterpret_cast(SubExprs[LHS]); } + Expr *getRHS() { return reinterpret_cast(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 {