r352989 - [AST] Extract ASTNodeTraverser class from ASTDumper

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 3 06:06:54 PST 2019


Author: steveire
Date: Sun Feb  3 06:06:54 2019
New Revision: 352989

URL: http://llvm.org/viewvc/llvm-project?rev=352989&view=rev
Log:
[AST] Extract ASTNodeTraverser class from ASTDumper

Summary:
This new traverser class allows clients to re-use the traversal logic
which was previously part of ASTDumper.  This means that alternative
visit logic may be implemented, such as

* Dump to alternative data formats such as JSON
* Implement AST Matcher parent/child visitation matching AST dumps

Reviewers: aaron.ballman

Subscribers: jfb, cfe-commits

Differential Revision: https://reviews.llvm.org/D57472

Added:
    cfe/trunk/include/clang/AST/ASTNodeTraverser.h
Modified:
    cfe/trunk/lib/AST/ASTDumper.cpp

Added: cfe/trunk/include/clang/AST/ASTNodeTraverser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=352989&view=auto
==============================================================================
--- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (added)
+++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Sun Feb  3 06:06:54 2019
@@ -0,0 +1,621 @@
+//===--- ASTNodeTraverser.h - Traversal of AST nodes ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the AST traversal facilities.  Other users
+// of this class may make use of the same traversal logic by inheriting it,
+// similar to RecursiveASTVisitor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H
+#define LLVM_CLANG_AST_ASTNODETRAVERSER_H
+
+#include "clang/AST/AttrVisitor.h"
+#include "clang/AST/CommentVisitor.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/LocInfoType.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/TypeVisitor.h"
+
+namespace clang {
+
+/**
+
+ASTNodeTraverser traverses the Clang AST for dumping purposes.
+
+The `Derived::doGetNodeDelegate()` method is required to be an accessible member
+which returns a reference of type `NodeDelegateType &` which implements the
+following interface:
+
+struct {
+  template <typename Fn> void AddChild(Fn DoAddChild);
+  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild);
+
+  void Visit(const comments::Comment *C, const comments::FullComment *FC);
+  void Visit(const Attr *A);
+  void Visit(const TemplateArgument &TA, SourceRange R = {},
+             const Decl *From = nullptr, StringRef Label = {});
+  void Visit(const Stmt *Node);
+  void Visit(const Type *T);
+  void Visit(QualType T);
+  void Visit(const Decl *D);
+  void Visit(const CXXCtorInitializer *Init);
+  void Visit(const OMPClause *C);
+  void Visit(const BlockDecl::Capture &C);
+  void Visit(const GenericSelectionExpr::ConstAssociation &A);
+};
+*/
+template <typename Derived, typename NodeDelegateType>
+class ASTNodeTraverser
+    : public ConstDeclVisitor<Derived>,
+      public ConstStmtVisitor<Derived>,
+      public comments::ConstCommentVisitor<Derived, void,
+                                           const comments::FullComment *>,
+      public TypeVisitor<Derived>,
+      public ConstAttrVisitor<Derived>,
+      public ConstTemplateArgumentVisitor<Derived> {
+
+  /// Indicates whether we should trigger deserialization of nodes that had
+  /// not already been loaded.
+  bool Deserialize = false;
+
+  NodeDelegateType &getNodeDelegate() {
+    return getDerived().doGetNodeDelegate();
+  }
+  Derived &getDerived() { return *static_cast<Derived *>(this); }
+
+public:
+  void setDeserialize(bool D) { Deserialize = D; }
+  bool getDeserialize() const { return Deserialize; }
+
+  void Visit(const Decl *D) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(D);
+      if (!D)
+        return;
+
+      ConstDeclVisitor<Derived>::Visit(D);
+
+      for (const auto &A : D->attrs())
+        Visit(A);
+
+      if (const comments::FullComment *Comment =
+              D->getASTContext().getLocalCommentForDeclUncached(D))
+        Visit(Comment, Comment);
+
+      // Decls within functions are visited by the body.
+      if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
+        if (const auto *DC = dyn_cast<DeclContext>(D))
+          dumpDeclContext(DC);
+      }
+    });
+  }
+
+  void Visit(const Stmt *S, StringRef Label = {}) {
+    getNodeDelegate().AddChild(Label, [=] {
+      getNodeDelegate().Visit(S);
+
+      if (!S) {
+        return;
+      }
+
+      ConstStmtVisitor<Derived>::Visit(S);
+
+      // Some statements have custom mechanisms for dumping their children.
+      if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) {
+        return;
+      }
+
+      for (const Stmt *SubStmt : S->children())
+        Visit(SubStmt);
+    });
+  }
+
+  void Visit(QualType T) {
+    SplitQualType SQT = T.split();
+    if (!SQT.Quals.hasQualifiers())
+      return Visit(SQT.Ty);
+
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(T);
+      Visit(T.split().Ty);
+    });
+  }
+
+  void Visit(const Type *T) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(T);
+      if (!T)
+        return;
+      TypeVisitor<Derived>::Visit(T);
+
+      QualType SingleStepDesugar =
+          T->getLocallyUnqualifiedSingleStepDesugaredType();
+      if (SingleStepDesugar != QualType(T, 0))
+        Visit(SingleStepDesugar);
+    });
+  }
+
+  void Visit(const Attr *A) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(A);
+      ConstAttrVisitor<Derived>::Visit(A);
+    });
+  }
+
+  void Visit(const CXXCtorInitializer *Init) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(Init);
+      Visit(Init->getInit());
+    });
+  }
+
+  void Visit(const TemplateArgument &A, SourceRange R = {},
+             const Decl *From = nullptr, const char *Label = nullptr) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(A, R, From, Label);
+      ConstTemplateArgumentVisitor<Derived>::Visit(A);
+    });
+  }
+
+  void Visit(const BlockDecl::Capture &C) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(C);
+      if (C.hasCopyExpr())
+        Visit(C.getCopyExpr());
+    });
+  }
+
+  void Visit(const OMPClause *C) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(C);
+      for (const auto *S : C->children())
+        Visit(S);
+    });
+  }
+
+  void Visit(const GenericSelectionExpr::ConstAssociation &A) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(A);
+      if (const TypeSourceInfo *TSI = A.getTypeSourceInfo())
+        Visit(TSI->getType());
+      Visit(A.getAssociationExpr());
+    });
+  }
+
+  void Visit(const comments::Comment *C, const comments::FullComment *FC) {
+    getNodeDelegate().AddChild([=] {
+      getNodeDelegate().Visit(C, FC);
+      if (!C) {
+        return;
+      }
+      comments::ConstCommentVisitor<Derived, void,
+                                    const comments::FullComment *>::visit(C,
+                                                                          FC);
+      for (comments::Comment::child_iterator I = C->child_begin(),
+                                             E = C->child_end();
+           I != E; ++I)
+        Visit(*I, FC);
+    });
+  }
+
+  void dumpDeclContext(const DeclContext *DC) {
+    if (!DC)
+      return;
+
+    for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
+      Visit(D);
+  }
+
+  void dumpTemplateParameters(const TemplateParameterList *TPL) {
+    if (!TPL)
+      return;
+
+    for (const auto &TP : *TPL)
+      Visit(TP);
+  }
+
+  void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI) {
+    for (const auto &TA : TALI.arguments())
+      dumpTemplateArgumentLoc(TA);
+  }
+
+  void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
+                               const Decl *From = nullptr,
+                               const char *Label = nullptr) {
+    Visit(A.getArgument(), A.getSourceRange(), From, Label);
+  }
+
+  void dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
+    for (unsigned i = 0, e = TAL.size(); i < e; ++i)
+      Visit(TAL[i]);
+  }
+
+  void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
+    if (!typeParams)
+      return;
+
+    for (const auto &typeParam : *typeParams) {
+      Visit(typeParam);
+    }
+  }
+
+  void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); }
+  void VisitLocInfoType(const LocInfoType *T) {
+    Visit(T->getTypeSourceInfo()->getType());
+  }
+  void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); }
+  void VisitBlockPointerType(const BlockPointerType *T) {
+    Visit(T->getPointeeType());
+  }
+  void VisitReferenceType(const ReferenceType *T) {
+    Visit(T->getPointeeType());
+  }
+  void VisitMemberPointerType(const MemberPointerType *T) {
+    Visit(T->getClass());
+    Visit(T->getPointeeType());
+  }
+  void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
+  void VisitVariableArrayType(const VariableArrayType *T) {
+    VisitArrayType(T);
+    Visit(T->getSizeExpr());
+  }
+  void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
+    Visit(T->getElementType());
+    Visit(T->getSizeExpr());
+  }
+  void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
+    Visit(T->getElementType());
+    Visit(T->getSizeExpr());
+  }
+  void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
+  void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
+  void VisitFunctionProtoType(const FunctionProtoType *T) {
+    VisitFunctionType(T);
+    for (const QualType &PT : T->getParamTypes())
+      Visit(PT);
+  }
+  void VisitTypeOfExprType(const TypeOfExprType *T) {
+    Visit(T->getUnderlyingExpr());
+  }
+  void VisitDecltypeType(const DecltypeType *T) {
+    Visit(T->getUnderlyingExpr());
+  }
+  void VisitUnaryTransformType(const UnaryTransformType *T) {
+    Visit(T->getBaseType());
+  }
+  void VisitAttributedType(const AttributedType *T) {
+    // FIXME: AttrKind
+    Visit(T->getModifiedType());
+  }
+  void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+    Visit(T->getReplacedParameter());
+  }
+  void
+  VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
+    Visit(T->getReplacedParameter());
+    Visit(T->getArgumentPack());
+  }
+  void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
+    for (const auto &Arg : *T)
+      Visit(Arg);
+    if (T->isTypeAlias())
+      Visit(T->getAliasedType());
+  }
+  void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
+    Visit(T->getPointeeType());
+  }
+  void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); }
+  void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); }
+  void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); }
+  void VisitPackExpansionType(const PackExpansionType *T) {
+    if (!T->isSugared())
+      Visit(T->getPattern());
+  }
+  // FIXME: ElaboratedType, DependentNameType,
+  // DependentTemplateSpecializationType, ObjCObjectType
+
+  void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
+
+  void VisitEnumConstantDecl(const EnumConstantDecl *D) {
+    if (const Expr *Init = D->getInitExpr())
+      Visit(Init);
+  }
+
+  void VisitFunctionDecl(const FunctionDecl *D) {
+    if (const auto *FTSI = D->getTemplateSpecializationInfo())
+      dumpTemplateArgumentList(*FTSI->TemplateArguments);
+
+    if (D->param_begin())
+      for (const auto *Parameter : D->parameters())
+        Visit(Parameter);
+
+    if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
+      for (const auto *I : C->inits())
+        Visit(I);
+
+    if (D->doesThisDeclarationHaveABody())
+      Visit(D->getBody());
+  }
+
+  void VisitFieldDecl(const FieldDecl *D) {
+    if (D->isBitField())
+      Visit(D->getBitWidth());
+    if (Expr *Init = D->getInClassInitializer())
+      Visit(Init);
+  }
+
+  void VisitVarDecl(const VarDecl *D) {
+    if (D->hasInit())
+      Visit(D->getInit());
+  }
+
+  void VisitDecompositionDecl(const DecompositionDecl *D) {
+    VisitVarDecl(D);
+    for (const auto *B : D->bindings())
+      Visit(B);
+  }
+
+  void VisitBindingDecl(const BindingDecl *D) {
+    if (const auto *E = D->getBinding())
+      Visit(E);
+  }
+
+  void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
+    Visit(D->getAsmString());
+  }
+
+  void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
+
+  void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
+    for (const auto *E : D->varlists())
+      Visit(E);
+  }
+
+  void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
+    Visit(D->getCombiner());
+    if (const auto *Initializer = D->getInitializer())
+      Visit(Initializer);
+  }
+
+  void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
+    for (const auto *C : D->clauselists())
+      Visit(C);
+  }
+
+  void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
+    Visit(D->getInit());
+  }
+
+  template <typename SpecializationDecl>
+  void dumpTemplateDeclSpecialization(const SpecializationDecl *D) {
+    for (const auto *RedeclWithBadType : D->redecls()) {
+      // FIXME: The redecls() range sometimes has elements of a less-specific
+      // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
+      // us TagDecls, and should give CXXRecordDecls).
+      auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
+      if (!Redecl) {
+        // Found the injected-class-name for a class template. This will be
+        // dumped as part of its surrounding class so we don't need to dump it
+        // here.
+        assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
+               "expected an injected-class-name");
+        continue;
+      }
+      Visit(Redecl);
+    }
+  }
+
+  template <typename TemplateDecl>
+  void dumpTemplateDecl(const TemplateDecl *D) {
+    dumpTemplateParameters(D->getTemplateParameters());
+
+    Visit(D->getTemplatedDecl());
+
+    for (const auto *Child : D->specializations())
+      dumpTemplateDeclSpecialization(Child);
+  }
+
+  void VisitTypeAliasDecl(const TypeAliasDecl *D) {
+    Visit(D->getUnderlyingType());
+  }
+
+  void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
+    dumpTemplateParameters(D->getTemplateParameters());
+    Visit(D->getTemplatedDecl());
+  }
+
+  void VisitStaticAssertDecl(const StaticAssertDecl *D) {
+    Visit(D->getAssertExpr());
+    Visit(D->getMessage());
+  }
+
+  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
+    dumpTemplateDecl(D);
+  }
+
+  void VisitClassTemplateDecl(const ClassTemplateDecl *D) {
+    dumpTemplateDecl(D);
+  }
+
+  void VisitClassTemplateSpecializationDecl(
+      const ClassTemplateSpecializationDecl *D) {
+    dumpTemplateArgumentList(D->getTemplateArgs());
+  }
+
+  void VisitClassTemplatePartialSpecializationDecl(
+      const ClassTemplatePartialSpecializationDecl *D) {
+    VisitClassTemplateSpecializationDecl(D);
+    dumpTemplateParameters(D->getTemplateParameters());
+  }
+
+  void VisitClassScopeFunctionSpecializationDecl(
+      const ClassScopeFunctionSpecializationDecl *D) {
+    Visit(D->getSpecialization());
+    if (D->hasExplicitTemplateArgs())
+      dumpTemplateArgumentListInfo(D->templateArgs());
+  }
+  void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); }
+
+  void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
+    dumpTemplateParameters(D->getTemplateParameters());
+  }
+
+  void
+  VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
+    dumpTemplateArgumentList(D->getTemplateArgs());
+    VisitVarDecl(D);
+  }
+
+  void VisitVarTemplatePartialSpecializationDecl(
+      const VarTemplatePartialSpecializationDecl *D) {
+    dumpTemplateParameters(D->getTemplateParameters());
+    VisitVarTemplateSpecializationDecl(D);
+  }
+
+  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
+    if (D->hasDefaultArgument())
+      Visit(D->getDefaultArgument(), SourceRange(),
+            D->getDefaultArgStorage().getInheritedFrom(),
+            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
+  }
+
+  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
+    if (D->hasDefaultArgument())
+      Visit(D->getDefaultArgument(), SourceRange(),
+            D->getDefaultArgStorage().getInheritedFrom(),
+            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
+  }
+
+  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
+    dumpTemplateParameters(D->getTemplateParameters());
+    if (D->hasDefaultArgument())
+      dumpTemplateArgumentLoc(
+          D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
+          D->defaultArgumentWasInherited() ? "inherited from" : "previous");
+  }
+
+  void VisitUsingShadowDecl(const UsingShadowDecl *D) {
+    if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
+      Visit(TD->getTypeForDecl());
+  }
+
+  void VisitFriendDecl(const FriendDecl *D) {
+    if (!D->getFriendType())
+      Visit(D->getFriendDecl());
+  }
+
+  void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
+    if (D->isThisDeclarationADefinition())
+      dumpDeclContext(D);
+    else
+      for (const ParmVarDecl *Parameter : D->parameters())
+        Visit(Parameter);
+
+    if (D->hasBody())
+      Visit(D->getBody());
+  }
+
+  void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
+    dumpObjCTypeParamList(D->getTypeParamList());
+  }
+
+  void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
+    dumpObjCTypeParamList(D->getTypeParamListAsWritten());
+  }
+
+  void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
+    for (const auto &I : D->inits())
+      Visit(I);
+  }
+
+  void VisitBlockDecl(const BlockDecl *D) {
+    for (const auto &I : D->parameters())
+      Visit(I);
+
+    for (const auto &I : D->captures())
+      Visit(I);
+    Visit(D->getBody());
+  }
+
+  void VisitDeclStmt(const DeclStmt *Node) {
+    for (const auto &D : Node->decls())
+      Visit(D);
+  }
+
+  void VisitAttributedStmt(const AttributedStmt *Node) {
+    for (const auto *A : Node->getAttrs())
+      Visit(A);
+  }
+
+  void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
+    Visit(Node->getExceptionDecl());
+  }
+
+  void VisitCapturedStmt(const CapturedStmt *Node) {
+    Visit(Node->getCapturedDecl());
+  }
+
+  void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) {
+    for (const auto *C : Node->clauses())
+      Visit(C);
+  }
+
+  void VisitInitListExpr(const InitListExpr *ILE) {
+    if (auto *Filler = ILE->getArrayFiller()) {
+      Visit(Filler, "array_filler");
+    }
+  }
+
+  void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
+
+  void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
+    if (Expr *Source = Node->getSourceExpr())
+      Visit(Source);
+  }
+
+  void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
+    Visit(E->getControllingExpr());
+    Visit(E->getControllingExpr()->getType()); // FIXME: remove
+
+    for (const auto &Assoc : E->associations()) {
+      Visit(Assoc);
+    }
+  }
+
+  void VisitLambdaExpr(const LambdaExpr *Node) {
+    Visit(Node->getLambdaClass());
+  }
+
+  void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
+    if (Node->isPartiallySubstituted())
+      for (const auto &A : Node->getPartialArguments())
+        Visit(A);
+  }
+
+  void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
+    if (const VarDecl *CatchParam = Node->getCatchParamDecl())
+      Visit(CatchParam);
+  }
+
+  void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
+    Visit(TA.getAsExpr());
+  }
+  void VisitPackTemplateArgument(const TemplateArgument &TA) {
+    for (const auto &TArg : TA.pack_elements())
+      Visit(TArg);
+  }
+
+  // Implements Visit methods for Attrs.
+#include "clang/AST/AttrNodeTraverse.inc"
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H

Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=352989&r1=352988&r2=352989&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Sun Feb  3 06:06:54 2019
@@ -12,20 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTDumperUtils.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/AttrVisitor.h"
-#include "clang/AST/CommentVisitor.h"
-#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ASTNodeTraverser.h"
 #include "clang/AST/DeclLookups.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#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"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceManager.h"
@@ -39,562 +28,44 @@ using namespace clang::comments;
 
 namespace  {
 
-  class ASTDumper
-      : public ConstDeclVisitor<ASTDumper>,
-        public ConstStmtVisitor<ASTDumper>,
-        public ConstCommentVisitor<ASTDumper, void, const FullComment *>,
-        public TypeVisitor<ASTDumper>,
-        public ConstAttrVisitor<ASTDumper>,
-        public ConstTemplateArgumentVisitor<ASTDumper> {
-
-    TextNodeDumper NodeDumper;
-
-    raw_ostream &OS;
-
-    /// Indicates whether we should trigger deserialization of nodes that had
-    /// not already been loaded.
-    bool Deserialize = false;
-
-    const bool ShowColors;
-
-  public:
-    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
-              const SourceManager *SM)
-        : ASTDumper(OS, Traits, SM,
-                    SM && SM->getDiagnostics().getShowColors()) {}
-
-    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
-              const SourceManager *SM, bool ShowColors)
-        : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
-    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
-              const SourceManager *SM, bool ShowColors,
-              const PrintingPolicy &PrintPolicy)
-        : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
-          ShowColors(ShowColors) {}
-
-    void setDeserialize(bool D) { Deserialize = D; }
-
-    void Visit(const Decl *D) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(D);
-        if (!D)
-          return;
-
-        ConstDeclVisitor<ASTDumper>::Visit(D);
-
-        for (const auto &A : D->attrs())
-          Visit(A);
-
-        if (const FullComment *Comment =
-                D->getASTContext().getLocalCommentForDeclUncached(D))
-          Visit(Comment, Comment);
-
-        // Decls within functions are visited by the body.
-        if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
-          if (const auto *DC = dyn_cast<DeclContext>(D))
-            dumpDeclContext(DC);
-        }
-      });
-    }
-
-    void Visit(const Stmt *S, StringRef Label = {}) {
-      NodeDumper.AddChild(Label, [=] {
-        NodeDumper.Visit(S);
-
-        if (!S) {
-          return;
-        }
-
-        ConstStmtVisitor<ASTDumper>::Visit(S);
-
-        // Some statements have custom mechanisms for dumping their children.
-        if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) {
-          return;
-        }
-
-        for (const Stmt *SubStmt : S->children())
-          Visit(SubStmt);
-      });
-    }
-
-    void Visit(QualType T) {
-      SplitQualType SQT = T.split();
-      if (!SQT.Quals.hasQualifiers())
-        return Visit(SQT.Ty);
-
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(T);
-        Visit(T.split().Ty);
-      });
-    }
-
-    void Visit(const Type *T) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(T);
-        if (!T)
-          return;
-        TypeVisitor<ASTDumper>::Visit(T);
-
-        QualType SingleStepDesugar =
-            T->getLocallyUnqualifiedSingleStepDesugaredType();
-        if (SingleStepDesugar != QualType(T, 0))
-          Visit(SingleStepDesugar);
-      });
-    }
-
-    void Visit(const Attr *A) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(A);
-        ConstAttrVisitor<ASTDumper>::Visit(A);
-      });
-    }
-
-    void Visit(const CXXCtorInitializer *Init) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(Init);
-        Visit(Init->getInit());
-      });
-    }
-
-    void Visit(const TemplateArgument &A, SourceRange R = {},
-               const Decl *From = nullptr, const char *Label = nullptr) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(A, R, From, Label);
-        ConstTemplateArgumentVisitor<ASTDumper>::Visit(A);
-      });
-    }
-
-    void Visit(const BlockDecl::Capture &C) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(C);
-        if (C.hasCopyExpr())
-          Visit(C.getCopyExpr());
-      });
-    }
-
-    void Visit(const OMPClause *C) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(C);
-        for (const auto *S : C->children())
-          Visit(S);
-      });
-    }
-
-    void Visit(const GenericSelectionExpr::ConstAssociation &A) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(A);
-        if (const TypeSourceInfo *TSI = A.getTypeSourceInfo())
-          Visit(TSI->getType());
-        Visit(A.getAssociationExpr());
-      });
-    }
-
-    void Visit(const Comment *C, const FullComment *FC) {
-      NodeDumper.AddChild([=] {
-        NodeDumper.Visit(C, FC);
-        if (!C) {
-          return;
-        }
-        ConstCommentVisitor<ASTDumper, void, const FullComment *>::visit(C, FC);
-        for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
-             I != E; ++I)
-          Visit(*I, FC);
-      });
-    }
-
-    void dumpDeclContext(const DeclContext *DC);
-    void dumpLookups(const DeclContext *DC, bool DumpDecls);
-
-    void dumpTemplateParameters(const TemplateParameterList *TPL) {
-      if (!TPL)
-        return;
-
-      for (const auto &TP : *TPL)
-        Visit(TP);
-    }
-
-    void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI) {
-      for (const auto &TA : TALI.arguments())
-        dumpTemplateArgumentLoc(TA);
-    }
-
-    void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
-                                 const Decl *From = nullptr,
-                                 const char *Label = nullptr) {
-      Visit(A.getArgument(), A.getSourceRange(), From, Label);
-    }
-
-    void dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
-      for (unsigned i = 0, e = TAL.size(); i < e; ++i)
-        Visit(TAL[i]);
-    }
-
-    void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
-      if (!typeParams)
-        return;
-
-      for (const auto &typeParam : *typeParams) {
-        Visit(typeParam);
-      }
-    }
-
-    void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); }
-    void VisitLocInfoType(const LocInfoType *T) {
-      Visit(T->getTypeSourceInfo()->getType());
-    }
-    void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); }
-    void VisitBlockPointerType(const BlockPointerType *T) {
-      Visit(T->getPointeeType());
-    }
-    void VisitReferenceType(const ReferenceType *T) {
-      Visit(T->getPointeeType());
-    }
-    void VisitMemberPointerType(const MemberPointerType *T) {
-      Visit(T->getClass());
-      Visit(T->getPointeeType());
-    }
-    void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
-    void VisitVariableArrayType(const VariableArrayType *T) {
-      VisitArrayType(T);
-      Visit(T->getSizeExpr());
-    }
-    void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
-      Visit(T->getElementType());
-      Visit(T->getSizeExpr());
-    }
-    void
-    VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
-      Visit(T->getElementType());
-      Visit(T->getSizeExpr());
-    }
-    void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
-    void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
-    void VisitFunctionProtoType(const FunctionProtoType *T) {
-      VisitFunctionType(T);
-      for (const QualType &PT : T->getParamTypes())
-        Visit(PT);
-    }
-    void VisitTypeOfExprType(const TypeOfExprType *T) {
-      Visit(T->getUnderlyingExpr());
-    }
-    void VisitDecltypeType(const DecltypeType *T) {
-      Visit(T->getUnderlyingExpr());
-    }
-    void VisitUnaryTransformType(const UnaryTransformType *T) {
-      Visit(T->getBaseType());
-    }
-    void VisitAttributedType(const AttributedType *T) {
-      // FIXME: AttrKind
-      Visit(T->getModifiedType());
-    }
-    void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
-      Visit(T->getReplacedParameter());
-    }
-    void
-    VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
-      Visit(T->getReplacedParameter());
-      Visit(T->getArgumentPack());
-    }
-    void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
-      for (const auto &Arg : *T)
-        Visit(Arg);
-      if (T->isTypeAlias())
-        Visit(T->getAliasedType());
-    }
-    void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
-      Visit(T->getPointeeType());
-    }
-    void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); }
-    void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); }
-    void VisitAdjustedType(const AdjustedType *T) {
-      Visit(T->getOriginalType());
-    }
-    void VisitPackExpansionType(const PackExpansionType *T) {
-      if (!T->isSugared())
-        Visit(T->getPattern());
-    }
-    // FIXME: ElaboratedType, DependentNameType,
-    // DependentTemplateSpecializationType, ObjCObjectType
-
-    void VisitTypedefDecl(const TypedefDecl *D) {
-      Visit(D->getUnderlyingType());
-    }
-
-    void VisitEnumConstantDecl(const EnumConstantDecl *D) {
-      if (const Expr *Init = D->getInitExpr())
-        Visit(Init);
-    }
-
-    void VisitFunctionDecl(const FunctionDecl *D) {
-      if (const auto *FTSI = D->getTemplateSpecializationInfo())
-        dumpTemplateArgumentList(*FTSI->TemplateArguments);
-
-      if (D->param_begin())
-        for (const auto *Parameter : D->parameters())
-          Visit(Parameter);
-
-      if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
-        for (const auto *I : C->inits())
-          Visit(I);
-
-      if (D->doesThisDeclarationHaveABody())
-        Visit(D->getBody());
-    }
-
-    void VisitFieldDecl(const FieldDecl *D) {
-      if (D->isBitField())
-        Visit(D->getBitWidth());
-      if (Expr *Init = D->getInClassInitializer())
-        Visit(Init);
-    }
-
-    void VisitVarDecl(const VarDecl *D) {
-      if (D->hasInit())
-        Visit(D->getInit());
-    }
-
-    void VisitDecompositionDecl(const DecompositionDecl *D) {
-      VisitVarDecl(D);
-      for (const auto *B : D->bindings())
-        Visit(B);
-    }
-
-    void VisitBindingDecl(const BindingDecl *D) {
-      if (const auto *E = D->getBinding())
-        Visit(E);
-    }
-
-    void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
-      Visit(D->getAsmString());
-    }
-
-    void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
-
-    void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
-      for (const auto *E : D->varlists())
-        Visit(E);
-    }
-
-    void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
-      Visit(D->getCombiner());
-      if (const auto *Initializer = D->getInitializer())
-        Visit(Initializer);
-    }
-
-    void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
-      for (const auto *C : D->clauselists())
-        Visit(C);
-    }
-
-    void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
-      Visit(D->getInit());
-    }
-
-    template <typename SpecializationDecl>
-    void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
-                                        bool DumpExplicitInst,
-                                        bool DumpRefOnly);
-    template <typename TemplateDecl>
-    void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
-
-    void VisitTypeAliasDecl(const TypeAliasDecl *D) {
-      Visit(D->getUnderlyingType());
-    }
-
-    void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
-      dumpTemplateParameters(D->getTemplateParameters());
-      Visit(D->getTemplatedDecl());
-    }
-
-    void VisitStaticAssertDecl(const StaticAssertDecl *D) {
-      Visit(D->getAssertExpr());
-      Visit(D->getMessage());
-    }
-    void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
-    void VisitClassTemplateDecl(const ClassTemplateDecl *D);
-
-    void VisitClassTemplateSpecializationDecl(
-        const ClassTemplateSpecializationDecl *D) {
-      dumpTemplateArgumentList(D->getTemplateArgs());
-    }
-
-    void VisitClassTemplatePartialSpecializationDecl(
-        const ClassTemplatePartialSpecializationDecl *D) {
-      VisitClassTemplateSpecializationDecl(D);
-      dumpTemplateParameters(D->getTemplateParameters());
-    }
+class ASTDumper : public ASTNodeTraverser<ASTDumper, TextNodeDumper> {
 
-    void VisitClassScopeFunctionSpecializationDecl(
-        const ClassScopeFunctionSpecializationDecl *D) {
-      Visit(D->getSpecialization());
-      if (D->hasExplicitTemplateArgs())
-        dumpTemplateArgumentListInfo(D->templateArgs());
-    }
-    void VisitVarTemplateDecl(const VarTemplateDecl *D);
-
-    void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
-      dumpTemplateParameters(D->getTemplateParameters());
-    }
-
-    void
-    VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
-      dumpTemplateArgumentList(D->getTemplateArgs());
-      VisitVarDecl(D);
-    }
-
-    void VisitVarTemplatePartialSpecializationDecl(
-        const VarTemplatePartialSpecializationDecl *D) {
-      dumpTemplateParameters(D->getTemplateParameters());
-      VisitVarTemplateSpecializationDecl(D);
-    }
-
-    void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
-      if (D->hasDefaultArgument())
-        Visit(D->getDefaultArgument(), SourceRange(),
-              D->getDefaultArgStorage().getInheritedFrom(),
-              D->defaultArgumentWasInherited() ? "inherited from" : "previous");
-    }
+  TextNodeDumper NodeDumper;
 
