diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -4347,6 +4347,19 @@ +
Matches function declarations that are either marked with +the inline keyword or are implicitly inline. + +Given + class A { + void f() {} + void g(); + }; +functionDecl(isEffectivelyInline()) will match ::f(). +
Determines whether the function is "main", which is the entry point into an executable program. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -7777,6 +7777,19 @@ llvm_unreachable("Not a valid polymorphic type"); } +/// Matches function declarations that are either marked with +/// the inline keyword or are implicitly inline. +/// +/// Given +/// \code +/// class A { +/// void f() {} +/// void g(); +/// }; +/// \endcode +/// functionDecl(isEffectivelyInline()) will match f(). +AST_MATCHER(FunctionDecl, isEffectivelyInline) { return Node.isInlined(); } + /// Matches anonymous namespace declarations. /// /// Given diff --git a/clang/include/clang/ASTMatchers/ASTMatchersMacros.h b/clang/include/clang/ASTMatchers/ASTMatchersMacros.h --- a/clang/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -93,7 +93,7 @@ /// The code should return true if 'Node' matches. #define AST_MATCHER(Type, DefineMatcher) \ namespace internal { \ - class matcher_##DefineMatcher##Matcher \ + class matcher_##DefineMatcher##Matcher final \ : public ::clang::ast_matchers::internal::MatcherInterface{ \ public: \ explicit matcher_##DefineMatcher##Matcher() = default; \ diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -432,6 +432,7 @@ REGISTER_MATCHER(isInTemplateInstantiation); REGISTER_MATCHER(isInitCapture); REGISTER_MATCHER(isInline); + REGISTER_MATCHER(isEffectivelyInline); REGISTER_MATCHER(isInstanceMessage); REGISTER_MATCHER(isInstanceMethod); REGISTER_MATCHER(isInstantiated); diff --git a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp @@ -306,6 +306,14 @@ varDecl(isInline(), hasName("Foo")), {Lang_CXX17})); } +TEST(IsInlineMatcher, IsEffectivelyInline) { + EXPECT_TRUE(matches("class X { void f() {} void g(); };", + functionDecl(isEffectivelyInline(), hasName("f")))); + EXPECT_TRUE(matches("constexpr int f() { return 0; }", + functionDecl(isEffectivelyInline(), hasName("f")), + {Lang_CXX11})); +} + // FIXME: Figure out how to specify paths so the following tests pass on // Windows. #ifndef _WIN32