Add the ability to visit binary operators without having to

match on binop then explicitly switching again.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41214 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-08-21 04:43:17 +00:00
Родитель 9c03356918
Коммит 03d6fb9922
3 изменённых файлов: 97 добавлений и 18 удалений

Просмотреть файл

@ -89,7 +89,7 @@ public:
// case Expr::CastExprClass:
// case Expr::CallExprClass:
void VisitBinaryOperator(const BinaryOperator *BO);
void VisitBinaryAssign(const BinaryOperator *E);
void VisitBinAssign(const BinaryOperator *E);
void VisitConditionalOperator(const ConditionalOperator *CO);
@ -128,12 +128,12 @@ void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
}
void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
fprintf(stderr, "Unimplemented aggregate binary expr!\n");
E->dump();
#if 0
switch (E->getOpcode()) {
default:
fprintf(stderr, "Unimplemented aggregate binary expr!\n");
E->dump();
return;
#if 0
case BinaryOperator::Mul:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
@ -183,10 +183,6 @@ void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitOr(LHS, RHS, E->getType());
#endif
case BinaryOperator::Assign: return VisitBinaryAssign(E);
#if 0
case BinaryOperator::MulAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
@ -258,11 +254,11 @@ void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::Comma: return EmitBinaryComma(E);
#endif
}
#endif
}
void AggExprEmitter::VisitBinaryAssign(const BinaryOperator *E) {
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
assert(E->getLHS()->getType().getCanonicalType() ==
E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
LValue LHS = CGF.EmitLValue(E->getLHS());

Просмотреть файл

@ -595,6 +595,7 @@ class BinaryOperator : public Expr {
public:
enum Opcode {
// Operators listed in order of precedence.
// Note that additions to this should also update the StmtVisitor class.
Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators.
Add, Sub, // [C99 6.5.6] Additive operators.
Shl, Shr, // [C99 6.5.7] Bitwise shift operators.

Просмотреть файл

@ -18,19 +18,52 @@
namespace clang {
#define DISPATCH(NAME, CLASS) \
return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<CLASS*>(S))
/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
template<typename ImplClass, typename RetTy=void>
class StmtVisitor {
public:
RetTy Visit(Stmt *S) {
// If we have a binary expr, dispatch to the subcode of the binop. A smart
// optimizer (e.g. LLVM) will fold this comparison into the switch stmt
// below.
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
default: assert(0 && "Unknown binary operator!");
case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator);
case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator);
case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator);
case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator);
case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator);
case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator);
case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator);
case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator);
case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator);
case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator);
case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator);
case BinaryOperator::MulAssign: DISPATCH(BinMulAssign, BinaryOperator);
case BinaryOperator::DivAssign: DISPATCH(BinDivAssign, BinaryOperator);
case BinaryOperator::RemAssign: DISPATCH(BinRemAssign, BinaryOperator);
case BinaryOperator::AddAssign: DISPATCH(BinAddAssign, BinaryOperator);
case BinaryOperator::SubAssign: DISPATCH(BinSubAssign, BinaryOperator);
case BinaryOperator::ShlAssign: DISPATCH(BinShlAssign, BinaryOperator);
case BinaryOperator::ShrAssign: DISPATCH(BinShrAssign, BinaryOperator);
case BinaryOperator::AndAssign: DISPATCH(BinAndAssign, BinaryOperator);
case BinaryOperator::OrAssign: DISPATCH(BinOrAssign, BinaryOperator);
case BinaryOperator::XorAssign: DISPATCH(BinXorAssign, BinaryOperator);
case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator);
}
}
// Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
switch (S->getStmtClass()) {
default: assert(0 && "Unknown stmt kind!");
#define STMT(N, CLASS, PARENT) \
case Stmt::CLASS ## Class: \
return static_cast<ImplClass*>(this)->Visit ## CLASS( \
static_cast<CLASS*>(S));
case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
#include "clang/AST/StmtNodes.def"
}
}
@ -38,15 +71,64 @@ public:
// If the implementation chooses not to implement a certain visit method, fall
// back on VisitExpr or whatever else is the superclass.
#define STMT(N, CLASS, PARENT) \
RetTy Visit ## CLASS(CLASS *Node) { \
return static_cast<ImplClass*>(this)->Visit ## PARENT(Node); \
}
RetTy Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT); }
#include "clang/AST/StmtNodes.def"
// If the implementation doesn't implement binary operator methods, fall back
// on VisitBinaryOperator.
RetTy VisitBinMul(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinDiv(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinRem(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinAdd(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinSub(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinShl(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinShr(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinAnd(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinXor(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinOr(BinaryOperator *S){DISPATCH(BinaryOperator,BinaryOperator);}
RetTy VisitBinAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinMulAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinDivAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinRemAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinAddAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinSubAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinShlAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinShrAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinAndAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinOrAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinXorAssign(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
RetTy VisitBinComma(BinaryOperator *S) {
DISPATCH(BinaryOperator,BinaryOperator);
}
// Base case, ignore it. :)
RetTy VisitStmt(Stmt *Node) { return RetTy(); }
};
}
#undef DISPATCH
} // end namespace clang
#endif