summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRihan Yang <adam@air20.com>2020-01-08 14:09:29 -0500
committerAaron Ballman <aaron@aaronballman.com>2020-01-08 14:10:11 -0500
commit2823e91d55891e33a7a8b9a4016db4ec9e2765ae (patch)
tree3cff8a06b1f09001bd0c7d252e61307851e8d490 /clang/lib
parentb675a7628ce6a21b1e4a71c079a67badfb8b073d (diff)
downloadbcm5719-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.cpp27
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Registry.cpp1
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);
OpenPOWER on IntegriCloud