From: Nathan James Date: Wed, 23 Feb 2022 08:33:58 +0000 (+0000) Subject: [ASTMatchers] Expand isInline matcher to VarDecl X-Git-Tag: upstream/15.0.7~15597 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c34d89818341b3c7c96bc8f59e3f98063d4ae9fd;p=platform%2Fupstream%2Fllvm.git [ASTMatchers] Expand isInline matcher to VarDecl Add support to the `isInline` matcher for C++17's inline variables. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D118900 --- diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index a3f5799..d552f4c 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -4322,7 +4322,7 @@ varDecl(isExternC()) Matcher<FunctionDecl>isInline -
Matches function and namespace declarations that are marked with
+
Matches functions, variables and namespace declarations that are marked with
 the inline keyword.
 
 Given
@@ -4331,8 +4331,10 @@ Given
   namespace n {
   inline namespace m {}
   }
+  inline int Foo = 5;
 functionDecl(isInline()) will match ::f().
 namespaceDecl(isInline()) will match n::m.
+varDecl(isInline()) will match Foo;
 
@@ -4697,7 +4699,7 @@ namespaceDecl(isAnonymous()) will match #1 but not ::n. Matcher<NamespaceDecl>isInline -
Matches function and namespace declarations that are marked with
+
Matches functions, variables and namespace declarations that are marked with
 the inline keyword.
 
 Given
@@ -4706,8 +4708,10 @@ Given
   namespace n {
   inline namespace m {}
   }
+  inline int Foo = 5;
 functionDecl(isInline()) will match ::f().
 namespaceDecl(isInline()) will match n::m.
+varDecl(isInline()) will match Foo;
 
@@ -5728,6 +5732,23 @@ auto f = [x=3]() { return x; };
+Matcher<VarDecl>isInline +
Matches functions, variables and namespace declarations that are marked with
+the inline keyword.
+
+Given
+  inline void f();
+  void g();
+  namespace n {
+  inline namespace m {}
+  }
+  inline int Foo = 5;
+functionDecl(isInline()) will match ::f().
+namespaceDecl(isInline()) will match n::m.
+varDecl(isInline()) will match Foo;
+
+ + Matcher<VarDecl>isStaticLocal
Matches a static variable with local scope.
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 68a8674..4131c02 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -186,6 +186,8 @@ Build System Changes
 AST Matchers
 ------------
 
+- Expanded ``isInline`` narrowing matcher to support c++17 inline variables.
+
 clang-format
 ------------
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 86bd440..6664a5b 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -7673,7 +7673,7 @@ AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher,
   return InnerMatcher.matches(*ES.getExpr(), Finder, Builder);
 }
 
-/// Matches function and namespace declarations that are marked with
+/// Matches functions, variables and namespace declarations that are marked with
 /// the inline keyword.
 ///
 /// Given
@@ -7683,18 +7683,22 @@ AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher,
 ///   namespace n {
 ///   inline namespace m {}
 ///   }
+///   inline int Foo = 5;
 /// \endcode
 /// functionDecl(isInline()) will match ::f().
 /// namespaceDecl(isInline()) will match n::m.
-AST_POLYMORPHIC_MATCHER(isInline,
-                        AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,
-                                                        FunctionDecl)) {
+/// varDecl(isInline()) will match Foo;
+AST_POLYMORPHIC_MATCHER(isInline, AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,
+                                                                  FunctionDecl,
+                                                                  VarDecl)) {
   // This is required because the spelling of the function used to determine
   // whether inline is specified or not differs between the polymorphic types.
   if (const auto *FD = dyn_cast(&Node))
     return FD->isInlineSpecified();
-  else if (const auto *NSD = dyn_cast(&Node))
+  if (const auto *NSD = dyn_cast(&Node))
     return NSD->isInline();
+  if (const auto *VD = dyn_cast(&Node))
+    return VD->isInline();
   llvm_unreachable("Not a valid polymorphic type");
 }
 
diff --git a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
index 6fec0d2..2766065 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -197,6 +197,8 @@ TEST(IsInlineMatcher, IsInline) {
                       functionDecl(isInline(), hasName("f"))));
   EXPECT_TRUE(matches("namespace n { inline namespace m {} }",
                       namespaceDecl(isInline(), hasName("m"))));
+  EXPECT_TRUE(matches("inline int Foo = 5;",
+                      varDecl(isInline(), hasName("Foo")), {Lang_CXX17}));
 }
 
 // FIXME: Figure out how to specify paths so the following tests pass on