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
This commit is contained in:
Ted Kremenek 2007-08-30 16:50:46 +00:00
parent ffb806cf0e
commit 14f0d1a85a
2 changed files with 44 additions and 26 deletions

View File

@ -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; }

View File

@ -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<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 {