=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin,
=?utf-8?q?Félix-Antoine?= Constantin
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/73...@github.com>


================
@@ -0,0 +1,113 @@
+//===--- RedundantInlineSpecifierCheck.cpp - 
clang-tidy--------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RedundantInlineSpecifierCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Token.h"
+
+#include "../utils/LexerUtils.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+AST_POLYMORPHIC_MATCHER(isInlineSpecified,
+                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+                                                        VarDecl)) {
+  if (const auto *FD = dyn_cast<FunctionDecl>(&Node))
+    return FD->isInlineSpecified();
+  if (const auto *VD = dyn_cast<VarDecl>(&Node))
+    return VD->isInlineSpecified();
+  llvm_unreachable("Not a valid polymorphic type");
+}
+
+static std::optional<SourceLocation>
+getInlineTokenLocation(SourceRange RangeLocation, const SourceManager &Sources,
+                       const LangOptions &LangOpts) {
+  SourceLocation Loc = RangeLocation.getBegin();
+  if (Loc.isMacroID())
+    return std::nullopt;
+
+  Token FirstToken;
+  Lexer::getRawToken(Loc, FirstToken, Sources, LangOpts, true);
+  std::optional<Token> CurrentToken = FirstToken;
+  while (CurrentToken && CurrentToken->getLocation() < RangeLocation.getEnd() 
&&
+         CurrentToken->isNot(tok::eof)) {
+    if (CurrentToken->is(tok::raw_identifier) &&
+        CurrentToken->getRawIdentifier() == "inline")
+      return CurrentToken->getLocation();
+
+    CurrentToken =
+        Lexer::findNextToken(CurrentToken->getLocation(), Sources, LangOpts);
+  }
+  return std::nullopt;
+}
+
+void RedundantInlineSpecifierCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      functionDecl(isInlineSpecified(),
+                   anyOf(isConstexpr(), isDeleted(), isDefaulted(),
+                         isInAnonymousNamespace(),
----------------
PiotrZSL wrote:

To be honest I'm not so sure about anonymous namespace, static keyword, and 
templates.
Looks like in those cases those functions are inline only due to optimizations, 
not because they "inline".

This is more visible in GCC when you use attribute:
```inline int __attribute__((always_inline))  fn2(int i) ```
if you change inline to static, or put this in anonymous namespace you get 
warning:
`warning: 'always_inline' function might not be inlinable [-Wattributes]`

Best would be add "StrictMode" option to check, and when set to true then emit 
warning also for templates and static and anonymous namespace, and when set to 
false, emit it only for class members and constexpr.
Please investigate it more.

https://github.com/llvm/llvm-project/pull/73069
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to