[cfe-commits] r41214 - in /cfe/trunk: CodeGen/CGAggExpr.cpp include/clang/AST/Expr.h include/clang/AST/StmtVisitor.h

Chris Lattner sabre at nondot.org
Mon Aug 20 21:43:17 PDT 2007


Author: lattner
Date: Mon Aug 20 23:43:17 2007
New Revision: 41214

URL: http://llvm.org/viewvc/llvm-project?rev=41214&view=rev
Log:
Add the ability to visit binary operators without having to
match on binop then explicitly switching again.

Modified:
    cfe/trunk/CodeGen/CGAggExpr.cpp
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/StmtVisitor.h

Modified: cfe/trunk/CodeGen/CGAggExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGAggExpr.cpp?rev=41214&r1=41213&r2=41214&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGAggExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGAggExpr.cpp Mon Aug 20 23:43:17 2007
@@ -89,7 +89,7 @@
   //  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::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 @@
     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 @@
     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());

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=41214&r1=41213&r2=41214&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Aug 20 23:43:17 2007
@@ -595,6 +595,7 @@
 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.

Modified: cfe/trunk/include/clang/AST/StmtVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtVisitor.h?rev=41214&r1=41213&r2=41214&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtVisitor.h (original)
+++ cfe/trunk/include/clang/AST/StmtVisitor.h Mon Aug 20 23:43:17 2007
@@ -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 @@
   // 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





More information about the cfe-commits mailing list