Skip to content

Commit

Permalink
[ASTMatchers] Add isNoReturn() match narrower for FunctionDeclarations
Browse files Browse the repository at this point in the history
Reviewers: aaron.ballman

Reviewed By: aaron.ballman

Subscribers: dblaikie, klimek, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D41455

llvm-svn: 322746
  • Loading branch information
LebedevRI committed Jan 17, 2018
1 parent 48d030d commit 6c3871b
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
14 changes: 14 additions & 0 deletions clang/docs/LibASTMatchersReference.html
Expand Up @@ -2843,6 +2843,20 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
</pre></td></tr>


<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isNoReturn0')"><a name="isNoReturn0Anchor">isNoReturn</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isNoReturn0"><pre>Matches FunctionDecls that have a noreturn attribute.

Given
void nope();
[[noreturn]] void a();
__attribute__((noreturn)) void b();
struct c { [[noreturn]] c(); };
functionDecl(isNoReturn())
matches all of those except
void nope();
</pre></td></tr>


<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isNoThrow0')"><a name="isNoThrow0Anchor">isNoThrow</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isNoThrow0"><pre>Matches functions that have a non-throwing exception specification.

Expand Down
18 changes: 18 additions & 0 deletions clang/include/clang/ASTMatchers/ASTMatchers.h
Expand Up @@ -3567,6 +3567,24 @@ AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
return Node.getNumParams() == N;
}

/// \brief Matches \c FunctionDecls that have a noreturn attribute.
///
/// Given
/// \code
/// void nope();
/// [[noreturn]] void a();
/// __attribute__((noreturn)) void b();
/// struct c { [[noreturn]] c(); };
/// \endcode
/// functionDecl(isNoReturn())
/// matches all of those except
/// \code
/// void nope();
/// \endcode
AST_MATCHER(FunctionDecl, isNoReturn) {
return Node.isNoReturn();
}

/// \brief Matches the return type of a function declaration.
///
/// Given:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/ASTMatchers/Dynamic/Registry.cpp
Expand Up @@ -354,6 +354,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isMemberInitializer);
REGISTER_MATCHER(isMoveAssignmentOperator);
REGISTER_MATCHER(isMoveConstructor);
REGISTER_MATCHER(isNoReturn);
REGISTER_MATCHER(isNoThrow);
REGISTER_MATCHER(isOverride);
REGISTER_MATCHER(isPrivate);
Expand Down
78 changes: 78 additions & 0 deletions clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
Expand Up @@ -1770,6 +1770,84 @@ TEST(IsExplicitTemplateSpecialization,
functionDecl(isExplicitTemplateSpecialization())));
}

TEST(TypeMatching, MatchesNoReturn) {
EXPECT_TRUE(notMatches("void func();", functionDecl(isNoReturn())));
EXPECT_TRUE(notMatches("void func() {}", functionDecl(isNoReturn())));

EXPECT_TRUE(notMatchesC("void func();", functionDecl(isNoReturn())));
EXPECT_TRUE(notMatchesC("void func() {}", functionDecl(isNoReturn())));

EXPECT_TRUE(
notMatches("struct S { void func(); };", functionDecl(isNoReturn())));
EXPECT_TRUE(
notMatches("struct S { void func() {} };", functionDecl(isNoReturn())));

EXPECT_TRUE(notMatches("struct S { static void func(); };",
functionDecl(isNoReturn())));
EXPECT_TRUE(notMatches("struct S { static void func() {} };",
functionDecl(isNoReturn())));

EXPECT_TRUE(notMatches("struct S { S(); };", functionDecl(isNoReturn())));
EXPECT_TRUE(notMatches("struct S { S() {} };", functionDecl(isNoReturn())));

// ---

EXPECT_TRUE(matches("[[noreturn]] void func();", functionDecl(isNoReturn())));
EXPECT_TRUE(
matches("[[noreturn]] void func() {}", functionDecl(isNoReturn())));

EXPECT_TRUE(matches("struct S { [[noreturn]] void func(); };",
functionDecl(isNoReturn())));
EXPECT_TRUE(matches("struct S { [[noreturn]] void func() {} };",
functionDecl(isNoReturn())));

EXPECT_TRUE(matches("struct S { [[noreturn]] static void func(); };",
functionDecl(isNoReturn())));
EXPECT_TRUE(matches("struct S { [[noreturn]] static void func() {} };",
functionDecl(isNoReturn())));

EXPECT_TRUE(
matches("struct S { [[noreturn]] S(); };", functionDecl(isNoReturn())));
EXPECT_TRUE(matches("struct S { [[noreturn]] S() {} };",
functionDecl(isNoReturn())));

// ---

EXPECT_TRUE(matches("__attribute__((noreturn)) void func();",
functionDecl(isNoReturn())));
EXPECT_TRUE(matches("__attribute__((noreturn)) void func() {}",
functionDecl(isNoReturn())));

EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func(); };",
functionDecl(isNoReturn())));
EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func() {} };",
functionDecl(isNoReturn())));

EXPECT_TRUE(
matches("struct S { __attribute__((noreturn)) static void func(); };",
functionDecl(isNoReturn())));
EXPECT_TRUE(
matches("struct S { __attribute__((noreturn)) static void func() {} };",
functionDecl(isNoReturn())));

EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S(); };",
functionDecl(isNoReturn())));
EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S() {} };",
functionDecl(isNoReturn())));

// ---

EXPECT_TRUE(matchesC("__attribute__((noreturn)) void func();",
functionDecl(isNoReturn())));
EXPECT_TRUE(matchesC("__attribute__((noreturn)) void func() {}",
functionDecl(isNoReturn())));

EXPECT_TRUE(matchesC("_Noreturn void func();",
functionDecl(isNoReturn())));
EXPECT_TRUE(matchesC("_Noreturn void func() {}",
functionDecl(isNoReturn())));
}

TEST(TypeMatching, MatchesBool) {
EXPECT_TRUE(matches("struct S { bool func(); };",
cxxMethodDecl(returns(booleanType()))));
Expand Down

0 comments on commit 6c3871b

Please sign in to comment.