Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -2843,6 +2843,39 @@ +
Matches FunctionDecls that have a noreturn attribute.
+
+Given
+ void nope();
+ [[noreturn]] void a0();
+ [[noreturn]] void a1() {}
+ __attribute__((noreturn)) void a2();
+ __attribute__((noreturn)) void a3() {}
+ struct b0 { [[noreturn]] b0(); };
+ struct b1 { [[noreturn]] b1() {} };
+ struct b2 { __attribute__((noreturn)) b2(); };
+ struct b3 { __attribute__((noreturn)) b3() {} };
+ struct c0 { [[noreturn]] int A(); };
+ struct c1 { [[noreturn]] int A() {} };
+ struct c2 { __attribute__((noreturn)) int A(); };
+ struct c3 { __attribute__((noreturn)) int A() {} };
+ struct d0 { [[noreturn]] static int A(); };
+ struct d1 { [[noreturn]] static int A() {} };
+ struct d2 { __attribute__((noreturn)) static int A(); };
+ struct d3 { __attribute__((noreturn)) static int A() {} };
+ extern "C" { void cNope(); }
+ extern "C" { __attribute__((noreturn)) void e0(); }
+ extern "C" { __attribute__((noreturn)) void e1() {} }
+ extern "C" { _Noreturn void e2(); }
+ extern "C" { _Noreturn void e3() {} }
+functionDecl(isNoReturn())
+ matches all of those except
+ void nope();
+ extern "C" { void cNope(); }
+Matches functions that have a non-throwing exception specification.
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3567,6 +3567,43 @@
return Node.getNumParams() == N;
}
+/// \brief Matches \c FunctionDecls that have a noreturn attribute.
+///
+/// Given
+/// \code
+/// void nope();
+/// [[noreturn]] void a0();
+/// [[noreturn]] void a1() {}
+/// __attribute__((noreturn)) void a2();
+/// __attribute__((noreturn)) void a3() {}
+/// struct b0 { [[noreturn]] b0(); };
+/// struct b1 { [[noreturn]] b1() {} };
+/// struct b2 { __attribute__((noreturn)) b2(); };
+/// struct b3 { __attribute__((noreturn)) b3() {} };
+/// struct c0 { [[noreturn]] int A(); };
+/// struct c1 { [[noreturn]] int A() {} };
+/// struct c2 { __attribute__((noreturn)) int A(); };
+/// struct c3 { __attribute__((noreturn)) int A() {} };
+/// struct d0 { [[noreturn]] static int A(); };
+/// struct d1 { [[noreturn]] static int A() {} };
+/// struct d2 { __attribute__((noreturn)) static int A(); };
+/// struct d3 { __attribute__((noreturn)) static int A() {} };
+/// extern "C" { void cNope(); }
+/// extern "C" { __attribute__((noreturn)) void e0(); }
+/// extern "C" { __attribute__((noreturn)) void e1() {} }
+/// extern "C" { _Noreturn void e2(); }
+/// extern "C" { _Noreturn void e3() {} }
+/// \endcode
+/// functionDecl(isNoReturn())
+/// matches all of those except
+/// \code
+/// void nope();
+/// extern "C" { void cNope(); }
+/// \endcode
+AST_MATCHER(FunctionDecl, isNoReturn) {
+ return Node.isNoReturn();
+}
+
/// \brief Matches the return type of a function declaration.
///
/// Given:
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -354,6 +354,7 @@
REGISTER_MATCHER(isMemberInitializer);
REGISTER_MATCHER(isMoveAssignmentOperator);
REGISTER_MATCHER(isMoveConstructor);
+ REGISTER_MATCHER(isNoReturn);
REGISTER_MATCHER(isNoThrow);
REGISTER_MATCHER(isOverride);
REGISTER_MATCHER(isPrivate);
Index: unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1770,6 +1770,84 @@
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()))));