//===- ArgList.cpp - Argument List Management -----------------------------===//
//
// 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 "llvm/Option/ArgList.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/OptSpecifier.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <memory>
#include <string>
#include <utility>
#include <vector>

using namespace llvm;
using namespace llvm::opt;

void ArgList::append(Arg *A) {
  Args.push_back(A);

  // Update ranges for the option and all of its groups.
  for (Option O = A->getOption().getUnaliasedOption(); O.isValid();
       O = O.getGroup()) {
    auto &R =
        OptRanges.insert(std::make_pair(O.getID(), emptyRange())).first->second;
    R.first = std::min<unsigned>(R.first, Args.size() - 1);
    R.second = Args.size();
  }
}

void ArgList::eraseArg(OptSpecifier Id) {
  // Zero out the removed entries but keep them around so that we don't
  // need to invalidate OptRanges.
  for (Arg *const &A : filtered(Id)) {
    // Avoid the need for a non-const filtered iterator variant.
    Arg **ArgsBegin = Args.data();
    ArgsBegin[&A - ArgsBegin] = nullptr;
  }
  OptRanges.erase(Id.getID());
}

ArgList::OptRange
ArgList::getRange(std::initializer_list<OptSpecifier> Ids) const {
  OptRange R = emptyRange();
  for (auto Id : Ids) {
    auto I = OptRanges.find(Id.getID());
    if (I != OptRanges.end()) {
      R.first = std::min(R.first, I->second.first);
      R.second = std::max(R.second, I->second.second);
    }
  }
  // Map an empty {-1, 0} range to {0, 0} so it can be used to form iterators.
  if (R.first == -1u)
    R.first = 0;
  return R;
}

bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
  if (Arg *A = getLastArg(Pos, Neg))
    return A->getOption().matches(Pos);
  return Default;
}

bool ArgList::hasFlagNoClaim(OptSpecifier Pos, OptSpecifier Neg,
                             bool Default) const {
  if (Arg *A = getLastArgNoClaim(Pos, Neg))
    return A->getOption().matches(Pos);
  return Default;
}

bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
                      bool Default) const {
  if (Arg *A = getLastArg(Pos, PosAlias, Neg))
    return A->getOption().matches(Pos) || A->getOption().matches(PosAlias);
  return Default;
}

StringRef ArgList::getLastArgValue(OptSpecifier Id, StringRef Default) const {
  if (Arg *A = getLastArg(Id))
    return A->getValue();
  return Default;
}

std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
  SmallVector<const char *, 16> Values;
  AddAllArgValues(Values, Id);
  return std::vector<std::string>(Values.begin(), Values.end());
}

void ArgList::addOptInFlag(ArgStringList &Output, OptSpecifier Pos,
                           OptSpecifier Neg) const {
  if (Arg *A = getLastArg(Pos, Neg))
    if (A->getOption().matches(Pos))
      A->render(*this, Output);
}

void ArgList::AddAllArgsExcept(ArgStringList &Output,
                               ArrayRef<OptSpecifier> Ids,
                               ArrayRef<OptSpecifier> ExcludeIds) const {
  for (const Arg *Arg : *this) {
    bool Excluded = false;
    for (OptSpecifier Id : ExcludeIds) {
      if (Arg->getOption().matches(Id)) {
        Excluded = true;
        break;
      }
    }
    if (!Excluded) {
      for (OptSpecifier Id : Ids) {
        if (Arg->getOption().matches(Id)) {
          Arg->claim();
          Arg->render(*this, Output);
          break;
        }
      }
    }
  }
}

/// This is a nicer interface when you don't have a list of Ids to exclude.
void ArgList::addAllArgs(ArgStringList &Output,
                         ArrayRef<OptSpecifier> Ids) const {
  ArrayRef<OptSpecifier> Exclude = {};
  AddAllArgsExcept(Output, Ids, Exclude);
}

