</pre></td></tr>\r
\r
\r
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isCopyAssignmentOperator0')"><a name="isCopyAssignmentOperator0Anchor">isCopyAssignmentOperator</a></td><td></td></tr>\r
+<tr><td colspan="4" class="doc" id="isCopyAssignmentOperator0"><pre>Matches if the given method declaration declares a copy assignment\r
+operator.\r
+\r
+Given\r
+struct A {\r
+ A &operator=(const A &);\r
+ A &operator=(A &&);\r
+};\r
+\r
+cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not\r
+the second one.\r
+</pre></td></tr>\r
+\r
+\r
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isFinal1')"><a name="isFinal1Anchor">isFinal</a></td><td></td></tr>\r
<tr><td colspan="4" class="doc" id="isFinal1"><pre>Matches if the given method or class declaration is final.\r
\r
</pre></td></tr>\r
\r
\r
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('hasAutomaticStorageDuration0')"><a name="hasAutomaticStorageDuration0Anchor">hasAutomaticStorageDuration</a></td><td></td></tr>\r
+<tr><td colspan="4" class="doc" id="hasAutomaticStorageDuration0"><pre>Matches a variable declaration that has automatic storage duration.\r
+\r
+Example matches x, but not y, z, or a.\r
+(matcher = varDecl(hasAutomaticStorageDuration())\r
+void f() {\r
+ int x;\r
+ static int y;\r
+ thread_local int z;\r
+}\r
+int a;\r
+</pre></td></tr>\r
+\r
+\r
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('hasGlobalStorage0')"><a name="hasGlobalStorage0Anchor">hasGlobalStorage</a></td><td></td></tr>\r
<tr><td colspan="4" class="doc" id="hasGlobalStorage0"><pre>Matches a variable declaration that does not have local storage.\r
\r
</pre></td></tr>\r
\r
\r
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('hasStaticStorageDuration0')"><a name="hasStaticStorageDuration0Anchor">hasStaticStorageDuration</a></td><td></td></tr>\r
+<tr><td colspan="4" class="doc" id="hasStaticStorageDuration0"><pre>Matches a variable declaration that has static storage duration.\r
+\r
+Example matches y and a, but not x or z.\r
+(matcher = varDecl(hasStaticStorageDuration())\r
+void f() {\r
+ int x;\r
+ static int y;\r
+ thread_local int z;\r
+}\r
+int a;\r
+</pre></td></tr>\r
+\r
+\r
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('hasThreadStorageDuration0')"><a name="hasThreadStorageDuration0Anchor">hasThreadStorageDuration</a></td><td></td></tr>\r
+<tr><td colspan="4" class="doc" id="hasThreadStorageDuration0"><pre>Matches a variable declaration that has thread storage duration.\r
+\r
+Example matches z, but not x, z, or a.\r
+(matcher = varDecl(hasThreadStorageDuration())\r
+void f() {\r
+ int x;\r
+ static int y;\r
+ thread_local int z;\r
+}\r
+int a;\r
+</pre></td></tr>\r
+\r
+\r
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('isConstexpr0')"><a name="isConstexpr0Anchor">isConstexpr</a></td><td></td></tr>\r
<tr><td colspan="4" class="doc" id="isConstexpr0"><pre>Matches constexpr variable and function declarations.\r
\r
</pre></td></tr>\r
\r
\r
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>></td><td class="name" onclick="toggle('hasLHS1')"><a name="hasLHS1Anchor">hasLHS</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>\r
+<tr><td colspan="4" class="doc" id="hasLHS1"><pre>Matches the left hand side of binary operator expressions.\r
+\r
+Example matches a (matcher = binaryOperator(hasLHS()))\r
+ a || b\r
+</pre></td></tr>\r
+\r
+\r
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>></td><td class="name" onclick="toggle('hasRHS1')"><a name="hasRHS1Anchor">hasRHS</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>\r
+<tr><td colspan="4" class="doc" id="hasRHS1"><pre>Matches the right hand side of binary operator expressions.\r
+\r
+Example matches b (matcher = binaryOperator(hasRHS()))\r
+ a || b\r
+</pre></td></tr>\r
+\r
+\r
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArrayTypeLoc.html">ArrayTypeLoc</a>></td><td class="name" onclick="toggle('hasElementTypeLoc0')"><a name="hasElementTypeLoc0Anchor">hasElementTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>\r
<tr><td colspan="4" class="doc" id="hasElementTypeLoc0"><pre>Matches arrays and C99 complex types that have a specific element\r
type.\r
return Node.hasGlobalStorage();
}
+/// \brief Matches a variable declaration that has automatic storage duration.
+///
+/// Example matches x, but not y, z, or a.
+/// (matcher = varDecl(hasAutomaticStorageDuration())
+/// \code
+/// void f() {
+/// int x;
+/// static int y;
+/// thread_local int z;
+/// }
+/// int a;
+/// \endcode
+AST_MATCHER(VarDecl, hasAutomaticStorageDuration) {
+ return Node.getStorageDuration() == SD_Automatic;
+}
+
+/// \brief Matches a variable declaration that has static storage duration.
+///
+/// Example matches y and a, but not x or z.
+/// (matcher = varDecl(hasStaticStorageDuration())
+/// \code
+/// void f() {
+/// int x;
+/// static int y;
+/// thread_local int z;
+/// }
+/// int a;
+/// \endcode
+AST_MATCHER(VarDecl, hasStaticStorageDuration) {
+ return Node.getStorageDuration() == SD_Static;
+}
+
+/// \brief Matches a variable declaration that has thread storage duration.
+///
+/// Example matches z, but not x, z, or a.
+/// (matcher = varDecl(hasThreadStorageDuration())
+/// \code
+/// void f() {
+/// int x;
+/// static int y;
+/// thread_local int z;
+/// }
+/// int a;
+/// \endcode
+AST_MATCHER(VarDecl, hasThreadStorageDuration) {
+ return Node.getStorageDuration() == SD_Thread;
+}
+
/// \brief Matches a variable declaration that is an exception variable from
/// a C++ catch block, or an Objective-C \@catch statement.
///
REGISTER_MATCHER(hasArgument);
REGISTER_MATCHER(hasArgumentOfType);
REGISTER_MATCHER(hasAttr);
+ REGISTER_MATCHER(hasAutomaticStorageDuration);
REGISTER_MATCHER(hasBase);
REGISTER_MATCHER(hasBody);
REGISTER_MATCHER(hasCanonicalType);
REGISTER_MATCHER(hasSize);
REGISTER_MATCHER(hasSizeExpr);
REGISTER_MATCHER(hasSourceExpression);
+ REGISTER_MATCHER(hasThreadStorageDuration);
REGISTER_MATCHER(hasTargetDecl);
REGISTER_MATCHER(hasTemplateArgument);
REGISTER_MATCHER(hasThen);
+ REGISTER_MATCHER(hasThreadStorageDuration);
REGISTER_MATCHER(hasTrueExpression);
REGISTER_MATCHER(hasTypeLoc);
REGISTER_MATCHER(hasUnaryOperand);
EXPECT_TRUE(matches("void f() { static int X; }", M));
}
+TEST(Matcher, VarDecl_StorageDuration) {
+ std::string T =
+ "void f() { int x; static int y; thread_local int z; } int a;";
+
+ EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
+ EXPECT_TRUE(
+ notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
+ EXPECT_TRUE(
+ notMatches(T, varDecl(hasName("z"), hasAutomaticStorageDuration())));
+ EXPECT_TRUE(
+ notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
+
+ EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
+ EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
+ EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
+ EXPECT_TRUE(notMatches(T, varDecl(hasName("z"), hasStaticStorageDuration())));
+
+ EXPECT_TRUE(matches(T, varDecl(hasName("z"), hasThreadStorageDuration())));
+ EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
+ EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
+ EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
+}
+
TEST(Matcher, FindsVarDeclInFunctionParameter) {
EXPECT_TRUE(matches(
"void f(int i) {}",