summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/ASTMatchers/ASTMatchersInternal.cpp11
-rw-r--r--clang/lib/ASTMatchers/Dynamic/VariantValue.cpp44
2 files changed, 48 insertions, 7 deletions
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index e501ee64f7e..b95004a6d43 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -26,6 +26,17 @@ void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
}
}
+bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const {
+ const auto From = getSupportedKind();
+ auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>();
+ auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>();
+ /// Mimic the implicit conversions of Matcher<>.
+ /// - From Matcher<Type> to Matcher<QualType>
+ if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;
+ /// - From Matcher<Base> to Matcher<Derived>
+ return From.isBaseOf(To);
+}
+
DynTypedMatcher::MatcherStorage::~MatcherStorage() {}
void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 57c7b80d361..3d14157fcab 100644
--- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -49,7 +49,32 @@ bool ArgKind::isConvertibleTo(ArgKind To, unsigned *Specificity) const {
return true;
}
-VariantMatcher::MatcherOps::~MatcherOps() {}
+bool
+VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const {
+ IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
+ return Matcher.canConvertTo(NodeKind);
+}
+
+llvm::Optional<DynTypedMatcher>
+VariantMatcher::MatcherOps::constructVariadicOperator(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<VariantMatcher> InnerMatchers) const {
+ std::vector<DynTypedMatcher> DynMatchers;
+ for (const auto &InnerMatcher : InnerMatchers) {
+ // Abort if any of the inner matchers can't be converted to
+ // Matcher<T>.
+ if (!InnerMatcher.Value)
+ return llvm::None;
+ llvm::Optional<DynTypedMatcher> Inner =
+ InnerMatcher.Value->getTypedMatcher(*this);
+ if (!Inner)
+ return llvm::None;
+ DynMatchers.push_back(*Inner);
+ }
+ return DynTypedMatcher::constructVariadic(Func, DynMatchers);
+}
+
VariantMatcher::Payload::~Payload() {}
class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
@@ -65,10 +90,12 @@ public:
.str();
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
bool Ignore;
if (Ops.canConstructFrom(Matcher, Ignore))
- Ops.constructFrom(Matcher);
+ return Matcher;
+ return llvm::None;
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
@@ -104,7 +131,8 @@ public:
return (Twine("Matcher<") + Inner + ">").str();
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
bool FoundIsExact = false;
const DynTypedMatcher *Found = nullptr;
int NumFound = 0;
@@ -124,7 +152,8 @@ public:
}
// We only succeed if we found exactly one, or if we found an exact match.
if (Found && (FoundIsExact || NumFound == 1))
- Ops.constructFrom(*Found);
+ return *Found;
+ return llvm::None;
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
@@ -165,8 +194,9 @@ public:
return Inner;
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
- Ops.constructVariadicOperator(Func, Args);
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
+ return Ops.constructVariadicOperator(Func, Args);
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
OpenPOWER on IntegriCloud