diff options
author | Rihan Yang <adam@air20.com> | 2020-01-08 14:09:29 -0500 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2020-01-08 14:10:11 -0500 |
commit | 2823e91d55891e33a7a8b9a4016db4ec9e2765ae (patch) | |
tree | 3cff8a06b1f09001bd0c7d252e61307851e8d490 /clang/lib | |
parent | b675a7628ce6a21b1e4a71c079a67badfb8b073d (diff) | |
download | bcm5719-llvm-2823e91d55891e33a7a8b9a4016db4ec9e2765ae.tar.gz bcm5719-llvm-2823e91d55891e33a7a8b9a4016db4ec9e2765ae.zip |
Add a new AST matcher 'optionally'.
This matcher matches any node and at the same time executes all its
inner matchers to produce any possbile result bindings.
This is useful when a user wants certain supplementary information
that's not always present along with the main match result.
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 27 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 |
2 files changed, 28 insertions, 0 deletions
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 75846ab2d4b..199a6d839e2 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -68,6 +68,11 @@ bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers); +bool OptionallyVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef<DynTypedMatcher> InnerMatchers); + void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) { if (Bindings.empty()) Bindings.push_back(BoundNodesMap()); @@ -184,6 +189,11 @@ DynTypedMatcher DynTypedMatcher::constructVariadic( SupportedKind, RestrictKind, new VariadicMatcher<EachOfVariadicOperator>(std::move(InnerMatchers))); + case VO_Optionally: + return DynTypedMatcher(SupportedKind, RestrictKind, + new VariadicMatcher<OptionallyVariadicOperator>( + std::move(InnerMatchers))); + case VO_UnaryNot: // FIXME: Implement the Not operator to take a single matcher instead of a // vector. @@ -347,6 +357,20 @@ bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, return false; } +bool OptionallyVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef<DynTypedMatcher> InnerMatchers) { + BoundNodesTreeBuilder Result; + for (const DynTypedMatcher &InnerMatcher : InnerMatchers) { + BoundNodesTreeBuilder BuilderInner(*Builder); + if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) + Result.addMatch(BuilderInner); + } + *Builder = std::move(Result); + return true; +} + inline static std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) { std::vector<std::string> Names; @@ -797,6 +821,9 @@ const internal::VariadicOperatorMatcherFunc< const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits<unsigned>::max()> allOf = {internal::DynTypedMatcher::VO_AllOf}; +const internal::VariadicOperatorMatcherFunc< + 1, std::numeric_limits<unsigned>::max()> + optionally = {internal::DynTypedMatcher::VO_Optionally}; const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, internal::hasAnyNameFunc> hasAnyName = {}; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 78b52d6fa2f..475818bc3ae 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -456,6 +456,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(on); REGISTER_MATCHER(onImplicitObjectArgument); REGISTER_MATCHER(opaqueValueExpr); + REGISTER_MATCHER(optionally); REGISTER_MATCHER(parameterCountIs); REGISTER_MATCHER(parenExpr); REGISTER_MATCHER(parenListExpr); |