diff options
author | Samuel Benzaquen <sbenza@google.com> | 2013-11-22 14:41:48 +0000 |
---|---|---|
committer | Samuel Benzaquen <sbenza@google.com> | 2013-11-22 14:41:48 +0000 |
commit | 4d05874ba2e1a7116c1eac22ab0eca537795cb75 (patch) | |
tree | e2a35f80fff4d5655fda9c3e312bd23a58964583 /clang/lib | |
parent | bf9b24edc3d62989e420d6ea0b1cf1ae8f6bcac3 (diff) | |
download | bcm5719-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.cpp | 20 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Marshallers.h | 27 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 2 |
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); |