//===--- MacroRepeatedSideEffectsCheck.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 "MacroRepeatedSideEffectsCheck.h"
#include "clang/Basic/Builtins.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/MacroArgs.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"

namespace clang::tidy::bugprone {

namespace {
class MacroRepeatedPPCallbacks : public PPCallbacks {
public:
  MacroRepeatedPPCallbacks(ClangTidyCheck &Check, Preprocessor &PP)
      : Check(Check), PP(PP) {}

  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
                    SourceRange Range, const MacroArgs *Args) override;

private:
  ClangTidyCheck &Check;
  Preprocessor &PP;

  unsigned countArgumentExpansions(const MacroInfo *MI,
                                   const IdentifierInfo *Arg) const;

  bool hasSideEffects(const Token *ResultArgToks) const;
};
} // End of anonymous namespace.

void MacroRepeatedPPCallbacks::MacroExpands(const Token &MacroNameTok,
                                            const MacroDefinition &MD,
                                            SourceRange Range,
                                            const MacroArgs *Args) {
  // Ignore macro argument expansions.
  if (!Range.getBegin().isFileID())
    return;

  const MacroInfo *MI = MD.getMacroInfo();

  // Bail out if the contents of the macro are containing keywords that are
  // making the macro too complex.
  if (llvm::any_of(MI->tokens(), [](const Token &T) {
        return T.isOneOf(tok::kw_if, tok::kw_else, tok::kw_switch, tok::kw_case,
                         tok::kw_break, tok::kw_while, tok::kw_do, tok::kw_for,
                         tok::kw_continue, tok::kw_goto, tok::kw_return);
      }))
    return;

  for (unsigned ArgNo = 0U; ArgNo < MI->getNumParams(); ++ArgNo) {
    const IdentifierInfo *Arg = *(MI->param_begin() + ArgNo);
    const Token *ResultArgToks = Args->getUnexpArgument(ArgNo);

    if (hasSideEffects(ResultArgToks) &&
        countArgumentExpansions(MI, Arg) >= 2) {
      Check.diag(ResultArgToks->getLocation(),
                 "side effects in the %ordinal0 macro argument %1 are "
                 "repeated in macro expansion")
          << (ArgNo + 1) << Arg;
      Check.diag(MI->getDefinitionLoc(), "macro %0 defined here",
                 DiagnosticIDs::Note)
          << MacroNameTok.getIdentifierInfo();
    }
  }
}

unsigned MacroRepeatedPPCallbacks::countArgumentExpansions(
    const MacroInfo *MI, const IdentifierInfo *Arg) const {
  // Current argument count. When moving forward to a different control-flow
  // path this can decrease.
  unsigned Current = 0;
  // Max argument count.
  unsigned Max = 0;
  bool SkipParen = false;
  int SkipParenCount = 0;
  // Has a __builtin_constant_p been found?
  bool FoundBuiltin = false;
  bool PrevTokenIsHash = false;
  // Count when "?" is reached. The "Current" will get this value when the ":"
  // is reached.
  std::stack<unsigned, SmallVector<unsigned, 8>> CountAtQuestion;
  for (const auto &T : MI->tokens()) {
    // The result of __builtin_constant_p(x) is 0 if x is a macro argument
    // with side effects. If we see a __builtin_constant_p(x) followed by a
    // "?" "&&" or "||", then we need to reason about control flow to report
    // warnings correctly. Until such reasoning is added, bail out when this
    // happens.
    if (FoundBuiltin && T.isOneOf(tok::question, tok::ampamp, tok::pipepipe))
      return Max;

    // Skip stringified tokens.
    if (T.is(tok::hash)) {
      PrevTokenIsHash = true;
      continue;
    }
    if (PrevTokenIsHash) {
      PrevTokenIsHash = false;
      continue;
    }

    // Handling of ? and :.
    if (T.is(tok::question)) {
      CountAtQuestion.push(Current);
    } else if (T.is(tok::colon)) {
      if (CountAtQuestion.empty())
        return 0;
      Current = CountAtQuestion.top();
      CountAtQuestion.pop();
    }

    // If current token is a parenthesis, skip it.
    if (SkipParen) {
      if (T.is(tok::l_paren))
        SkipParenCount++;
      else if (T.is(tok::r_paren))
        SkipParenCount--;
      SkipParen = (SkipParenCount != 0);
      if (SkipParen)
        continue;
    }

    IdentifierInfo *TII = T.getIdentifierInfo();
    // If not existent, skip it.
    if (TII == nullptr)
      continue;

    // If a __builtin_constant_p is found within the macro definition, don't
    // count arguments inside the parentheses and remember that it has been
    // seen in case there are "?", "&&" or "||" operators later.
    if (TII->getBuiltinID() == Builtin::BI__builtin_constant_p) {
      FoundBuiltin = true;
      SkipParen = true;
      continue;
    }

    // If another macro is found within the macro definition, skip the macro
    // and the eventual arguments.
    if (TII->hasMacroDefinition()) {
      const MacroInfo *M = PP.getMacroDefinition(TII).getMacroInfo();
      if (M != nullptr && M->isFunctionLike())
        SkipParen = true;
      continue;
    }

    // Count argument.
    if (TII == Arg) {
      Current++;
      if (Current > Max)
        Max = Current;
    }
  }
  return Max;
}

bool MacroRepeatedPPCallbacks::hasSideEffects(
    const Token *ResultArgToks) const {
  for (; ResultArgToks->isNot(tok::eof); ++ResultArgToks) {
    if (ResultArgToks->isOneOf(tok::plusplus, tok::minusminus))
      return true;
  }
  return false;
}

void MacroRepeatedSideEffectsCheck::registerPPCallbacks(
    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
  PP->addPPCallbacks(::std::make_unique<MacroRepeatedPPCallbacks>(*this, *PP));
}

} // namespace clang::tidy::bugprone
