//===--- MacroRepeatedSideEffectsCheck.cpp - clang-tidy--------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MacroRepeatedSideEffectsCheck.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/MacroArgs.h"

namespace clang {
namespace tidy {
namespace misc {

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 (std::find_if(
          MI->tokens().begin(), MI->tokens().end(), [](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);
          }) != MI->tokens().end())
    return;

  for (unsigned ArgNo = 0U; ArgNo < MI->getNumArgs(); ++ArgNo) {
    const IdentifierInfo *Arg = *(MI->arg_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->getName();
      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;
  // 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;

    // 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(
    CompilerInstance &Compiler) {
  Compiler.getPreprocessor().addPPCallbacks(
      ::llvm::make_unique<MacroRepeatedPPCallbacks>(
          *this, Compiler.getPreprocessor()));
}

} // namespace misc
} // namespace tidy
} // namespace clang
