summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorSamuel Benzaquen <sbenza@google.com>2013-11-22 14:41:48 +0000
committerSamuel Benzaquen <sbenza@google.com>2013-11-22 14:41:48 +0000
commit4d05874ba2e1a7116c1eac22ab0eca537795cb75 (patch)
treee2a35f80fff4d5655fda9c3e312bd23a58964583 /clang/lib
parentbf9b24edc3d62989e420d6ea0b1cf1ae8f6bcac3 (diff)
downloadbcm5719-llvm-4d05874ba2e1a7116c1eac22ab0eca537795cb75.tar.gz
bcm5719-llvm-4d05874ba2e1a7116c1eac22ab0eca537795cb75.zip
Add support for the 'unless' matcher in the dynamic layer.
Summary: Add support for the 'unless' matcher in the dynamic layer. Reviewers: klimek CC: cfe-commits, revane, klimek Differential Revision: http://llvm-reviews.chandlerc.com/D2247 llvm-svn: 195466
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/ASTMatchers/ASTMatchersInternal.cpp20
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Marshallers.h27
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Registry.cpp2
3 files changed, 42 insertions, 7 deletions
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index d15eb54002f..47b8b6d2f27 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -34,6 +34,26 @@ void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
}
}
+bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ ArrayRef<DynTypedMatcher> InnerMatchers) {
+ if (InnerMatchers.size() != 1)
+ return false;
+
+ // The 'unless' matcher will always discard the result:
+ // If the inner matcher doesn't match, unless returns true,
+ // but the inner matcher cannot have bound anything.
+ // If the inner matcher matches, the result is false, and
+ // any possible binding will be discarded.
+ // We still need to hand in all the bound nodes up to this
+ // point so the inner matcher can depend on bound nodes,
+ // and we need to actively discard the bound nodes, otherwise
+ // the inner matcher will reset the bound nodes if it doesn't
+ // match, but this would be inversed by 'unless'.
+ BoundNodesTreeBuilder Discard(*Builder);
+ return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
+}
+
bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
index ae0c300d094..2f9db9c56b7 100644
--- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -347,12 +347,22 @@ private:
class VariadicOperatorMatcherCreateCallback : public MatcherCreateCallback {
public:
typedef ast_matchers::internal::VariadicOperatorFunction VarFunc;
- VariadicOperatorMatcherCreateCallback(VarFunc Func, StringRef MatcherName)
- : Func(Func), MatcherName(MatcherName) {}
+ VariadicOperatorMatcherCreateCallback(unsigned MinCount, unsigned MaxCount,
+ VarFunc Func, StringRef MatcherName)
+ : MinCount(MinCount), MaxCount(MaxCount), Func(Func),
+ MatcherName(MatcherName) {}
virtual VariantMatcher run(const SourceRange &NameRange,
ArrayRef<ParserValue> Args,
Diagnostics *Error) const {
+ if (Args.size() < MinCount || MaxCount < Args.size()) {
+ const std::string MaxStr =
+ (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str();
+ Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
+ << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
+ return VariantMatcher();
+ }
+
std::vector<VariantMatcher> InnerArgs;
for (size_t i = 0, e = Args.size(); i != e; ++i) {
const ParserValue &Arg = Args[i];
@@ -368,6 +378,8 @@ public:
}
private:
+ const unsigned MinCount;
+ const unsigned MaxCount;
const VarFunc Func;
const StringRef MatcherName;
};
@@ -439,10 +451,13 @@ AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>::collect(
}
/// \brief Variadic operator overload.
-MatcherCreateCallback *makeMatcherAutoMarshall(
- ast_matchers::internal::VariadicOperatorMatcherFunc Func,
- StringRef MatcherName) {
- return new VariadicOperatorMatcherCreateCallback(Func.Func, MatcherName);
+template <unsigned MinCount, unsigned MaxCount>
+MatcherCreateCallback *
+makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc<
+ MinCount, MaxCount> Func,
+ StringRef MatcherName) {
+ return new VariadicOperatorMatcherCreateCallback(MinCount, MaxCount,
+ Func.Func, MatcherName);
}
} // namespace internal
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 70e956e6546..a19cdc06e9f 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -76,7 +76,6 @@ RegistryMaps::RegistryMaps() {
// ofKind
//
// Polymorphic + argument overload:
- // unless
// findAll
//
// Other:
@@ -285,6 +284,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(typedefType);
REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
REGISTER_MATCHER(unaryOperator);
+ REGISTER_MATCHER(unless);
REGISTER_MATCHER(userDefinedLiteral);
REGISTER_MATCHER(usingDecl);
REGISTER_MATCHER(varDecl);
OpenPOWER on IntegriCloud