void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const {
  for (auto *Arg : filtered(Id0)) {
    Arg->claim();
    Arg->render(*this, Output);
  }
}

void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
                              OptSpecifier Id1, OptSpecifier Id2) const {
  for (auto *Arg : filtered(Id0, Id1, Id2)) {
    Arg->claim();
    const auto &Values = Arg->getValues();
    Output.append(Values.begin(), Values.end());
  }
}

void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
                                   const char *Translation,
                                   bool Joined) const {
  for (auto *Arg : filtered(Id0)) {
    Arg->claim();

    if (Joined) {
      Output.push_back(MakeArgString(StringRef(Translation) +
                                     Arg->getValue(0)));
    } else {
      Output.push_back(Translation);
      Output.push_back(Arg->getValue(0));
    }
  }
}

void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
  for (auto *Arg : filtered(Id0))
    Arg->claim();
}

void ArgList::ClaimAllArgs() const {
  for (auto *Arg : *this)
    if (!Arg->isClaimed())
      Arg->claim();
}

const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
                                              StringRef LHS,
                                              StringRef RHS) const {
  StringRef Cur = getArgString(Index);
  if (Cur.size() == LHS.size() + RHS.size() && Cur.starts_with(LHS) &&
      Cur.ends_with(RHS))
    return Cur.data();

  return MakeArgString(LHS + RHS);
}

void ArgList::print(raw_ostream &O) const {
  for (Arg *A : *this) {
    O << "* ";
    A->print(O);
  }
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void ArgList::dump() const { print(dbgs()); }
#endif

void InputArgList::releaseMemory() {
  // An InputArgList always owns its arguments.
  for (Arg *A : *this)
    delete A;
}

InputArgList::InputArgList(const char* const *ArgBegin,
                           const char* const *ArgEnd)
  : NumInputArgStrings(ArgEnd - ArgBegin) {
  ArgStrings.append(ArgBegin, ArgEnd);
}

unsigned InputArgList::MakeIndex(StringRef String0) const {
  unsigned Index = ArgStrings.size();

  // Tuck away so we have a reliable const char *.
  SynthesizedStrings.push_back(std::string(String0));
  ArgStrings.push_back(SynthesizedStrings.back().c_str());

  return Index;
}

unsigned InputArgList::MakeIndex(StringRef String0,
                                 StringRef String1) const {
  unsigned Index0 = MakeIndex(String0);
  unsigned Index1 = MakeIndex(String1);
  assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
  (void) Index1;
  return Index0;
}

const char *InputArgList::MakeArgStringRef(StringRef Str) const {
  return getArgString(MakeIndex(Str));
}

DerivedArgList::DerivedArgList(const InputArgList &BaseArgs)
    : BaseArgs(BaseArgs) {}

const char *DerivedArgList::MakeArgStringRef(StringRef Str) const {
  return BaseArgs.MakeArgString(Str);
}

void DerivedArgList::AddSynthesizedArg(Arg *A) {
  SynthesizedArgs.push_back(std::unique_ptr<Arg>(A));
}

Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
  SynthesizedArgs.push_back(
      std::make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
                       BaseArgs.MakeIndex(Opt.getName()), BaseArg));
  return SynthesizedArgs.back().get();
}

Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
                                       StringRef Value) const {
  unsigned Index = BaseArgs.MakeIndex(Value);
  SynthesizedArgs.push_back(
      std::make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
                       Index, BaseArgs.getArgString(Index), BaseArg));
  return SynthesizedArgs.back().get();
}

Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
                                     StringRef Value) const {
  unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
  SynthesizedArgs.push_back(
      std::make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
                       Index, BaseArgs.getArgString(Index + 1), BaseArg));
  return SynthesizedArgs.back().get();
}

Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
                                   StringRef Value) const {
  unsigned Index = BaseArgs.MakeIndex((Opt.getName() + Value).str());
  SynthesizedArgs.push_back(std::make_unique<Arg>(
      Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index,
      BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg));
  return SynthesizedArgs.back().get();
}
