steveire updated this revision to Diff 177421.
steveire added a comment.

Update


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55491/new/

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,19 @@
   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);
+  }
+
+  ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
+}
+
 void TextNodeDumper::dumpPointer(const void *Ptr) {
   ColorScope Color(OS, ShowColors, AddressColor);
   OS << ' ' << Ptr;
@@ -1022,3 +1035,46 @@
   if (auto N = T->getNumExpansions())
     OS << " expansions " << *N;
 }
+
+void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &TA) {
+  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 &TA) {
+  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 &TA) {
+  OS << " expr";
+}
+
+void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
+  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;
@@ -328,6 +330,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);
+    }
   };
 }
 
@@ -534,51 +546,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,9 @@
     : public comments::ConstCommentVisitor<TextNodeDumper, void,
                                            const comments::FullComment *>,
       public ConstStmtVisitor<TextNodeDumper>,
-      public TypeVisitor<TextNodeDumper> {
+      public TypeVisitor<TextNodeDumper>,
+      public ConstTemplateArgumentVisitor<TextNodeDumper> {
+
   TextTreeStructure &TreeStructure;
   raw_ostream &OS;
   const bool ShowColors;
@@ -64,6 +67,9 @@
 
   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 +177,16 @@
   void VisitObjCInterfaceType(const ObjCInterfaceType *T);
   void VisitPackExpansionType(const PackExpansionType *T);
 
+  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);
+
 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

Reply via email to