From 56cc8f8880db2ebc433eeb6b6a707c101467a186 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 14 Nov 2017 14:17:26 +0000 Subject: [PATCH] Make isDefinition matcher support ObjCMethodDecl Summary: Allow the `isDefinition()` matcher to apply to `ObjCMethodDecl` nodes, in addition to those it already supports. For whatever reason, `ObjCMethodDecl` does not inherit from `FunctionDecl` and so this is specialization is necessary. Reviewers: aaron.ballman, malcolm.parsons, alexshap Reviewed By: aaron.ballman Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D39948 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@318152 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LibASTMatchersReference.html | 53 +++++++++++++++++-- include/clang/ASTMatchers/ASTMatchers.h | 10 +++- .../ASTMatchers/ASTMatchersNarrowingTest.cpp | 8 +++ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index c0221c1c66..295b0b1e43 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -2746,8 +2746,8 @@ functionDecl(isDefaulted()) -Matcher<FunctionDecl>isDefinition -
Matches if a declaration has a body attached.
+Matcher<FunctionDecl>isDefinition
+
Matches if a declaration has a body attached.
 
 Example matches A, va, fa
   class A {};
@@ -2756,8 +2756,15 @@ Example matches A, va, fa
   extern int vb;  Doesn't match, as it doesn't define the variable.
   void fa() {}
   void fb();  Doesn't match, as it has no body.
+  @interface X
+  - (void)ma; Doesn't match, interface is declaration.
+  @end
+  @implementation X
+  - (void)ma {}
+  @end
 
-Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
+Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
+  Matcher<ObjCMethodDecl>
 
@@ -3154,6 +3161,28 @@ a substring matched by the given RegExp.
+Matcher<ObjCMethodDecl>isDefinition +
Matches if a declaration has a body attached.
+
+Example matches A, va, fa
+  class A {};
+  class B;  Doesn't match, as it has no body.
+  int va;
+  extern int vb;  Doesn't match, as it doesn't define the variable.
+  void fa() {}
+  void fb();  Doesn't match, as it has no body.
+  @interface X
+  - (void)ma; Doesn't match, interface is declaration.
+  @end
+  @implementation X
+  - (void)ma {}
+  @end
+
+Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
+  Matcher<ObjCMethodDecl>
+
+ + Matcher<QualType>asStringstd::string Name
Matches if the matched type is represented by the given string.
 
@@ -3433,8 +3462,15 @@ Example matches A, va, fa
   extern int vb;  Doesn't match, as it doesn't define the variable.
   void fa() {}
   void fb();  Doesn't match, as it has no body.
+  @interface X
+  - (void)ma; Doesn't match, interface is declaration.
+  @end
+  @implementation X
+  - (void)ma {}
+  @end
 
-Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
+Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
+  Matcher<ObjCMethodDecl>
 
@@ -3696,8 +3732,15 @@ Example matches A, va, fa extern int vb; Doesn't match, as it doesn't define the variable. void fa() {} void fb(); Doesn't match, as it has no body. + @interface X + - (void)ma; Doesn't match, interface is declaration. + @end + @implementation X + - (void)ma {} + @end -Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl> +Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>, + Matcher<ObjCMethodDecl> diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index c2abb983eb..657ce126d4 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -4201,11 +4201,19 @@ AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression, /// extern int vb; // Doesn't match, as it doesn't define the variable. /// void fa() {} /// void fb(); // Doesn't match, as it has no body. +/// @interface X +/// - (void)ma; // Doesn't match, interface is declaration. +/// @end +/// @implementation X +/// - (void)ma {} +/// @end /// \endcode /// -/// Usable as: Matcher, Matcher, Matcher +/// Usable as: Matcher, Matcher, Matcher, +/// Matcher AST_POLYMORPHIC_MATCHER(isDefinition, AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl, + ObjCMethodDecl, FunctionDecl)) { return Node.isThisDeclarationADefinition(); } diff --git a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 7bc8421bab..3858384e55 100644 --- a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1315,6 +1315,14 @@ TEST(Matcher, IsDefinition) { cxxMethodDecl(hasName("a"), isDefinition()); EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA)); EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA)); + + DeclarationMatcher DefinitionOfObjCMethodA = + objcMethodDecl(hasName("a"), isDefinition()); + EXPECT_TRUE(matchesObjC("@interface A @end " + "@implementation A; -(void)a {} @end", + DefinitionOfObjCMethodA)); + EXPECT_TRUE(notMatchesObjC("@interface A; - (void)a; @end", + DefinitionOfObjCMethodA)); } TEST(Matcher, HandlesNullQualTypes) { -- 2.40.0