diff options
author | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/clang16/include/clang/ASTMatchers/ASTMatchFinder.h | |
parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
download | ydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/clang16/include/clang/ASTMatchers/ASTMatchFinder.h')
-rw-r--r-- | contrib/libs/clang16/include/clang/ASTMatchers/ASTMatchFinder.h | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/contrib/libs/clang16/include/clang/ASTMatchers/ASTMatchFinder.h b/contrib/libs/clang16/include/clang/ASTMatchers/ASTMatchFinder.h new file mode 100644 index 0000000000..aada04890c --- /dev/null +++ b/contrib/libs/clang16/include/clang/ASTMatchers/ASTMatchFinder.h @@ -0,0 +1,367 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Provides a way to construct an ASTConsumer that runs given matchers +// over the AST and invokes a given callback on every match. +// +// The general idea is to construct a matcher expression that describes a +// subtree match on the AST. Next, a callback that is executed every time the +// expression matches is registered, and the matcher is run over the AST of +// some code. Matched subexpressions can be bound to string IDs and easily +// be accessed from the registered callback. The callback can than use the +// AST nodes that the subexpressions matched on to output information about +// the match or construct changes that can be applied to the code. +// +// Example: +// class HandleMatch : public MatchFinder::MatchCallback { +// public: +// virtual void Run(const MatchFinder::MatchResult &Result) { +// const CXXRecordDecl *Class = +// Result.Nodes.GetDeclAs<CXXRecordDecl>("id"); +// ... +// } +// }; +// +// int main(int argc, char **argv) { +// ClangTool Tool(argc, argv); +// MatchFinder finder; +// finder.AddMatcher(Id("id", record(hasName("::a_namespace::AClass"))), +// new HandleMatch); +// return Tool.Run(newFrontendActionFactory(&finder)); +// } +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H +#define LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H + +#include "clang/ASTMatchers/ASTMatchers.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Timer.h" +#include <optional> + +namespace clang { + +namespace ast_matchers { + +/// A class to allow finding matches over the Clang AST. +/// +/// After creation, you can add multiple matchers to the MatchFinder via +/// calls to addMatcher(...). +/// +/// Once all matchers are added, newASTConsumer() returns an ASTConsumer +/// that will trigger the callbacks specified via addMatcher(...) when a match +/// is found. +/// +/// The order of matches is guaranteed to be equivalent to doing a pre-order +/// traversal on the AST, and applying the matchers in the order in which they +/// were added to the MatchFinder. +/// +/// See ASTMatchers.h for more information about how to create matchers. +/// +/// Not intended to be subclassed. +class MatchFinder { +public: + /// Contains all information for a given match. + /// + /// Every time a match is found, the MatchFinder will invoke the registered + /// MatchCallback with a MatchResult containing information about the match. + struct MatchResult { + MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context); + + /// Contains the nodes bound on the current match. + /// + /// This allows user code to easily extract matched AST nodes. + const BoundNodes Nodes; + + /// Utilities for interpreting the matched AST structures. + /// @{ + clang::ASTContext * const Context; + clang::SourceManager * const SourceManager; + /// @} + }; + + /// Called when the Match registered for it was successfully found + /// in the AST. + class MatchCallback { + public: + virtual ~MatchCallback(); + + /// Called on every match by the \c MatchFinder. + virtual void run(const MatchResult &Result) = 0; + + /// Called at the start of each translation unit. + /// + /// Optionally override to do per translation unit tasks. + virtual void onStartOfTranslationUnit() {} + + /// Called at the end of each translation unit. + /// + /// Optionally override to do per translation unit tasks. + virtual void onEndOfTranslationUnit() {} + + /// An id used to group the matchers. + /// + /// This id is used, for example, for the profiling output. + /// It defaults to "<unknown>". + virtual StringRef getID() const; + + /// TraversalKind to use while matching and processing + /// the result nodes. This API is temporary to facilitate + /// third parties porting existing code to the default + /// behavior of clang-tidy. + virtual std::optional<TraversalKind> getCheckTraversalKind() const; + }; + + /// Called when parsing is finished. Intended for testing only. + class ParsingDoneTestCallback { + public: + virtual ~ParsingDoneTestCallback(); + virtual void run() = 0; + }; + + struct MatchFinderOptions { + struct Profiling { + Profiling(llvm::StringMap<llvm::TimeRecord> &Records) + : Records(Records) {} + + /// Per bucket timing information. + llvm::StringMap<llvm::TimeRecord> &Records; + }; + + /// Enables per-check timers. + /// + /// It prints a report after match. + std::optional<Profiling> CheckProfiling; + }; + + MatchFinder(MatchFinderOptions Options = MatchFinderOptions()); + ~MatchFinder(); + + /// Adds a matcher to execute when running over the AST. + /// + /// Calls 'Action' with the BoundNodes on every match. + /// Adding more than one 'NodeMatch' allows finding different matches in a + /// single pass over the AST. + /// + /// Does not take ownership of 'Action'. + /// @{ + void addMatcher(const DeclarationMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const TypeMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const StatementMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const NestedNameSpecifierMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const TypeLocMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const CXXCtorInitializerMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const TemplateArgumentLocMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const AttrMatcher &NodeMatch, MatchCallback *Action); + /// @} + + /// Adds a matcher to execute when running over the AST. + /// + /// This is similar to \c addMatcher(), but it uses the dynamic interface. It + /// is more flexible, but the lost type information enables a caller to pass + /// a matcher that cannot match anything. + /// + /// \returns \c true if the matcher is a valid top-level matcher, \c false + /// otherwise. + bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, + MatchCallback *Action); + + /// Creates a clang ASTConsumer that finds all matches. + std::unique_ptr<clang::ASTConsumer> newASTConsumer(); + + /// Calls the registered callbacks on all matches on the given \p Node. + /// + /// Note that there can be multiple matches on a single node, for + /// example when using decl(forEachDescendant(stmt())). + /// + /// @{ + template <typename T> void match(const T &Node, ASTContext &Context) { + match(clang::DynTypedNode::create(Node), Context); + } + void match(const clang::DynTypedNode &Node, ASTContext &Context); + /// @} + + /// Finds all matches in the given AST. + void matchAST(ASTContext &Context); + + /// Registers a callback to notify the end of parsing. + /// + /// The provided closure is called after parsing is done, before the AST is + /// traversed. Useful for benchmarking. + /// Each call to FindAll(...) will call the closure once. + void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone); + + /// For each \c Matcher<> a \c MatchCallback that will be called + /// when it matches. + struct MatchersByType { + std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *>> + DeclOrStmt; + std::vector<std::pair<TypeMatcher, MatchCallback *>> Type; + std::vector<std::pair<NestedNameSpecifierMatcher, MatchCallback *>> + NestedNameSpecifier; + std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>> + NestedNameSpecifierLoc; + std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc; + std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit; + std::vector<std::pair<TemplateArgumentLocMatcher, MatchCallback *>> + TemplateArgumentLoc; + std::vector<std::pair<AttrMatcher, MatchCallback *>> Attr; + /// All the callbacks in one container to simplify iteration. + llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks; + }; + +private: + MatchersByType Matchers; + + MatchFinderOptions Options; + + /// Called when parsing is done. + ParsingDoneTestCallback *ParsingDone; +}; + +/// Returns the results of matching \p Matcher on \p Node. +/// +/// Collects the \c BoundNodes of all callback invocations when matching +/// \p Matcher on \p Node and returns the collected results. +/// +/// Multiple results occur when using matchers like \c forEachDescendant, +/// which generate a result for each sub-match. +/// +/// If you want to find all matches on the sub-tree rooted at \c Node (rather +/// than only the matches on \c Node itself), surround the \c Matcher with a +/// \c findAll(). +/// +/// \see selectFirst +/// @{ +template <typename MatcherT, typename NodeT> +SmallVector<BoundNodes, 1> +match(MatcherT Matcher, const NodeT &Node, ASTContext &Context); + +template <typename MatcherT> +SmallVector<BoundNodes, 1> match(MatcherT Matcher, const DynTypedNode &Node, + ASTContext &Context); +/// @} + +/// Returns the results of matching \p Matcher on the translation unit of +/// \p Context and collects the \c BoundNodes of all callback invocations. +template <typename MatcherT> +SmallVector<BoundNodes, 1> match(MatcherT Matcher, ASTContext &Context); + +/// Returns the first result of type \c NodeT bound to \p BoundTo. +/// +/// Returns \c NULL if there is no match, or if the matching node cannot be +/// casted to \c NodeT. +/// +/// This is useful in combanation with \c match(): +/// \code +/// const Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"), +/// Node, Context)); +/// \endcode +template <typename NodeT> +const NodeT * +selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) { + for (const BoundNodes &N : Results) { + if (const NodeT *Node = N.getNodeAs<NodeT>(BoundTo)) + return Node; + } + return nullptr; +} + +namespace internal { +class CollectMatchesCallback : public MatchFinder::MatchCallback { +public: + void run(const MatchFinder::MatchResult &Result) override { + Nodes.push_back(Result.Nodes); + } + + std::optional<TraversalKind> getCheckTraversalKind() const override { + return std::nullopt; + } + + SmallVector<BoundNodes, 1> Nodes; +}; +} + +template <typename MatcherT> +SmallVector<BoundNodes, 1> match(MatcherT Matcher, const DynTypedNode &Node, + ASTContext &Context) { + internal::CollectMatchesCallback Callback; + MatchFinder Finder; + Finder.addMatcher(Matcher, &Callback); + Finder.match(Node, Context); + return std::move(Callback.Nodes); +} + +template <typename MatcherT, typename NodeT> +SmallVector<BoundNodes, 1> +match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) { + return match(Matcher, DynTypedNode::create(Node), Context); +} + +template <typename MatcherT> +SmallVector<BoundNodes, 1> +match(MatcherT Matcher, ASTContext &Context) { + internal::CollectMatchesCallback Callback; + MatchFinder Finder; + Finder.addMatcher(Matcher, &Callback); + Finder.matchAST(Context); + return std::move(Callback.Nodes); +} + +inline SmallVector<BoundNodes, 1> +matchDynamic(internal::DynTypedMatcher Matcher, const DynTypedNode &Node, + ASTContext &Context) { + internal::CollectMatchesCallback Callback; + MatchFinder Finder; + Finder.addDynamicMatcher(Matcher, &Callback); + Finder.match(Node, Context); + return std::move(Callback.Nodes); +} + +template <typename NodeT> +SmallVector<BoundNodes, 1> matchDynamic(internal::DynTypedMatcher Matcher, + const NodeT &Node, + ASTContext &Context) { + return matchDynamic(Matcher, DynTypedNode::create(Node), Context); +} + +inline SmallVector<BoundNodes, 1> +matchDynamic(internal::DynTypedMatcher Matcher, ASTContext &Context) { + internal::CollectMatchesCallback Callback; + MatchFinder Finder; + Finder.addDynamicMatcher(Matcher, &Callback); + Finder.matchAST(Context); + return std::move(Callback.Nodes); +} + +} // end namespace ast_matchers +} // end namespace clang + +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |