steveire created this revision. steveire added a reviewer: aaron.ballman. Herald added a subscriber: cfe-commits.
Split the output streaming from the traversal to other AST nodes. Repository: rC Clang https://reviews.llvm.org/D55491 Files: include/clang/AST/TemplateArgumentVisitor.h include/clang/AST/TextNodeDumper.h lib/AST/ASTDumper.cpp lib/AST/TextNodeDumper.cpp
Index: lib/AST/TextNodeDumper.cpp =================================================================== --- lib/AST/TextNodeDumper.cpp +++ lib/AST/TextNodeDumper.cpp @@ -161,6 +161,18 @@ OS << " " << T.split().Quals.getAsString(); } +void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R, const Decl* From, const char* label) { + OS << "TemplateArgument"; + if (R.isValid()) + dumpSourceRange(R); + + if (From) { + dumpDeclRef(From, label); + } + + TemplateArgumentVisitorType::Visit(TA, R); +} + void TextNodeDumper::dumpPointer(const void *Ptr) { ColorScope Color(OS, ShowColors, AddressColor); OS << ' ' << Ptr; @@ -1022,3 +1034,52 @@ if (auto N = T->getNumExpansions()) OS << " expansions " << *N; } + +void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &TA, + SourceRange) { + OS << " null"; +} + +void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA, + SourceRange) { + OS << " type"; + dumpType(TA.getAsType()); +} + +void TextNodeDumper::VisitDeclarationTemplateArgument( + const TemplateArgument &TA, SourceRange) { + OS << " decl"; + dumpDeclRef(TA.getAsDecl()); +} + +void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA, + SourceRange) { + OS << " nullptr"; +} + +void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA, + SourceRange) { + OS << " integral " << TA.getAsIntegral(); +} + +void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA, + SourceRange) { + OS << " template "; + TA.getAsTemplate().dump(OS); +} + +void TextNodeDumper::VisitTemplateExpansionTemplateArgument( + const TemplateArgument &TA, SourceRange) { + OS << " template expansion "; + TA.getAsTemplateOrTemplatePattern().dump(OS); +} + +void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &TA, + SourceRange) { + OS << " expr"; +} + +void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA, + SourceRange) { + OS << " pack"; +} Index: lib/AST/ASTDumper.cpp =================================================================== --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -23,6 +23,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" @@ -42,7 +43,8 @@ : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>, public ConstCommentVisitor<ASTDumper, void, const FullComment *>, - public TypeVisitor<ASTDumper> { + public TypeVisitor<ASTDumper>, + public ConstTemplateArgumentVisitor<ASTDumper> { TextTreeStructure TreeStructure; TextNodeDumper NodeDumper; @@ -327,6 +329,16 @@ // Comments. void dumpComment(const Comment *C, const FullComment *FC); + + void VisitExpressionTemplateArgument(const TemplateArgument &TA) { + dumpStmt(TA.getAsExpr()); + } + void VisitPackTemplateArgument(const TemplateArgument &TA) { + for (TemplateArgument::pack_iterator I = TA.pack_begin(), + E = TA.pack_end(); + I != E; ++I) + dumpTemplateArgument(*I); + } }; } @@ -533,51 +545,8 @@ 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 (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); - I != E; ++I) - dumpTemplateArgument(*I); - break; - } + NodeDumper.Visit(A, R, From, label); + ConstTemplateArgumentVisitor<ASTDumper>::Visit(A); }); } Index: include/clang/AST/TextNodeDumper.h =================================================================== --- include/clang/AST/TextNodeDumper.h +++ include/clang/AST/TextNodeDumper.h @@ -20,6 +20,7 @@ #include "clang/AST/CommentVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtVisitor.h" +#include "clang/AST/TemplateArgumentVisitor.h" #include "clang/AST/TypeVisitor.h" namespace clang { @@ -28,7 +29,12 @@ : public comments::ConstCommentVisitor<TextNodeDumper, void, const comments::FullComment *>, public ConstStmtVisitor<TextNodeDumper>, - public TypeVisitor<TextNodeDumper> { + public TypeVisitor<TextNodeDumper>, + public ConstTemplateArgumentVisitor<TextNodeDumper, void, SourceRange> { + + using TemplateArgumentVisitorType = + ConstTemplateArgumentVisitor<TextNodeDumper, void, SourceRange>; + TextTreeStructure &TreeStructure; raw_ostream &OS; const bool ShowColors; @@ -64,6 +70,8 @@ void Visit(QualType T); + void Visit(const TemplateArgument &TA, SourceRange R, const Decl* From = nullptr, const char* label = nullptr); + void dumpPointer(const void *Ptr); void dumpLocation(SourceLocation Loc); void dumpSourceRange(SourceRange R); @@ -171,6 +179,19 @@ void VisitObjCInterfaceType(const ObjCInterfaceType *T); void VisitPackExpansionType(const PackExpansionType *T); + void VisitNullTemplateArgument(const TemplateArgument &TA, SourceRange R); + void VisitTypeTemplateArgument(const TemplateArgument &TA, SourceRange R); + void VisitDeclarationTemplateArgument(const TemplateArgument &TA, + SourceRange R); + void VisitNullPtrTemplateArgument(const TemplateArgument &TA, SourceRange R); + void VisitIntegralTemplateArgument(const TemplateArgument &TA, SourceRange R); + void VisitTemplateTemplateArgument(const TemplateArgument &TA, SourceRange R); + void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA, + SourceRange R); + void VisitExpressionTemplateArgument(const TemplateArgument &TA, + SourceRange R); + void VisitPackTemplateArgument(const TemplateArgument &TA, SourceRange R); + private: void dumpCXXTemporary(const CXXTemporary *Temporary); }; Index: include/clang/AST/TemplateArgumentVisitor.h =================================================================== --- /dev/null +++ include/clang/AST/TemplateArgumentVisitor.h @@ -0,0 +1,117 @@ +//===- 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 { + +template <typename T> struct make_ref { using type = T &; }; +template <typename T> struct make_const_ref { using type = const T &; }; + +/// A simple visitor class that helps create template argument visitors. +template <template <typename> class Ref, typename ImplClass, + typename RetTy = void, class... 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. + + RetTy VisitNullTemplateArgument(REF(TemplateArgument) TA, ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + RetTy VisitTypeTemplateArgument(REF(TemplateArgument) TA, ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + RetTy VisitDeclarationTemplateArgument(REF(TemplateArgument) TA, + ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + RetTy VisitNullPtrTemplateArgument(REF(TemplateArgument) TA, ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + RetTy VisitIntegralTemplateArgument(REF(TemplateArgument) TA, ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + RetTy VisitTemplateTemplateArgument(REF(TemplateArgument) TA, ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + RetTy VisitTemplateExpansionTemplateArgument(REF(TemplateArgument) TA, + ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + RetTy VisitExpressionTemplateArgument(REF(TemplateArgument) TA, + ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + RetTy VisitPackTemplateArgument(REF(TemplateArgument) TA, ParamTys... P) { + return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); + } + + RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) { + return RetTy(); + } + +#undef REF +#undef DISPATCH +}; + +} // 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<templateargumentvisitor::make_ref, + 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< + templateargumentvisitor::make_const_ref, ImplClass, RetTy, + ParamTys...> {}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits