]> granicus.if.org Git - clang/commitdiff
Adding a narrowing AST matcher for FunctionDecl::isVariadic(), plus tests and documen...
authorAaron Ballman <aaron@aaronballman.com>
Mon, 5 Oct 2015 14:41:27 +0000 (14:41 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Mon, 5 Oct 2015 14:41:27 +0000 (14:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@249321 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LibASTMatchersReference.html
include/clang/ASTMatchers/ASTMatchers.h
lib/ASTMatchers/Dynamic/Registry.cpp
unittests/ASTMatchers/ASTMatchersTest.cpp
unittests/ASTMatchers/ASTMatchersTest.h

index 47666a13867ca9a675b248f90188491542f1aa04..cab709e3a643f4155f5b650e14b3e34cb098510e 100644 (file)
@@ -2210,6 +2210,18 @@ Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Functi
 </pre></td></tr>\r
 \r
 \r
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isVariadic0')"><a name="isVariadic0Anchor">isVariadic</a></td><td></td></tr>\r
+<tr><td colspan="4" class="doc" id="isVariadic0"><pre>Matches if a function declaration is variadic.\r
+\r
+Example matches f, but not g or h. The function i will not match, event when\r
+compiled in C mode.\r
+  void f(...);\r
+  void g(int);\r
+  template &lt;typename... Ts&gt; void h(Ts...);\r
+  void i();\r
+</pre></td></tr>\r
+\r
+\r
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('parameterCountIs0')"><a name="parameterCountIs0Anchor">parameterCountIs</a></td><td>unsigned N</td></tr>\r
 <tr><td colspan="4" class="doc" id="parameterCountIs0"><pre>Matches FunctionDecls that have a specific parameter count.\r
 \r
index 5a14eef72a8fb1dd459b0907b34866c51e2cdf74..cfed1fd16deb3af4dd78ecdf41ff91a5a4c78d63 100644 (file)
@@ -3255,6 +3255,20 @@ AST_POLYMORPHIC_MATCHER(isDefinition,
   return Node.isThisDeclarationADefinition();
 }
 
+/// \brief Matches if a function declaration is variadic.
+///
+/// Example matches f, but not g or h. The function i will not match, even when
+/// compiled in C mode.
+/// \code
+///   void f(...);
+///   void g(int);
+///   template <typename... Ts> void h(Ts...);
+///   void i();
+/// \endcode
+AST_MATCHER(FunctionDecl, isVariadic) {
+  return Node.isVariadic();
+}
+
 /// \brief Matches the class declaration that the given method declaration
 /// belongs to.
 ///
index 1bf4c5b21d19f53c3ba22f761152ff3170304975..81e3ffd8f91fdac422d8f0e64d5f393146878dca 100644 (file)
@@ -291,6 +291,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(isStruct);
   REGISTER_MATCHER(isTemplateInstantiation);
   REGISTER_MATCHER(isUnion);
+  REGISTER_MATCHER(isVariadic);
   REGISTER_MATCHER(isVirtual);
   REGISTER_MATCHER(isWritten);
   REGISTER_MATCHER(labelStmt);
index 7f553513daa9a428be5c12f0da476a9b5fe9e683..a15d6ac2be57bfb794eff58c55c6ab9171a59e98 100644 (file)
@@ -1511,6 +1511,13 @@ TEST(Function, MatchesFunctionDeclarations) {
       notMatches("void f(int);"
                  "template <typename T> struct S { void g(T t) { f(t); } };",
                  CallFunctionF));
+
+  EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic())));
+  EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic())));
+  EXPECT_TRUE(notMatches("template <typename... Ts> void f(Ts...);",
+                         functionDecl(isVariadic())));
+  EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic())));
+  EXPECT_TRUE(notMatchesC("void f();", functionDecl(isVariadic())));
 }
 
 TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
index 285d2630cea676df38cececd4f0d1eb8b899df2f..9ed7ef66e511945e7aca2ea0a80944ff00163856 100644 (file)
@@ -125,6 +125,13 @@ testing::AssertionResult matchesC(const std::string &Code, const T &AMatcher) {
                               "input.c");
 }
 
+template <typename T>
+testing::AssertionResult notMatchesC(const std::string &Code,
+                                     const T &AMatcher) {
+  return matchesConditionally(Code, AMatcher, false, "", FileContentMappings(),
+                              "input.c");
+}
+
 template <typename T>
 testing::AssertionResult notMatchesObjC(const std::string &Code,
                                      const T &AMatcher) {