//===- 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/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.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/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Option/OptSpecifier.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::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::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
  if (Arg *A = getLastArg(Id)) {
    A->claim();
    A->render(*this, Output);
  }
}

void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0,
                         OptSpecifier Id1) const {
  if (Arg *A = getLastArg(Id0, Id1)) {
    A->claim();
    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 = None;
  AddAllArgsExcept(Output, Ids, Exclude);
}

/// This 3-opt variant of AddAllArgs could be eliminated in favor of one
/// that accepts a single specifier, given the above which accepts any number.
void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
                         OptSpecifier Id1, OptSpecifier Id2) const {
  for (auto Arg: filtered(Id0, Id1, Id2)) {
    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.startswith(LHS) && Cur.endswith(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(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(
      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(
      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(
      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(make_unique<Arg>(
      Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index,
      BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg));
  return SynthesizedArgs.back().get();
}