-    void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
-      if (D->hasDefaultArgument())
-        Visit(D->getDefaultArgument(), SourceRange(),
-              D->getDefaultArgStorage().getInheritedFrom(),
-              D->defaultArgumentWasInherited() ? "inherited from" : "previous");
-    }
-
-    void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
-      dumpTemplateParameters(D->getTemplateParameters());
-      if (D->hasDefaultArgument())
-        dumpTemplateArgumentLoc(
-            D->getDefaultArgument(),
-            D->getDefaultArgStorage().getInheritedFrom(),
-            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
-    }
-
-    void VisitUsingShadowDecl(const UsingShadowDecl *D) {
-      if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
-        Visit(TD->getTypeForDecl());
-    }
+  raw_ostream &OS;
 
-    void VisitFriendDecl(const FriendDecl *D) {
-      if (!D->getFriendType())
-        Visit(D->getFriendDecl());
-    }
-
-    void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
-      if (D->isThisDeclarationADefinition())
-        dumpDeclContext(D);
-      else
-        for (const ParmVarDecl *Parameter : D->parameters())
-          Visit(Parameter);
-
-      if (D->hasBody())
-        Visit(D->getBody());
-    }
+  const bool ShowColors;
 
-    void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
-      dumpObjCTypeParamList(D->getTypeParamList());
-    }
-
-    void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
-      dumpObjCTypeParamList(D->getTypeParamListAsWritten());
-    }
-
-    void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
-      for (const auto &I : D->inits())
-        Visit(I);
-    }
-
-    void VisitBlockDecl(const BlockDecl *D) {
-      for (const auto &I : D->parameters())
-        Visit(I);
-
-      for (const auto &I : D->captures())
-        Visit(I);
-      Visit(D->getBody());
-    }
-
-    void VisitDeclStmt(const DeclStmt *Node) {
-      for (const auto &D : Node->decls())
-        Visit(D);
-    }
-
-    void VisitAttributedStmt(const AttributedStmt *Node) {
-      for (const auto *A : Node->getAttrs())
-        Visit(A);
-    }
-
-    void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
-      Visit(Node->getExceptionDecl());
-    }
-
-    void VisitCapturedStmt(const CapturedStmt *Node) {
-      Visit(Node->getCapturedDecl());
-    }
-
-    void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) {
-      for (const auto *C : Node->clauses())
-        Visit(C);
-    }
-
-    void VisitInitListExpr(const InitListExpr *ILE) {
-      if (auto *Filler = ILE->getArrayFiller()) {
-        Visit(Filler, "array_filler");
-      }
-    }
-
-    void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
-
-    void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
-      if (Expr *Source = Node->getSourceExpr())
-        Visit(Source);
-    }
-
-    void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
-      Visit(E->getControllingExpr());
-      Visit(E->getControllingExpr()->getType()); // FIXME: remove
-
-      for (const auto &Assoc : E->associations()) {
-        Visit(Assoc);
-      }
-    }
-
-    void VisitLambdaExpr(const LambdaExpr *Node) {
-      Visit(Node->getLambdaClass());
-    }
-
-    void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
-      if (Node->isPartiallySubstituted())
-        for (const auto &A : Node->getPartialArguments())
-          Visit(A);
-    }
-
-    void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
-      if (const VarDecl *CatchParam = Node->getCatchParamDecl())
-        Visit(CatchParam);
-    }
-
-    void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
-      Visit(TA.getAsExpr());
-    }
-    void VisitPackTemplateArgument(const TemplateArgument &TA) {
-      for (const auto &TArg : TA.pack_elements())
-        Visit(TArg);
-    }
-
-    // Implements Visit methods for Attrs.
-#include "clang/AST/AttrNodeTraverse.inc"
-  };
+public:
+  ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
+            const SourceManager *SM)
+      : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {}
+
+  ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
+            const SourceManager *SM, bool ShowColors)
+      : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
+  ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
+            const SourceManager *SM, bool ShowColors,
+            const PrintingPolicy &PrintPolicy)
+      : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
+        ShowColors(ShowColors) {}
+
+  TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
+
+  void dumpLookups(const DeclContext *DC, bool DumpDecls);
+
+  template <typename SpecializationDecl>
+  void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
+                                      bool DumpExplicitInst, bool DumpRefOnly);
+  template <typename TemplateDecl>
+  void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
+
+  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
+  void VisitClassTemplateDecl(const ClassTemplateDecl *D);
+  void VisitVarTemplateDecl(const VarTemplateDecl *D);
+};
 } // namespace
 
-void ASTDumper::dumpDeclContext(const DeclContext *DC) {
-  if (!DC)
-    return;
-
-  for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
-    Visit(D);
-}
-
 void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
   NodeDumper.AddChild([=] {
     OS << "StoredDeclsMap ";
@@ -608,7 +79,7 @@ void ASTDumper::dumpLookups(const DeclCo
 
     bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
 
-    auto Range = Deserialize
+    auto Range = getDeserialize()
                      ? Primary->lookups()
                      : Primary->noload_lookups(/*PreserveInternalState=*/true);
     for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {




More information about the cfe-commits mailing list