зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
9c03356918
Коммит
03d6fb9922
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче