]> granicus.if.org Git - clang/commitdiff
Switch StmtVisitor from using dynamic to static dispatch. This makes it
authorChris Lattner <sabre@nondot.org>
Tue, 21 Aug 2007 04:04:25 +0000 (04:04 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 21 Aug 2007 04:04:25 +0000 (04:04 +0000)
significantly faster and actually reduces the amount of code in the system.
This also allows for future visitor changes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41211 91177308-0d34-0410-b5e6-96231b3b80d8

AST/Stmt.cpp
AST/StmtDumper.cpp
AST/StmtPrinter.cpp
AST/StmtVisitor.cpp [deleted file]
clang.xcodeproj/project.pbxproj
include/clang/AST/Expr.h
include/clang/AST/ExprCXX.h
include/clang/AST/Stmt.h
include/clang/AST/StmtVisitor.h

index e43f03c404a92e4b56fda4c9891f491ebd524ded..d56a02641ae60bbbaadc9e5ef78cefb296254ce0 100644 (file)
 #include "clang/Lex/IdentifierTable.h"
 using namespace clang;
 
-// Implement all the AST node visit methods using the StmtNodes.def database.
-#define STMT(N, CLASS, PARENT) \
-void CLASS::visit(StmtVisitor &V) { return V.Visit##CLASS(this); }
-
-STMT(0, Stmt, )
-#include "clang/AST/StmtNodes.def"
-
 static struct StmtClassNameTable {
   int enumValue;
   const char *className;
index 7b0d7945f017f9b92a8480c905f7bd9187ba4f52..87d4e333b6bba9cafb0f5cf250e416811d74ad6a 100644 (file)
@@ -25,7 +25,7 @@ using namespace clang;
 //===----------------------------------------------------------------------===//
 
 namespace  {
-  class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor {
+  class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor<StmtDumper> {
     FILE *F;
     unsigned IndentLevel;
     
@@ -43,7 +43,7 @@ namespace  {
       
       ++IndentLevel;
       if (S) {
-        S->visit(*this);
+        Visit(S);
       } else {
         Indent();
         fprintf(F, "<<<NULL>>>\n");
@@ -78,9 +78,9 @@ namespace  {
       DumpType(Node->getType());
     }
     
-    virtual void VisitStmt(Stmt *Node);
+    void VisitStmt(Stmt *Node);
 #define STMT(N, CLASS, PARENT) \
-    virtual void Visit##CLASS(CLASS *Node);
+    void Visit##CLASS(CLASS *Node);
 #include "clang/AST/StmtNodes.def"
   };
 }
@@ -502,13 +502,13 @@ void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
 /// This is useful in a debugger.
 void Stmt::dump() const {
   StmtDumper P(stderr, 4);
-  const_cast<Stmt*>(this)->visit(P);
+  P.Visit(const_cast<Stmt*>(this));
   fprintf(stderr, "\n");
 }
 
 /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
 void Stmt::dumpAll() const {
   StmtDumper P(stderr, ~0U);
-  const_cast<Stmt*>(this)->visit(P);
+  P.Visit(const_cast<Stmt*>(this));
   fprintf(stderr, "\n");
 }
index 67a6be8be6eb5eb6e36fde0ba922359f8022f6ca..6387f66301b74062ab875303454f0c3400bd8c93 100644 (file)
@@ -26,7 +26,7 @@ using namespace clang;
 //===----------------------------------------------------------------------===//
 
 namespace  {
-  class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor {
+  class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
     std::ostream &OS;
     unsigned IndentLevel;
   public:
@@ -37,10 +37,10 @@ namespace  {
       if (S && isa<Expr>(S)) {
         // If this is an expr used in a stmt context, indent and newline it.
         Indent();
-        S->visit(*this);
+        Visit(S);
         OS << ";\n";
       } else if (S) {
-        S->visit(*this);
+        Visit(S);
       } else {
         Indent() << "<<<NULL STATEMENT>>>\n";
       }
@@ -53,7 +53,7 @@ namespace  {
     
     void PrintExpr(Expr *E) {
       if (E)
-        E->visit(*this);
+        Visit(E);
       else
         OS << "<null expr>";
     }
@@ -64,9 +64,9 @@ namespace  {
       return OS;
     }
     
-    virtual void VisitStmt(Stmt *Node);
+    void VisitStmt(Stmt *Node);
 #define STMT(N, CLASS, PARENT) \
-    virtual void Visit##CLASS(CLASS *Node);
+    void Visit##CLASS(CLASS *Node);
 #include "clang/AST/StmtNodes.def"
   };
 }
@@ -528,5 +528,5 @@ void Stmt::printPretty(std::ostream &OS) const {
   }
 
   StmtPrinter P(OS);
-  const_cast<Stmt*>(this)->visit(P);
+  P.Visit(const_cast<Stmt*>(this));
 }
diff --git a/AST/StmtVisitor.cpp b/AST/StmtVisitor.cpp
deleted file mode 100644 (file)
index 9171ef7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-//===--- StmtVisitor.cpp - Visitor for Stmt subclasses --------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the StmtVisitor class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/ExprCXX.h"
-using namespace clang;
-
-StmtVisitor::~StmtVisitor() {
-  // Out-of-line virtual dtor.
-}
-
-// Implement all of the delegation visitor methods.
-#define STMT(N, FROM, TO) \
-  void StmtVisitor::Visit##FROM(FROM *Node) { Visit##TO(Node); }
-#include "clang/AST/StmtNodes.def"
-
index a372e33827875ef7d0d9d1850ec37fea75b08324..a16f098162411d7f262c6c3515157c9ce0270617 100644 (file)
@@ -32,7 +32,6 @@
                DE3452410AEF1A2D00DBC861 /* Stmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3452400AEF1A2D00DBC861 /* Stmt.cpp */; };
                DE3452810AEF1B1800DBC861 /* Stmt.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3452800AEF1B1800DBC861 /* Stmt.h */; };
                DE345C1A0AFC658B00DBC861 /* StmtVisitor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE345C190AFC658B00DBC861 /* StmtVisitor.h */; };
-               DE345C570AFC69E800DBC861 /* StmtVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE345C560AFC69E800DBC861 /* StmtVisitor.cpp */; };
                DE345F220AFD347900DBC861 /* StmtNodes.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE345F210AFD347900DBC861 /* StmtNodes.def */; };
                DE3460000AFDCC1900DBC861 /* ParseObjc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */; };
                DE3460050AFDCC6500DBC861 /* ParseInit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3460040AFDCC6500DBC861 /* ParseInit.cpp */; };
                DE3452400AEF1A2D00DBC861 /* Stmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Stmt.cpp; path = AST/Stmt.cpp; sourceTree = "<group>"; };
                DE3452800AEF1B1800DBC861 /* Stmt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Stmt.h; path = clang/AST/Stmt.h; sourceTree = "<group>"; };
                DE345C190AFC658B00DBC861 /* StmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = StmtVisitor.h; path = clang/AST/StmtVisitor.h; sourceTree = "<group>"; };
-               DE345C560AFC69E800DBC861 /* StmtVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StmtVisitor.cpp; path = AST/StmtVisitor.cpp; sourceTree = "<group>"; };
                DE345F210AFD347900DBC861 /* StmtNodes.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = StmtNodes.def; path = clang/AST/StmtNodes.def; sourceTree = "<group>"; };
                DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseObjc.cpp; path = Parse/ParseObjc.cpp; sourceTree = "<group>"; };
                DE3460040AFDCC6500DBC861 /* ParseInit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseInit.cpp; path = Parse/ParseInit.cpp; sourceTree = "<group>"; };
                                DE75EDF00B06880E0020CF81 /* Type.cpp */,
                                DEF2EDA60C6A4252000C4259 /* StmtDumper.cpp */,
                                DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */,
-                               DE345C560AFC69E800DBC861 /* StmtVisitor.cpp */,
                        );
                        name = AST;
                        sourceTree = "<group>";
                08FB7793FE84155DC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
-                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
                        projectDirPath = "";
                                DE344B540AE5E46C00DBC861 /* HeaderSearch.cpp in Sources */,
                                DE3451580AEC176100DBC861 /* MacroExpander.cpp in Sources */,
                                DE3452410AEF1A2D00DBC861 /* Stmt.cpp in Sources */,
-                               DE345C570AFC69E800DBC861 /* StmtVisitor.cpp in Sources */,
                                DE3460000AFDCC1900DBC861 /* ParseObjc.cpp in Sources */,
                                DE3460050AFDCC6500DBC861 /* ParseInit.cpp in Sources */,
                                DE34600B0AFDCCBF00DBC861 /* ParseStmt.cpp in Sources */,
index 4314ceb6af4ff0698202816a1d2adbc9186dba76..2397c58b348f4f3d69dec4e77ab0fa1fc0b7ed98 100644 (file)
@@ -103,7 +103,6 @@ public:
     return isIntegerConstantExpr(X, Ctx, Loc);
   }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() >= firstExprConstant &&
            T->getStmtClass() <= lastExprConstant; 
@@ -129,7 +128,6 @@ public:
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
   
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == DeclRefExprClass; 
   }
@@ -156,7 +154,6 @@ public:
   
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == PreDefinedExprClass; 
   }
@@ -176,7 +173,6 @@ public:
   const llvm::APInt &getValue() const { return Value; }
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == IntegerLiteralClass; 
   }
@@ -197,7 +193,6 @@ public:
   
   unsigned getValue() const { return Value; }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CharacterLiteralClass; 
   }
@@ -215,7 +210,6 @@ public:
   
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == FloatingLiteralClass; 
   }
@@ -246,7 +240,6 @@ public:
   virtual SourceRange getSourceRange() const { 
     return SourceRange(firstTokLoc,lastTokLoc); 
   }
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == StringLiteralClass; 
   }
@@ -266,7 +259,6 @@ public:
   Expr *getSubExpr() { return Val; }
   SourceRange getSourceRange() const { return SourceRange(L, R); }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ParenExprClass; 
   }
@@ -329,7 +321,6 @@ public:
   }
   virtual SourceLocation getExprLoc() const { return Loc; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == UnaryOperatorClass; 
   }
@@ -354,7 +345,6 @@ public:
   SourceLocation getOperatorLoc() const { return OpLoc; }
   SourceRange getSourceRange() const { return SourceRange(OpLoc, RParenLoc); }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == SizeOfAlignOfTypeExprClass; 
   }
@@ -402,7 +392,6 @@ public:
   }
   virtual SourceLocation getExprLoc() const { return RBracketLoc; }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ArraySubscriptExprClass; 
   }
@@ -451,7 +440,6 @@ public:
     return SourceRange(Fn->getLocStart(), RParenLoc);
   }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CallExprClass; 
   }
@@ -479,7 +467,6 @@ public:
   }
   virtual SourceLocation getExprLoc() const { return MemberLoc; }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == MemberExprClass; 
   }
@@ -536,7 +523,6 @@ public:
   virtual SourceRange getSourceRange() const {
     return SourceRange(getBase()->getLocStart(), AccessorLoc);
   }
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == OCUVectorElementExprClass; 
   }
@@ -556,7 +542,6 @@ public:
   
   virtual SourceRange getSourceRange() const { return Init->getSourceRange(); }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CompoundLiteralExprClass; 
   }
@@ -578,7 +563,6 @@ public:
 
   virtual SourceRange getSourceRange() const { return Op->getSourceRange(); }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ImplicitCastExprClass; 
   }
@@ -601,7 +585,6 @@ public:
   virtual SourceRange getSourceRange() const {
     return SourceRange(Loc, getSubExpr()->getSourceRange().End());
   }
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CastExprClass; 
   }
@@ -660,7 +643,6 @@ public:
   bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
   bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == BinaryOperatorClass; 
   }
@@ -717,7 +699,6 @@ public:
   virtual SourceRange getSourceRange() const {
     return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd());
   }
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ConditionalOperatorClass; 
   }
@@ -739,7 +720,6 @@ public:
   
   LabelStmt *getLabel() const { return Label; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == AddrLabelExprClass; 
   }
@@ -764,7 +744,6 @@ public:
     return SourceRange(LParenLoc, RParenLoc);
   }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == StmtExprClass; 
   }
@@ -793,7 +772,6 @@ public:
   virtual SourceRange getSourceRange() const {
     return SourceRange(BuiltinLoc, RParenLoc);
   }
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == TypesCompatibleExprClass; 
   }
@@ -826,7 +804,6 @@ public:
   virtual SourceRange getSourceRange() const {
     return SourceRange(BuiltinLoc, RParenLoc);
   }
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == ChooseExprClass; 
   }
index 5a3508c46d0a24d5bcde7e08e13064a45a7aa2bb..8544b2d4fccf95be9e9b00bebbf0b658bae87458 100644 (file)
@@ -62,7 +62,6 @@ namespace clang {
     virtual SourceRange getSourceRange() const {
       return SourceRange(Loc, getSubExpr()->getSourceRange().End());
     }
-    virtual void visit(StmtVisitor &Visitor);
     static bool classof(const Stmt *T) { 
       return T->getStmtClass() == CXXCastExprClass;
     }
@@ -82,7 +81,6 @@ namespace clang {
 
     virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
       
-    virtual void visit(StmtVisitor &Visitor);
     static bool classof(const Stmt *T) { 
       return T->getStmtClass() == CXXBoolLiteralExprClass;
     }
index f9d0bb37211a4ab7626bedfc9c0f0da7f5b08faf..c2d46ab7816ffd2bcb7473b7d27cf1557e2ef59a 100644 (file)
@@ -22,7 +22,6 @@ namespace clang {
   class Expr;
   class Decl;
   class IdentifierInfo;
-  class StmtVisitor;
   class SwitchStmt;
   
 /// Stmt - This represents one statement.
@@ -66,9 +65,6 @@ public:
   void dumpPretty() const;
   void printPretty(std::ostream &OS) const;
   
-  // Implement visitor support.
-  virtual void visit(StmtVisitor &Visitor);
-
   // Implement isa<T> support.
   static bool classof(const Stmt *) { return true; }
 };
@@ -86,7 +82,6 @@ public:
   const Decl *getDecl() const { return TheDecl; }
   Decl *getDecl() { return TheDecl; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == DeclStmtClass; 
   }
@@ -102,7 +97,6 @@ public:
 
   SourceLocation getSemiLoc() const { return SemiLoc; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == NullStmtClass; 
   }
@@ -131,7 +125,6 @@ public:
   
   void push_back(Stmt *S) { Body.push_back(S); }
     
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CompoundStmtClass; 
   }
@@ -158,8 +151,6 @@ public:
     T->getStmtClass() == DefaultStmtClass;
   }
   static bool classof(const SwitchCase *) { return true; }
