From c5598cbc4c3f2fb515af7f142f78ff630bdb5c01 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 21 Aug 2007 04:04:25 +0000 Subject: [PATCH] Switch StmtVisitor from using dynamic to static dispatch. This makes it 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 | 7 ------- AST/StmtDumper.cpp | 12 ++++++------ AST/StmtPrinter.cpp | 14 +++++++------- AST/StmtVisitor.cpp | 26 ------------------------- clang.xcodeproj/project.pbxproj | 5 ----- include/clang/AST/Expr.h | 23 ---------------------- include/clang/AST/ExprCXX.h | 2 -- include/clang/AST/Stmt.h | 22 --------------------- include/clang/AST/StmtVisitor.h | 34 ++++++++++++++++++++++----------- 9 files changed, 36 insertions(+), 109 deletions(-) delete mode 100644 AST/StmtVisitor.cpp diff --git a/AST/Stmt.cpp b/AST/Stmt.cpp index e43f03c404..d56a02641a 100644 --- a/AST/Stmt.cpp +++ b/AST/Stmt.cpp @@ -17,13 +17,6 @@ #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; diff --git a/AST/StmtDumper.cpp b/AST/StmtDumper.cpp index 7b0d7945f0..87d4e333b6 100644 --- a/AST/StmtDumper.cpp +++ b/AST/StmtDumper.cpp @@ -25,7 +25,7 @@ using namespace clang; //===----------------------------------------------------------------------===// namespace { - class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor { + class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor { FILE *F; unsigned IndentLevel; @@ -43,7 +43,7 @@ namespace { ++IndentLevel; if (S) { - S->visit(*this); + Visit(S); } else { Indent(); fprintf(F, "<<>>\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(this)->visit(P); + P.Visit(const_cast(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(this)->visit(P); + P.Visit(const_cast(this)); fprintf(stderr, "\n"); } diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp index 67a6be8be6..6387f66301 100644 --- a/AST/StmtPrinter.cpp +++ b/AST/StmtPrinter.cpp @@ -26,7 +26,7 @@ using namespace clang; //===----------------------------------------------------------------------===// namespace { - class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor { + class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor { std::ostream &OS; unsigned IndentLevel; public: @@ -37,10 +37,10 @@ namespace { if (S && isa(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() << "<<>>\n"; } @@ -53,7 +53,7 @@ namespace { void PrintExpr(Expr *E) { if (E) - E->visit(*this); + Visit(E); else OS << ""; } @@ -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(this)->visit(P); + P.Visit(const_cast(this)); } diff --git a/AST/StmtVisitor.cpp b/AST/StmtVisitor.cpp deleted file mode 100644 index 9171ef7566..0000000000 --- a/AST/StmtVisitor.cpp +++ /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" - diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index a372e33827..a16f098162 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -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 */; }; @@ -221,7 +220,6 @@ DE3452400AEF1A2D00DBC861 /* Stmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Stmt.cpp; path = AST/Stmt.cpp; sourceTree = ""; }; DE3452800AEF1B1800DBC861 /* Stmt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Stmt.h; path = clang/AST/Stmt.h; sourceTree = ""; }; DE345C190AFC658B00DBC861 /* StmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = StmtVisitor.h; path = clang/AST/StmtVisitor.h; sourceTree = ""; }; - DE345C560AFC69E800DBC861 /* StmtVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StmtVisitor.cpp; path = AST/StmtVisitor.cpp; sourceTree = ""; }; DE345F210AFD347900DBC861 /* StmtNodes.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = StmtNodes.def; path = clang/AST/StmtNodes.def; sourceTree = ""; }; DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseObjc.cpp; path = Parse/ParseObjc.cpp; sourceTree = ""; }; DE3460040AFDCC6500DBC861 /* ParseInit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseInit.cpp; path = Parse/ParseInit.cpp; sourceTree = ""; }; @@ -504,7 +502,6 @@ DE75EDF00B06880E0020CF81 /* Type.cpp */, DEF2EDA60C6A4252000C4259 /* StmtDumper.cpp */, DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */, - DE345C560AFC69E800DBC861 /* StmtVisitor.cpp */, ); name = AST; sourceTree = ""; @@ -616,7 +613,6 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; - compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* clang */; projectDirPath = ""; @@ -654,7 +650,6 @@ 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 */, diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 4314ceb6af..2397c58b34 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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; } diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 5a3508c46d..8544b2d4fc 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -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; } diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index f9d0bb3721..c2d46ab781 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -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 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; } diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h index 9422765e8c..346f331050 100644 --- a/include/clang/AST/StmtVisitor.h +++ b/include/clang/AST/StmtVisitor.h @@ -14,25 +14,37 @@ #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 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(this)->Visit ## CLASS( \ + static_cast(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(this)->Visit ## PARENT(Node); \ + } #include "clang/AST/StmtNodes.def" + + // Base case, ignore it. :) + void VisitStmt(Stmt *Node) {} }; } -- 2.40.0