[PATCH] Add loc() to the dynamic registry.
Samuel Benzaquen
sbenza at google.com
Mon Mar 3 07:48:12 PST 2014
Hi klimek,
Add loc() to the dynamic registry.
Other fixes:
- Fix the polymorphic variant value to accept an exact match, even if
there are other possible conversions.
- Fix specifiesTypeLoc() to not crash on an empty
NestedNameSpecifierLoc.
http://llvm-reviews.chandlerc.com/D2928
Files:
include/clang/ASTMatchers/ASTMatchers.h
include/clang/ASTMatchers/Dynamic/VariantValue.h
lib/ASTMatchers/Dynamic/Registry.cpp
lib/ASTMatchers/Dynamic/VariantValue.cpp
unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -2824,6 +2824,9 @@
return internal::BindableMatcher<TypeLoc>(
new internal::TypeLocTypeMatcher(InnerMatcher));
}
+/// Signature for the registry.
+typedef internal::BindableMatcher<TypeLoc>(&loc_Type0)(
+ const internal::Matcher<QualType> &);
/// \brief Matches builtin Types.
///
@@ -3309,6 +3312,9 @@
new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>(
InnerMatcher));
}
+/// Signature for the registry.
+typedef internal::BindableMatcher<NestedNameSpecifierLoc>(&loc_Type1)(
+ const internal::Matcher<NestedNameSpecifier> &);
/// \brief Matches nested name specifiers that specify a type matching the
/// given \c QualType matcher without qualifiers.
@@ -3340,7 +3346,7 @@
/// matches "A::"
AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
internal::Matcher<TypeLoc>, InnerMatcher) {
- return InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
+ return Node && InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
}
/// \brief Matches on the prefix of a \c NestedNameSpecifier.
Index: include/clang/ASTMatchers/Dynamic/VariantValue.h
===================================================================
--- include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -50,7 +50,8 @@
class MatcherOps {
public:
virtual ~MatcherOps();
- virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const = 0;
+ virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const = 0;
virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
virtual void constructVariadicOperator(
ast_matchers::internal::VariadicOperatorFunction Func,
@@ -145,7 +146,10 @@
public:
typedef ast_matchers::internal::Matcher<T> MatcherT;
- virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const {
+ virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const {
+ IsExactMatch = Matcher.getSupportedKind().isSame(
+ ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
return Matcher.canConvertTo<T>();
}
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -79,15 +79,15 @@
// findAll
//
// Other:
- // loc
// equals
// equalsNode
REGISTER_OVERLOADED_2(callee);
REGISTER_OVERLOADED_2(hasPrefix);
REGISTER_OVERLOADED_2(hasType);
REGISTER_OVERLOADED_2(isDerivedFrom);
REGISTER_OVERLOADED_2(isSameOrDerivedFrom);
+ REGISTER_OVERLOADED_2(loc);
REGISTER_OVERLOADED_2(pointsTo);
REGISTER_OVERLOADED_2(references);
REGISTER_OVERLOADED_2(thisPointerType);
Index: lib/ASTMatchers/Dynamic/VariantValue.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -38,7 +38,8 @@
}
virtual void makeTypedMatcher(MatcherOps &Ops) const {
- if (Ops.canConstructFrom(Matcher))
+ bool Ignore;
+ if (Ops.canConstructFrom(Matcher, Ignore))
Ops.constructFrom(Matcher);
}
@@ -70,15 +71,25 @@
}
virtual void makeTypedMatcher(MatcherOps &Ops) const {
+ bool FoundIsExact = false;
const DynTypedMatcher *Found = NULL;
+ int NumFound = 0;
for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
- if (Ops.canConstructFrom(Matchers[i])) {
- if (Found)
- return;
+ bool IsExactMatch;
+ if (Ops.canConstructFrom(Matchers[i], IsExactMatch)) {
+ if (Found) {
+ if (FoundIsExact) {
+ assert(!IsExactMatch && "We should not have two exact matches.");
+ continue;
+ }
+ }
Found = &Matchers[i];
+ FoundIsExact = IsExactMatch;
+ ++NumFound;
}
}
- if (Found)
+ // We only succeed if we found exactly one, or if we found an exact match.
+ if (Found && (FoundIsExact || NumFound == 1))
Ops.constructFrom(*Found);
}
Index: unittests/ASTMatchers/Dynamic/RegistryTest.cpp
===================================================================
--- unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -67,7 +67,7 @@
VariantMatcher Out;
if (Ctor)
Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(Arg1), Error);
- EXPECT_EQ("", DummyError.toStringFull());
+ EXPECT_EQ("", DummyError.toStringFull()) << MatcherName;
return Out;
}
@@ -168,6 +168,25 @@
Code = "class Z { public: void z() { this->z(); } };";
EXPECT_TRUE(matches(Code, CallExpr0));
EXPECT_FALSE(matches(Code, CallExpr1));
+
+ Matcher<Decl> DeclDecl = declaratorDecl(hasTypeLoc(
+ constructMatcher(
+ "loc", constructMatcher("asString", std::string("const double *")))
+ .getTypedMatcher<TypeLoc>()));
+
+ Matcher<NestedNameSpecifierLoc> NNSL =
+ constructMatcher(
+ "loc", VariantMatcher::SingleMatcher(nestedNameSpecifier(
+ specifiesType(hasDeclaration(recordDecl(hasName("A")))))))
+ .getTypedMatcher<NestedNameSpecifierLoc>();
+
+ Code = "const double * x = 0;";
+ EXPECT_TRUE(matches(Code, DeclDecl));
+ EXPECT_FALSE(matches(Code, NNSL));
+
+ Code = "struct A { struct B {}; }; A::B a_b;";
+ EXPECT_FALSE(matches(Code, DeclDecl));
+ EXPECT_TRUE(matches(Code, NNSL));
}
TEST_F(RegistryTest, PolymorphicMatchers) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2928.1.patch
Type: text/x-patch
Size: 5853 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140303/d64171a8/attachment.bin>
More information about the cfe-commits
mailing list