-
-  virtual void visit(StmtVisitor &Visitor) = 0;
 };
 
 class CaseStmt : public SwitchCase {
@@ -174,7 +165,6 @@ public:
   Expr *getRHS() { return RHSVal; }
   Stmt *getSubStmt() { return SubStmt; }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CaseStmtClass; 
   }
@@ -191,7 +181,6 @@ public:
   SourceLocation getDefaultLoc() const { return DefaultLoc; }
   Stmt *getSubStmt() { return SubStmt; }
 
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == DefaultStmtClass; 
   }
@@ -215,7 +204,6 @@ public:
   void setIdentLoc(SourceLocation L) { IdentLoc = L; }
   void setSubStmt(Stmt *SS) { SubStmt = SS; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == LabelStmtClass; 
   }
@@ -240,7 +228,6 @@ public:
   Stmt *getThen() { return Then; }
   Stmt *getElse() { return Else; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == IfStmtClass; 
   }
@@ -276,7 +263,6 @@ public:
     FirstCase = SC;
   }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == SwitchStmtClass; 
   }
@@ -298,7 +284,6 @@ public:
   Stmt *getBody() { return Body; }
   const Stmt *getBody() const { return Body; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == WhileStmtClass; 
   }
@@ -319,7 +304,6 @@ public:
   Expr *getCond() { return Cond; }
   const Expr *getCond() const { return Cond; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == DoStmtClass; 
   }
@@ -349,7 +333,6 @@ public:
   const Expr *getInc()  const { return Inc; }
   const Stmt *getBody() const { return Body; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ForStmtClass; 
   }
@@ -365,7 +348,6 @@ public:
   
   LabelStmt *getLabel() const { return Label; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == GotoStmtClass; 
   }
@@ -382,7 +364,6 @@ public:
   Expr *getTarget() { return Target; }
   const Expr *getTarget() const { return Target; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == IndirectGotoStmtClass; 
   }
@@ -395,7 +376,6 @@ public:
 class ContinueStmt : public Stmt {
 public:
   ContinueStmt() : Stmt(ContinueStmtClass) {}
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ContinueStmtClass; 
   }
@@ -407,7 +387,6 @@ public:
 class BreakStmt : public Stmt {
 public:
   BreakStmt() : Stmt(BreakStmtClass) {}
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == BreakStmtClass; 
   }
@@ -425,7 +404,6 @@ public:
   const Expr *getRetValue() const { return RetExpr; }
   Expr *getRetValue() { return RetExpr; }
   
-  virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ReturnStmtClass; 
   }
index 9422765e8c32e2fcd2a9782b42b0c180f5a8d0b4..346f331050ce60af5fa6fd03b1871ce527dd7d7d 100644 (file)
 #ifndef LLVM_CLANG_AST_STMTVISITOR_H
 #define LLVM_CLANG_AST_STMTVISITOR_H
 
+#include "clang/AST/ExprCXX.h"
+
 namespace clang {
-  class Stmt;
-  // Add prototypes for all AST node classes.
-#define STMT(N, CLASS, PARENT) \
-  class CLASS;
-#include "clang/AST/StmtNodes.def"
   
 /// 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>
 class StmtVisitor {
 public:
-  virtual ~StmtVisitor();
-  
-  virtual void VisitStmt(Stmt *Node) {}
+  void Visit(Stmt *S) {
+    // 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));
+#include "clang/AST/StmtNodes.def"
+    }
+  }
   
-  // Implement all the methods with the StmtNodes.def file.
-#define STMT(N, CLASS, PARENT) \
-  virtual void Visit##CLASS(CLASS *Node);
+  // 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)                                   \
+  void Visit ## CLASS(CLASS *Node) {                             \
+    return static_cast<ImplClass*>(this)->Visit ## PARENT(Node); \
+  }
 #include "clang/AST/StmtNodes.def"
+
+  // Base case, ignore it. :)
+  void VisitStmt(Stmt *Node) {}
 };
   
 }