Closed by commit rL219622 (authored by @sbenza).

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D5731

Files:
  cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
  cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
  cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -591,6 +591,11 @@
   EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
   EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
                          ClassXHasNotClassY));
+
+  DeclarationMatcher NamedNotRecord =
+      namedDecl(hasName("Foo"), unless(recordDecl()));
+  EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
+  EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
 }
 
 TEST(DeclarationMatcher, HasDescendant) {
Index: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
===================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -380,6 +380,13 @@
 
   EXPECT_FALSE(matches("class Bar{ int Foo; };", D));
   EXPECT_TRUE(matches("class OtherBar{ int Foo; };", D));
+
+  D = constructMatcher(
+          "namedDecl", constructMatcher("hasName", std::string("Foo")),
+          constructMatcher("unless", constructMatcher("recordDecl")))
+          .getTypedMatcher<Decl>();
+  EXPECT_TRUE(matches("void Foo(){}", D));
+  EXPECT_TRUE(notMatches("struct Foo {};", D));
 }
 
 TEST_F(RegistryTest, Errors) {
Index: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
===================================================================
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -89,18 +89,19 @@
 DynTypedMatcher DynTypedMatcher::constructVariadic(
     VariadicOperatorFunction Func, std::vector<DynTypedMatcher> InnerMatchers) {
   assert(InnerMatchers.size() > 0 && "Array must not be empty.");
-  DynTypedMatcher Result = InnerMatchers[0];
-  // Use the least derived type as the restriction for the wrapper.
-  // This allows mismatches to be resolved on the inner matchers.
-  for (const DynTypedMatcher &M : InnerMatchers) {
-    assert(Result.SupportedKind.isSame(M.SupportedKind) &&
-           "SupportedKind must match!");
-    Result.RestrictKind =
-        ast_type_traits::ASTNodeKind::getMostDerivedCommonAncestor(
-            Result.RestrictKind, M.RestrictKind);
-  }
-  Result.Implementation = new VariadicMatcher(Func, std::move(InnerMatchers));
-  return Result;
+  assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(),
+                     [&InnerMatchers](const DynTypedMatcher &M) {
+           return InnerMatchers[0].SupportedKind.isSame(M.SupportedKind);
+         }) &&
+         "SupportedKind must match!");
+
+  // We must relax the restrict kind here.
+  // The different operators might deal differently with a mismatch.
+  // Make it the same as SupportedKind, since that is the broadest type we are
+  // allowed to accept.
+  return DynTypedMatcher(InnerMatchers[0].SupportedKind,
+                         InnerMatchers[0].SupportedKind,
+                         new VariadicMatcher(Func, std::move(InnerMatchers)));
 }
 
 DynTypedMatcher DynTypedMatcher::trueMatcher(
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to