Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:34

0001 //===--- DynamicRecursiveASTVisitor.h - Virtual AST Visitor -----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the DynamicRecursiveASTVisitor interface, which acts
0010 //  identically to RecursiveASTVisitor, except that it uses virtual dispatch
0011 //  instead of CRTP, which greatly improves compile times and binary size.
0012 //
0013 //  Prefer to use this over RecursiveASTVisitor whenever possible.
0014 //
0015 //===----------------------------------------------------------------------===//
0016 #ifndef LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
0017 #define LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
0018 
0019 #include "clang/AST/Attr.h"
0020 #include "clang/AST/ExprConcepts.h"
0021 #include "clang/AST/TypeLoc.h"
0022 
0023 namespace clang {
0024 class ASTContext;
0025 
0026 /// Recursive AST visitor that supports extension via dynamic dispatch.
0027 ///
0028 /// Like RecursiveASTVisitor, this class allows for traversal of arbitrarily
0029 /// complex ASTs. The main difference is that this uses virtual functions
0030 /// instead of CRTP, which greatly improves compile times of Clang itself,
0031 /// as well as binary size.
0032 ///
0033 /// Instead of functions (e.g. shouldVisitImplicitCode()), this class
0034 /// uses member variables (e.g. ShouldVisitImplicitCode) to control
0035 /// visitation behaviour.
0036 ///
0037 /// However, there is no support for overriding some of the less commonly
0038 /// used features of the RAV, such as WalkUpFromX or attribute traversal
0039 /// (attributes can still be traversed, but you can't change what happens
0040 /// when we traverse one).
0041 ///
0042 /// The following is a list of RAV features that are NOT customisable:
0043 ///
0044 ///   - Visiting attributes,
0045 ///   - Overriding WalkUpFromX,
0046 ///   - Overriding getStmtChildren().
0047 ///
0048 /// Furthermore, post-order traversal is not supported at all.
0049 ///
0050 /// Prefer to use this over RecursiveASTVisitor unless you absolutely
0051 /// need to use one of the features listed above (e.g. overriding
0052 /// WalkUpFromX or post-order traversal).
0053 ///
0054 /// \see RecursiveASTVisitor.
0055 class DynamicRecursiveASTVisitor {
0056 public:
0057   /// Whether this visitor should recurse into template instantiations.
0058   bool ShouldVisitTemplateInstantiations = false;
0059 
0060   /// Whether this visitor should recurse into the types of TypeLocs.
0061   bool ShouldWalkTypesOfTypeLocs = true;
0062 
0063   /// Whether this visitor should recurse into implicit code, e.g.
0064   /// implicit constructors and destructors.
0065   bool ShouldVisitImplicitCode = false;
0066 
0067   /// Whether this visitor should recurse into lambda body.
0068   bool ShouldVisitLambdaBody = true;
0069 
0070 protected:
0071   DynamicRecursiveASTVisitor() = default;
0072   DynamicRecursiveASTVisitor(DynamicRecursiveASTVisitor &&) = default;
0073   DynamicRecursiveASTVisitor(const DynamicRecursiveASTVisitor &) = default;
0074   DynamicRecursiveASTVisitor &
0075   operator=(DynamicRecursiveASTVisitor &&) = default;
0076   DynamicRecursiveASTVisitor &
0077   operator=(const DynamicRecursiveASTVisitor &) = default;
0078 
0079 public:
0080   virtual void anchor();
0081   virtual ~DynamicRecursiveASTVisitor() = default;
0082 
0083   /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
0084   /// \returns false if visitation was terminated early.
0085   virtual bool TraverseAST(ASTContext &AST);
0086 
0087   /// Recursively visit an attribute, by dispatching to
0088   /// Traverse*Attr() based on the argument's dynamic type.
0089   ///
0090   /// \returns false if the visitation was terminated early, true
0091   /// otherwise (including when the argument is a Null type location).
0092   virtual bool TraverseAttr(Attr *At);
0093 
0094   /// Recursively visit a constructor initializer.  This
0095   /// automatically dispatches to another visitor for the initializer
0096   /// expression, but not for the name of the initializer, so may
0097   /// be overridden for clients that need access to the name.
0098   ///
0099   /// \returns false if the visitation was terminated early, true otherwise.
0100   virtual bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
0101 
0102   /// Recursively visit a base specifier. This can be overridden by a
0103   /// subclass.
0104   ///
0105   /// \returns false if the visitation was terminated early, true otherwise.
0106   virtual bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base);
0107 
0108   /// Recursively visit a declaration, by dispatching to
0109   /// Traverse*Decl() based on the argument's dynamic type.
0110   ///
0111   /// \returns false if the visitation was terminated early, true
0112   /// otherwise (including when the argument is NULL).
0113   virtual bool TraverseDecl(Decl *D);
0114 
0115   /// Recursively visit a name with its location information.
0116   ///
0117   /// \returns false if the visitation was terminated early, true otherwise.
0118   virtual bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
0119 
0120   /// Recursively visit a lambda capture. \c Init is the expression that
0121   /// will be used to initialize the capture.
0122   ///
0123   /// \returns false if the visitation was terminated early, true otherwise.
0124   virtual bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
0125                                      Expr *Init);
0126 
0127   /// Recursively visit a C++ nested-name-specifier.
0128   ///
0129   /// \returns false if the visitation was terminated early, true otherwise.
0130   virtual bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
0131 
0132   /// Recursively visit a C++ nested-name-specifier with location
0133   /// information.
0134   ///
0135   /// \returns false if the visitation was terminated early, true otherwise.
0136   virtual bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
0137 
0138   /// Recursively visit a statement or expression, by
0139   /// dispatching to Traverse*() based on the argument's dynamic type.
0140   ///
0141   /// \returns false if the visitation was terminated early, true
0142   /// otherwise (including when the argument is nullptr).
0143   virtual bool TraverseStmt(Stmt *S);
0144 
0145   /// Recursively visit a template argument and dispatch to the
0146   /// appropriate method for the argument type.
0147   ///
0148   /// \returns false if the visitation was terminated early, true otherwise.
0149   // FIXME: migrate callers to TemplateArgumentLoc instead.
0150   virtual bool TraverseTemplateArgument(const TemplateArgument &Arg);
0151 
0152   /// Recursively visit a template argument location and dispatch to the
0153   /// appropriate method for the argument type.
0154   ///
0155   /// \returns false if the visitation was terminated early, true otherwise.
0156   virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
0157 
0158   /// Recursively visit a set of template arguments.
0159   ///
0160   /// \returns false if the visitation was terminated early, true otherwise.
0161   // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
0162   // Not virtual for now because no-one overrides it.
0163   bool TraverseTemplateArguments(ArrayRef<TemplateArgument> Args);
0164 
0165   /// Recursively visit a template name and dispatch to the
0166   /// appropriate method.
0167   ///
0168   /// \returns false if the visitation was terminated early, true otherwise.
0169   virtual bool TraverseTemplateName(TemplateName Template);
0170 
0171   /// Recursively visit a type, by dispatching to
0172   /// Traverse*Type() based on the argument's getTypeClass() property.
0173   ///
0174   /// \returns false if the visitation was terminated early, true
0175   /// otherwise (including when the argument is a Null type).
0176   virtual bool TraverseType(QualType T);
0177 
0178   /// Recursively visit a type with location, by dispatching to
0179   /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
0180   ///
0181   /// \returns false if the visitation was terminated early, true
0182   /// otherwise (including when the argument is a Null type location).
0183   virtual bool TraverseTypeLoc(TypeLoc TL);
0184 
0185   /// Recursively visit an Objective-C protocol reference with location
0186   /// information.
0187   ///
0188   /// \returns false if the visitation was terminated early, true otherwise.
0189   virtual bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc);
0190 
0191   /// Traverse a concept (requirement).
0192   virtual bool TraverseTypeConstraint(const TypeConstraint *C);
0193   virtual bool TraverseConceptRequirement(concepts::Requirement *R);
0194   virtual bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R);
0195   virtual bool TraverseConceptExprRequirement(concepts::ExprRequirement *R);
0196   virtual bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R);
0197   virtual bool TraverseConceptReference(ConceptReference *CR);
0198   virtual bool VisitConceptReference(ConceptReference *CR) { return true; }
0199 
0200   /// Visit a node.
0201   virtual bool VisitAttr(Attr *A) { return true; }
0202   virtual bool VisitDecl(Decl *D) { return true; }
0203   virtual bool VisitStmt(Stmt *S) { return true; }
0204   virtual bool VisitType(Type *T) { return true; }
0205   virtual bool VisitTypeLoc(TypeLoc TL) { return true; }
0206 
0207   /// Walk up from a node.
0208   bool WalkUpFromDecl(Decl *D) { return VisitDecl(D); }
0209   bool WalkUpFromStmt(Stmt *S) { return VisitStmt(S); }
0210   bool WalkUpFromType(Type *T) { return VisitType(T); }
0211   bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); }
0212 
0213   /// Invoked before visiting a statement or expression via data recursion.
0214   ///
0215   /// \returns false to skip visiting the node, true otherwise.
0216   virtual bool dataTraverseStmtPre(Stmt *S) { return true; }
0217 
0218   /// Invoked after visiting a statement or expression via data recursion.
0219   /// This is not invoked if the previously invoked \c dataTraverseStmtPre
0220   /// returned false.
0221   ///
0222   /// \returns false if the visitation was terminated early, true otherwise.
0223   virtual bool dataTraverseStmtPost(Stmt *S) { return true; }
0224   virtual bool dataTraverseNode(Stmt *S);
0225 
0226 #define DEF_TRAVERSE_TMPL_INST(kind)                                           \
0227   virtual bool TraverseTemplateInstantiations(kind##TemplateDecl *D);
0228   DEF_TRAVERSE_TMPL_INST(Class)
0229   DEF_TRAVERSE_TMPL_INST(Var)
0230   DEF_TRAVERSE_TMPL_INST(Function)
0231 #undef DEF_TRAVERSE_TMPL_INST
0232 
0233   // Decls.
0234 #define ABSTRACT_DECL(DECL)
0235 #define DECL(CLASS, BASE) virtual bool Traverse##CLASS##Decl(CLASS##Decl *D);
0236 #include "clang/AST/DeclNodes.inc"
0237 
0238 #define DECL(CLASS, BASE)                                                      \
0239   bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D);                                \
0240   virtual bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
0241 #include "clang/AST/DeclNodes.inc"
0242 
0243   // Stmts.
0244 #define ABSTRACT_STMT(STMT)
0245 #define STMT(CLASS, PARENT) virtual bool Traverse##CLASS(CLASS *S);
0246 #include "clang/AST/StmtNodes.inc"
0247 
0248 #define STMT(CLASS, PARENT)                                                    \
0249   bool WalkUpFrom##CLASS(CLASS *S);                                            \
0250   virtual bool Visit##CLASS(CLASS *S) { return true; }
0251 #include "clang/AST/StmtNodes.inc"
0252 
0253   // Types.
0254 #define ABSTRACT_TYPE(CLASS, BASE)
0255 #define TYPE(CLASS, BASE) virtual bool Traverse##CLASS##Type(CLASS##Type *T);
0256 #include "clang/AST/TypeNodes.inc"
0257 
0258 #define TYPE(CLASS, BASE)                                                      \
0259   bool WalkUpFrom##CLASS##Type(CLASS##Type *T);                                \
0260   virtual bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
0261 #include "clang/AST/TypeNodes.inc"
0262 
0263   // TypeLocs.
0264 #define ABSTRACT_TYPELOC(CLASS, BASE)
0265 #define TYPELOC(CLASS, BASE)                                                   \
0266   virtual bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
0267 #include "clang/AST/TypeLocNodes.def"
0268 
0269 #define TYPELOC(CLASS, BASE)                                                   \
0270   bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL);                          \
0271   virtual bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
0272 #include "clang/AST/TypeLocNodes.def"
0273 };
0274 } // namespace clang
0275 
0276 #endif // LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H