Izaron created this revision.
Izaron added reviewers: klimek, aaron.ballman.
Izaron requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Inline variables is a feature from C++17. It makes sense
to extend the `isInline` matcher in order to support corresponding varDecls.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D118922

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/ReleaseNotes.rst
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===================================================================
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1455,6 +1455,23 @@
       "int main() { int x = 3; auto f = [vd=x]() { return vd; }; }", M));
 }
 
+TEST_P(ASTMatchersTest, IsInline) {
+  if (!GetParam().isCXX() && !GetParam().isC99OrLater())
+    return;
+  EXPECT_TRUE(matches("void g(); inline void f();",
+                      functionDecl(isInline(), hasName("f"))));
+
+  if (!GetParam().isCXX())
+    return;
+  EXPECT_TRUE(matches("namespace n { inline namespace m {} }",
+                      namespaceDecl(isInline(), hasName("m"))));
+
+  if (!GetParam().isCXX17OrLater())
+    return;
+  EXPECT_TRUE(matches("inline constexpr int i = 1;",
+                      varDecl(isInline(), hasName("i"))));
+}
+
 TEST_P(ASTMatchersTest, StorageDuration) {
   StringRef T =
       "void f() { int x; static int y; } int a;static int b;extern int c;";
Index: clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
===================================================================
--- clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -192,13 +192,6 @@
               llvm::ValueIs(TK_IgnoreUnlessSpelledInSource));
 }
 
-TEST(IsInlineMatcher, IsInline) {
-  EXPECT_TRUE(matches("void g(); inline void f();",
-                      functionDecl(isInline(), hasName("f"))));
-  EXPECT_TRUE(matches("namespace n { inline namespace m {} }",
-                      namespaceDecl(isInline(), hasName("m"))));
-}
-
 // FIXME: Figure out how to specify paths so the following tests pass on
 // Windows.
 #ifndef _WIN32
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -7673,25 +7673,29 @@
   return InnerMatcher.matches(*ES.getExpr(), Finder, Builder);
 }
 
-/// Matches function and namespace declarations that are marked with
+/// Matches variable, function and namespace declarations that are marked with
 /// the inline keyword.
 ///
 /// Given
 /// \code
+///   inline constexpr int i = 1;
 ///   inline void f();
 ///   void g();
 ///   namespace n {
 ///   inline namespace m {}
 ///   }
 /// \endcode
+/// varDecl(isInline()) will match ::i.
 /// functionDecl(isInline()) will match ::f().
 /// namespaceDecl(isInline()) will match n::m.
 AST_POLYMORPHIC_MATCHER(isInline,
-                        AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,
-                                                        FunctionDecl)) {
+                        AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl, FunctionDecl,
+                                                        NamespaceDecl)) {
   // 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<FunctionDecl>(&Node))
+  if (const auto *VD = dyn_cast<VarDecl>(&Node))
+    return VD->isInline();
+  else if (const auto *FD = dyn_cast<FunctionDecl>(&Node))
     return FD->isInlineSpecified();
   else if (const auto *NSD = dyn_cast<NamespaceDecl>(&Node))
     return NSD->isInline();
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -135,6 +135,8 @@
 AST Matchers
 ------------
 
+- The ``isInline`` matcher now accepts inline variable declarations.
+
 clang-format
 ------------
 
Index: clang/docs/LibASTMatchersReference.html
===================================================================
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4310,15 +4310,17 @@
 
 
 <tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html";>FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isInline1')"><a name="isInline1Anchor">isInline</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="isInline1"><pre>Matches function and namespace declarations that are marked with
+<tr><td colspan="4" class="doc" id="isInline1"><pre>Matches variable, function and namespace declarations that are marked with
 the inline keyword.
 
 Given
+  inline constexpr int i = 1;
   inline void f();
   void g();
   namespace n {
   inline namespace m {}
   }
+varDecl(isInline()) will match ::i.
 functionDecl(isInline()) will match ::f().
 namespaceDecl(isInline()) will match n::m.
 </pre></td></tr>
@@ -4689,11 +4691,13 @@
 the inline keyword.
 
 Given
+  inline constexpr int i = 1;
   inline void f();
   void g();
   namespace n {
   inline namespace m {}
   }
+varDecl(isInline()) will match ::i.
 functionDecl(isInline()) will match ::f().
 namespaceDecl(isInline()) will match n::m.
 </pre></td></tr>
@@ -5716,6 +5720,23 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1VarDecl.html";>VarDecl</a>&gt;</td><td class="name" onclick="toggle('isInline2')"><a name="isInline2Anchor">isInline</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isInline2"><pre>Matches variable, function and namespace declarations that are marked with
+the inline keyword.
+
+Given
+  inline constexpr int i = 1;
+  inline void f();
+  void g();
+  namespace n {
+  inline namespace m {}
+  }
+varDecl(isInline()) will match ::i.
+functionDecl(isInline()) will match ::f().
+namespaceDecl(isInline()) will match n::m.
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1VarDecl.html";>VarDecl</a>&gt;</td><td class="name" onclick="toggle('isStaticLocal0')"><a name="isStaticLocal0Anchor">isStaticLocal</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isStaticLocal0"><pre>Matches a static variable with local scope.
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to