//===--- 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 {

namespace {
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");
}

AST_POLYMORPHIC_MATCHER_P(isInternalLinkage,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                          VarDecl),
                          bool, StrictMode) {
  if (!StrictMode)
    return false;
  if (const auto *FD = dyn_cast<FunctionDecl>(&Node))
    return FD->getStorageClass() == SC_Static || FD->isInAnonymousNamespace();
  if (const auto *VD = dyn_cast<VarDecl>(&Node))
    return VD->isInAnonymousNamespace();
  llvm_unreachable("Not a valid polymorphic type");
}
} // namespace

static SourceLocation getInlineTokenLocation(SourceRange RangeLocation,
                                             const SourceManager &Sources,
                                             const LangOptions &LangOpts) {
  SourceLocation Loc = RangeLocation.getBegin();
  if (Loc.isMacroID())
    return {};

  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 {};
}

void RedundantInlineSpecifierCheck::registerMatchers(MatchFinder *Finder) {
  const auto IsPartOfRecordDecl = hasAncestor(recordDecl());
  Finder->addMatcher(
      functionDecl(isInlineSpecified(),
                   anyOf(isConstexpr(), isDeleted(),
                         allOf(isDefaulted(), IsPartOfRecordDecl),
                         isInternalLinkage(StrictMode),
                         allOf(isDefinition(), IsPartOfRecordDecl)))
          .bind("fun_decl"),
      this);

  if (StrictMode)
    Finder->addMatcher(
        functionTemplateDecl(
            has(functionDecl(allOf(isInlineSpecified(), isDefinition()))))
            .bind("templ_decl"),
        this);

  if (getLangOpts().CPlusPlus17) {
    Finder->addMatcher(
        varDecl(
            isInlineSpecified(),
            anyOf(allOf(isInternalLinkage(StrictMode),
                        unless(allOf(hasInitializer(expr()), IsPartOfRecordDecl,
                                     isStaticStorageClass()))),
                  allOf(isConstexpr(), IsPartOfRecordDecl)))
            .bind("var_decl"),
        this);
  }
}

template <typename T>
void RedundantInlineSpecifierCheck::handleMatchedDecl(
    const T *MatchedDecl, const SourceManager &Sources,
    const MatchFinder::MatchResult &Result, StringRef Message) {
  SourceLocation Loc = getInlineTokenLocation(
      MatchedDecl->getSourceRange(), Sources, Result.Context->getLangOpts());
  if (Loc.isValid())
    diag(Loc, Message) << MatchedDecl << FixItHint::CreateRemoval(Loc);
}

void RedundantInlineSpecifierCheck::check(
    const MatchFinder::MatchResult &Result) {
  const SourceManager &Sources = *Result.SourceManager;

  if (const auto *MatchedDecl =
          Result.Nodes.getNodeAs<FunctionDecl>("fun_decl")) {
    handleMatchedDecl(
        MatchedDecl, Sources, Result,
        "function %0 has inline specifier but is implicitly inlined");
  } else if (const auto *MatchedDecl =
                 Result.Nodes.getNodeAs<VarDecl>("var_decl")) {
    handleMatchedDecl(
        MatchedDecl, Sources, Result,
        "variable %0 has inline specifier but is implicitly inlined");
  } else if (const auto *MatchedDecl =
                 Result.Nodes.getNodeAs<FunctionTemplateDecl>("templ_decl")) {
    handleMatchedDecl(
        MatchedDecl, Sources, Result,
        "function %0 has inline specifier but is implicitly inlined");
  }
}

} // namespace clang::tidy::readability
