On Sat, Jan 12, 2019 at 11:39 AM Stephen Kelly via cfe-commits <cfe-commits@lists.llvm.org> wrote: > > Author: steveire > Date: Sat Jan 12 08:35:37 2019 > New Revision: 351012 > > URL: http://llvm.org/viewvc/llvm-project?rev=351012&view=rev > Log: > Implement TemplateArgument dumping in terms of Visitor > > Summary: Split the output streaming from the traversal to other AST nodes.
Thanks for this! However, it looks like you missed some of the nits raised in the review -- comments below. > > Reviewers: aaron.ballman > > Subscribers: cfe-commits > > Differential Revision: https://reviews.llvm.org/D55491 > > Added: > cfe/trunk/include/clang/AST/TemplateArgumentVisitor.h > Modified: > cfe/trunk/include/clang/AST/TextNodeDumper.h > cfe/trunk/lib/AST/ASTDumper.cpp > cfe/trunk/lib/AST/TextNodeDumper.cpp > > Added: cfe/trunk/include/clang/AST/TemplateArgumentVisitor.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateArgumentVisitor.h?rev=351012&view=auto > ============================================================================== > --- cfe/trunk/include/clang/AST/TemplateArgumentVisitor.h (added) > +++ cfe/trunk/include/clang/AST/TemplateArgumentVisitor.h Sat Jan 12 08:35:37 > 2019 > @@ -0,0 +1,99 @@ > +//===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- C++ > -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file defines the TemplateArgumentVisitor interface. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H > +#define LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H > + > +#include "clang/AST/TemplateBase.h" > + > +namespace clang { > + > +namespace templateargumentvisitor { > + > +/// A simple visitor class that helps create template argument visitors. > +template <template <typename> class Ref, typename ImplClass, > + typename RetTy = void, typename... ParamTys> > +class Base { > +public: > +#define REF(CLASS) typename Ref<CLASS>::type > +#define DISPATCH(NAME) > \ > + case TemplateArgument::NAME: > \ > + return static_cast<ImplClass *>(this)->Visit##NAME##TemplateArgument( > \ > + TA, std::forward<ParamTys>(P)...) > + > + RetTy Visit(REF(TemplateArgument) TA, ParamTys... P) { > + switch (TA.getKind()) { > + DISPATCH(Null); > + DISPATCH(Type); > + DISPATCH(Declaration); > + DISPATCH(NullPtr); > + DISPATCH(Integral); > + DISPATCH(Template); > + DISPATCH(TemplateExpansion); > + DISPATCH(Expression); > + DISPATCH(Pack); > + } > + llvm_unreachable("TemplateArgument is not covered in switch!"); > + } > + > + // If the implementation chooses not to implement a certain visit > + // method, fall back to the parent. > + > +#define VISIT_METHOD(CATEGORY) > \ > + RetTy Visit##CATEGORY##TemplateArgument(REF(TemplateArgument) TA, > \ > + ParamTys... P) { > \ > + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); > \ > + } > + > + VISIT_METHOD(Null); > + VISIT_METHOD(Type); > + VISIT_METHOD(Declaration); > + VISIT_METHOD(NullPtr); > + VISIT_METHOD(Integral); > + VISIT_METHOD(Template); > + VISIT_METHOD(TemplateExpansion); > + VISIT_METHOD(Expression); > + VISIT_METHOD(Pack); > + > + RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) { > + return RetTy(); > + } > + > +#undef REF > +#undef DISPATCH > +#undef VISIT_METHOD > +}; > + > +} // namespace templateargumentvisitor > + > +/// A simple visitor class that helps create template argument visitors. > +/// > +/// This class does not preserve constness of TemplateArgument references > (see > +/// also ConstTemplateArgumentVisitor). > +template <typename ImplClass, typename RetTy = void, typename... ParamTys> > +class TemplateArgumentVisitor > + : public templateargumentvisitor::Base<std::add_lvalue_reference, > ImplClass, > + RetTy, ParamTys...> {}; > + > +/// A simple visitor class that helps create template argument visitors. > +/// > +/// This class preserves constness of TemplateArgument references (see also > +/// TemplateArgumentVisitor). > +template <typename ImplClass, typename RetTy = void, typename... ParamTys> > +class ConstTemplateArgumentVisitor > + : public templateargumentvisitor::Base<llvm::make_const_ref, ImplClass, > + RetTy, ParamTys...> {}; > + > +} // namespace clang > + > +#endif // LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H > > Modified: cfe/trunk/include/clang/AST/TextNodeDumper.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TextNodeDumper.h?rev=351012&r1=351011&r2=351012&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/TextNodeDumper.h (original) > +++ cfe/trunk/include/clang/AST/TextNodeDumper.h Sat Jan 12 08:35:37 2019 > @@ -20,6 +20,7 @@ > #include "clang/AST/CommentCommandTraits.h" > #include "clang/AST/CommentVisitor.h" > #include "clang/AST/ExprCXX.h" > +#include "clang/AST/TemplateArgumentVisitor.h" > > namespace clang { > > @@ -123,7 +124,8 @@ class TextNodeDumper > : public TextTreeStructure, > public comments::ConstCommentVisitor<TextNodeDumper, void, > const comments::FullComment *>, > - public ConstAttrVisitor<TextNodeDumper> { > + public ConstAttrVisitor<TextNodeDumper>, > + public ConstTemplateArgumentVisitor<TextNodeDumper> { > raw_ostream &OS; > const bool ShowColors; > > @@ -150,6 +152,9 @@ public: > > void Visit(const Attr *A); > > + void Visit(const TemplateArgument &TA, SourceRange R, > + const Decl *From = nullptr, StringRef Label = {}); > + > void dumpPointer(const void *Ptr); > void dumpLocation(SourceLocation Loc); > void dumpSourceRange(SourceRange R); > @@ -186,6 +191,16 @@ public: > > // Implements Visit methods for Attrs. > #include "clang/AST/AttrTextNodeDump.inc" > + > + void VisitNullTemplateArgument(const TemplateArgument &TA); > + void VisitTypeTemplateArgument(const TemplateArgument &TA); > + void VisitDeclarationTemplateArgument(const TemplateArgument &TA); > + void VisitNullPtrTemplateArgument(const TemplateArgument &TA); > + void VisitIntegralTemplateArgument(const TemplateArgument &TA); > + void VisitTemplateTemplateArgument(const TemplateArgument &TA); > + void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA); > + void VisitExpressionTemplateArgument(const TemplateArgument &TA); > + void VisitPackTemplateArgument(const TemplateArgument &TA); > }; > > } // namespace clang > > Modified: cfe/trunk/lib/AST/ASTDumper.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=351012&r1=351011&r2=351012&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ASTDumper.cpp (original) > +++ cfe/trunk/lib/AST/ASTDumper.cpp Sat Jan 12 08:35:37 2019 > @@ -24,6 +24,7 @@ > #include "clang/AST/DeclVisitor.h" > #include "clang/AST/LocInfoType.h" > #include "clang/AST/StmtVisitor.h" > +#include "clang/AST/TemplateArgumentVisitor.h" > #include "clang/AST/TextNodeDumper.h" > #include "clang/AST/TypeVisitor.h" > #include "clang/Basic/Builtins.h" > @@ -44,7 +45,8 @@ namespace { > public ConstStmtVisitor<ASTDumper>, > public ConstCommentVisitor<ASTDumper, void, const FullComment *>, > public TypeVisitor<ASTDumper>, > - public ConstAttrVisitor<ASTDumper> { > + public ConstAttrVisitor<ASTDumper>, > + public ConstTemplateArgumentVisitor<ASTDumper> { > > TextNodeDumper NodeDumper; > > @@ -440,6 +442,14 @@ namespace { > // Comments. > void dumpComment(const Comment *C, const FullComment *FC); > > + void VisitExpressionTemplateArgument(const TemplateArgument &TA) { > + dumpStmt(TA.getAsExpr()); > + } > + void VisitPackTemplateArgument(const TemplateArgument &TA) { > + for (const auto& TArg : TA.pack_elements()) Good on changing to a range-based for loop, but the formatting is incorrect here. > + dumpTemplateArgument(TArg); > + } > + > // Implements Visit methods for Attrs. > #include "clang/AST/AttrNodeTraverse.inc" > }; > @@ -670,49 +680,8 @@ void ASTDumper::dumpTemplateArgumentList > void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange > R, > const Decl *From, const char *Label) { > dumpChild([=] { > - OS << "TemplateArgument"; > - if (R.isValid()) > - NodeDumper.dumpSourceRange(R); > - > - if (From) > - NodeDumper.dumpDeclRef(From, Label); > - > - switch (A.getKind()) { > - case TemplateArgument::Null: > - OS << " null"; > - break; > - case TemplateArgument::Type: > - OS << " type"; > - NodeDumper.dumpType(A.getAsType()); > - break; > - case TemplateArgument::Declaration: > - OS << " decl"; > - NodeDumper.dumpDeclRef(A.getAsDecl()); > - break; > - case TemplateArgument::NullPtr: > - OS << " nullptr"; > - break; > - case TemplateArgument::Integral: > - OS << " integral " << A.getAsIntegral(); > - break; > - case TemplateArgument::Template: > - OS << " template "; > - A.getAsTemplate().dump(OS); > - break; > - case TemplateArgument::TemplateExpansion: > - OS << " template expansion "; > - A.getAsTemplateOrTemplatePattern().dump(OS); > - break; > - case TemplateArgument::Expression: > - OS << " expr"; > - dumpStmt(A.getAsExpr()); > - break; > - case TemplateArgument::Pack: > - OS << " pack"; > - for (const auto& TArg : A.pack_elements()) > - dumpTemplateArgument(TArg); > - break; > - } > + NodeDumper.Visit(A, R, From, Label); > + ConstTemplateArgumentVisitor<ASTDumper>::Visit(A); > }); > } > > > Modified: cfe/trunk/lib/AST/TextNodeDumper.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TextNodeDumper.cpp?rev=351012&r1=351011&r2=351012&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/TextNodeDumper.cpp (original) > +++ cfe/trunk/lib/AST/TextNodeDumper.cpp Sat Jan 12 08:35:37 2019 > @@ -64,6 +64,19 @@ void TextNodeDumper::Visit(const Attr *A > ConstAttrVisitor<TextNodeDumper>::Visit(A); > } > > +void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R, > + const Decl *From, StringRef Label) { > + OS << "TemplateArgument"; > + if (R.isValid()) > + dumpSourceRange(R); > + > + if (From) { These braces should be elided. ~Aaron > + dumpDeclRef(From, Label); > + } > + > + ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA); > +} > + > void TextNodeDumper::dumpPointer(const void *Ptr) { > ColorScope Color(OS, ShowColors, AddressColor); > OS << ' ' << Ptr; > @@ -317,3 +330,45 @@ void TextNodeDumper::visitVerbatimLineCo > const comments::VerbatimLineComment *C, const comments::FullComment *) { > OS << " Text=\"" << C->getText() << "\""; > } > + > +void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) { > + OS << " null"; > +} > + > +void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) { > + OS << " type"; > + dumpType(TA.getAsType()); > +} > + > +void TextNodeDumper::VisitDeclarationTemplateArgument( > + const TemplateArgument &TA) { > + OS << " decl"; > + dumpDeclRef(TA.getAsDecl()); > +} > + > +void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) { > + OS << " nullptr"; > +} > + > +void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument > &TA) { > + OS << " integral " << TA.getAsIntegral(); > +} > + > +void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument > &TA) { > + OS << " template "; > + TA.getAsTemplate().dump(OS); > +} > + > +void TextNodeDumper::VisitTemplateExpansionTemplateArgument( > + const TemplateArgument &TA) { > + OS << " template expansion "; > + TA.getAsTemplateOrTemplatePattern().dump(OS); > +} > + > +void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument > &) { > + OS << " expr"; > +} > + > +void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) { > + OS << " pack"; > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits