llvm/llvm/include/llvm/Support/CommandLine.h

//===- llvm/Support/CommandLine.h - Command line handler --------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This class implements a command line argument processor that is useful when
// creating a tool.  It provides a simple, minimalistic interface that is easily
// extensible and supports nonlocal (library) command line options.
//
// Note that rather than trying to figure out what this code does, you should
// read the library documentation located in docs/CommandLine.html or looks at
// the many example usages in tools/*/*.cpp
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_COMMANDLINE_H
#define LLVM_SUPPORT_COMMANDLINE_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <climits>
#include <cstddef>
#include <functional>
#include <initializer_list>
#include <string>
#include <type_traits>
#include <vector>

namespace llvm {

namespace vfs {
class FileSystem;
}

class StringSaver;

/// This namespace contains all of the command line option processing machinery.
/// It is intentionally a short name to make qualified usage concise.
namespace cl {

//===----------------------------------------------------------------------===//
// Command line option processing entry point.
//
// Returns true on success. Otherwise, this will print the error message to
// stderr and exit if \p Errs is not set (nullptr by default), or print the
// error message to \p Errs and return false if \p Errs is provided.
//
// If EnvVar is not nullptr, command-line options are also parsed from the
// environment variable named by EnvVar.  Precedence is given to occurrences
// from argv.  This precedence is currently implemented by parsing argv after
// the environment variable, so it is only implemented correctly for options
// that give precedence to later occurrences.  If your program supports options
// that give precedence to earlier occurrences, you will need to extend this
// function to support it correctly.
bool ParseCommandLineOptions(int argc, const char *const *argv,
                             StringRef Overview = "",
                             raw_ostream *Errs = nullptr,
                             const char *EnvVar = nullptr,
                             bool LongOptionsUseDoubleDash = false);

// Function pointer type for printing version information.
VersionPrinterTy;

///===---------------------------------------------------------------------===//
/// Override the default (LLVM specific) version printer used to print out the
/// version when --version is given on the command line. This allows other
/// systems using the CommandLine utilities to print their own version string.
void SetVersionPrinter(VersionPrinterTy func);

///===---------------------------------------------------------------------===//
/// Add an extra printer to use in addition to the default one. This can be
/// called multiple times, and each time it adds a new function to the list
/// which will be called after the basic LLVM version printing is complete.
/// Each can then add additional information specific to the tool.
void AddExtraVersionPrinter(VersionPrinterTy func);

// Print option values.
// With -print-options print the difference between option values and defaults.
// With -print-all-options print all option values.
// (Currently not perfect, but best-effort.)
void PrintOptionValues();

// Forward declaration - AddLiteralOption needs to be up here to make gcc happy.
class Option;

/// Adds a new option for parsing and provides the option it refers to.
///
/// \param O pointer to the option
/// \param Name the string name for the option to handle during parsing
///
/// Literal options are used by some parsers to register special option values.
/// This is how the PassNameParser registers pass names for opt.
void AddLiteralOption(Option &O, StringRef Name);

//===----------------------------------------------------------------------===//
// Flags permitted to be passed to command line arguments
//

enum NumOccurrencesFlag {};

enum ValueExpected {};

enum OptionHidden {};

// This controls special features that the option might have that cause it to be
// parsed differently...
//
// Prefix - This option allows arguments that are otherwise unrecognized to be
// matched by options that are a prefix of the actual value.  This is useful for
// cases like a linker, where options are typically of the form '-lfoo' or
// '-L../../include' where -l or -L are the actual flags.  When prefix is
// enabled, and used, the value for the flag comes from the suffix of the
// argument.
//
// AlwaysPrefix - Only allow the behavior enabled by the Prefix flag and reject
// the Option=Value form.
//

enum FormattingFlags {};

enum MiscFlags {};

//===----------------------------------------------------------------------===//
//
class OptionCategory {};

// The general Option Category (used as default category).
OptionCategory &getGeneralCategory();

//===----------------------------------------------------------------------===//
//
class SubCommand {};

class SubCommandGroup {};

//===----------------------------------------------------------------------===//
//
class Option {};

//===----------------------------------------------------------------------===//
// Command line option modifiers that can be used to modify the behavior of
// command line option parsers...
//

// Modifier to set the description shown in the -help output...
struct desc {};

// Modifier to set the value description shown in the -help output...
struct value_desc {};

// Specify a default (initial) value for the command line argument, if the
// default constructor for the argument type does not give you what you want.
// This is only valid on "opt" arguments, not on "list" arguments.
template <class Ty> struct initializer {};

template <class Ty> struct list_initializer {};

template <class Ty> initializer<Ty> init(const Ty &Val) {}

template <class Ty>
list_initializer<Ty> list_init(ArrayRef<Ty> Vals) {}

// Allow the user to specify which external variable they want to store the
// results of the command line argument processing into, if they don't want to
// store it in the option itself.
template <class Ty> struct LocationClass {};

template <class Ty> LocationClass<Ty> location(Ty &L) {}

// Specify the Option category for the command line argument to belong to.
struct cat {};

// Specify the subcommand that this option belongs to.
struct sub {};

// Specify a callback function to be called when an option is seen.
// Can be used to set other options automatically.
template <typename R, typename Ty> struct cb {};

namespace detail {
template <typename F>
struct callback_traits : public callback_traits<decltype(&F::operator())> {};

callback_traits<R (C::*)(Args...) const>;
} // namespace detail

template <typename F>
cb<typename detail::callback_traits<F>::result_type,
   typename detail::callback_traits<F>::arg_type>
callback(F CB) {}

//===----------------------------------------------------------------------===//

// Support value comparison outside the template.
struct GenericOptionValue {};

template <class DataType> struct OptionValue;

// The default value safely does nothing. Option value printing is only
// best-effort.
template <class DataType, bool isClass>
struct OptionValueBase : public GenericOptionValue {};

// Simple copy of the option value.
template <class DataType> class OptionValueCopy : public GenericOptionValue {};

// Non-class option values.
OptionValueBase<DataType, false>;

// Top-level option class.
template <class DataType>
struct OptionValue final
    : OptionValueBase<DataType, std::is_class_v<DataType>> {};

// Other safe-to-copy-by-value common option types.
enum boolOrDefault {};
template <>
struct OptionValue<cl::boolOrDefault> final
    : OptionValueCopy<cl::boolOrDefault> {};

template <>
struct OptionValue<std::string> final : OptionValueCopy<std::string> {};

//===----------------------------------------------------------------------===//
// Enum valued command line option
//

// This represents a single enum value, using "int" as the underlying type.
struct OptionEnumValue {};

#define clEnumVal(ENUMVAL, DESC)
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)

// For custom data types, allow specifying a group of values together as the
// values that go into the mapping that the option handler uses.
//
class ValuesClass {};

/// Helper to build a ValuesClass by forwarding a variable number of arguments
/// as an initializer list to the ValuesClass constructor.
template <typename... OptsTy> ValuesClass values(OptsTy... Options) {}

//===----------------------------------------------------------------------===//
// Parameterizable parser for different data types. By default, known data types
// (string, int, bool) have specialized parsers, that do what you would expect.
// The default parser, used for data types that are not built-in, uses a mapping
// table to map specific options to values, which is used, among other things,
// to handle enum types.

//--------------------------------------------------
// This class holds all the non-generic code that we do not need replicated for
// every instance of the generic parser.  This also allows us to put stuff into
// CommandLine.cpp
//
class generic_parser_base {};

// Default parser implementation - This implementation depends on having a
// mapping of recognized options to values of some sort.  In addition to this,
// each entry in the mapping also tracks a help message that is printed with the
// command line option for -help.  Because this is a simple mapping parser, the
// data type can be any unsupported type.
//
template <class DataType> class parser : public generic_parser_base {};

//--------------------------------------------------
// Super class of parsers to provide boilerplate code
//
class basic_parser_impl {};

// The real basic parser is just a template wrapper that provides a typedef for
// the provided data type.
//
template <class DataType> class basic_parser : public basic_parser_impl {};

//--------------------------------------------------

extern template class basic_parser<bool>;

template <> class parser<bool> : public basic_parser<bool> {};

//--------------------------------------------------

extern template class basic_parser<boolOrDefault>;

template <> class parser<boolOrDefault> : public basic_parser<boolOrDefault> {};

//--------------------------------------------------

extern template class basic_parser<int>;

template <> class parser<int> : public basic_parser<int> {};

//--------------------------------------------------

extern template class basic_parser<long>;

template <> class parser<long> final : public basic_parser<long> {};

//--------------------------------------------------

extern template class basic_parser<long long>;

template <> class parser<long long> : public basic_parser<long long> {};

//--------------------------------------------------

extern template class basic_parser<unsigned>;

template <> class parser<unsigned> : public basic_parser<unsigned> {};

//--------------------------------------------------

extern template class basic_parser<unsigned long>;

template <>
class parser<unsigned long> final : public basic_parser<unsigned long> {};

//--------------------------------------------------

extern template class basic_parser<unsigned long long>;

template <>
class parser<unsigned long long> : public basic_parser<unsigned long long> {};

//--------------------------------------------------

extern template class basic_parser<double>;

template <> class parser<double> : public basic_parser<double> {};

//--------------------------------------------------

extern template class basic_parser<float>;

template <> class parser<float> : public basic_parser<float> {};

//--------------------------------------------------

extern template class basic_parser<std::string>;

template <> class parser<std::string> : public basic_parser<std::string> {};

//--------------------------------------------------

extern template class basic_parser<char>;

template <> class parser<char> : public basic_parser<char> {};

//--------------------------------------------------
// This collection of wrappers is the intermediary between class opt and class
// parser to handle all the template nastiness.

// This overloaded function is selected by the generic parser.
template <class ParserClass, class DT>
void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V,
                     const OptionValue<DT> &Default, size_t GlobalWidth) {}

// This is instantiated for basic parsers when the parsed value has a different
// type than the option value. e.g. HelpPrinter.
template <class ParserDT, class ValDT> struct OptionDiffPrinter {};

// This is instantiated for basic parsers when the parsed value has the same
// type as the option value.
OptionDiffPrinter<DT, DT>;

// This overloaded function is selected by the basic parser, which may parse a
// different type than the option type.
template <class ParserClass, class ValDT>
void printOptionDiff(
    const Option &O,
    const basic_parser<typename ParserClass::parser_data_type> &P,
    const ValDT &V, const OptionValue<ValDT> &Default, size_t GlobalWidth) {}

//===----------------------------------------------------------------------===//
// This class is used because we must use partial specialization to handle
// literal string arguments specially (const char* does not correctly respond to
// the apply method). Because the syntax to use this is a pain, we have the
// 'apply' method below to handle the nastiness...
//
template <class Mod> struct applicator {};

// Handle const char* as a special case...
applicator<char[n]>;
applicator<const char[n]>;
template <> struct applicator<StringRef > {};

template <> struct applicator<NumOccurrencesFlag> {};

template <> struct applicator<ValueExpected> {};

template <> struct applicator<OptionHidden> {};

template <> struct applicator<FormattingFlags> {};

template <> struct applicator<MiscFlags> {};

// Apply modifiers to an option in a type safe way.
template <class Opt, class Mod, class... Mods>
void apply(Opt *O, const Mod &M, const Mods &... Ms) {}

template <class Opt, class Mod> void apply(Opt *O, const Mod &M) {}

//===----------------------------------------------------------------------===//
// Default storage class definition: external storage.  This implementation
// assumes the user will specify a variable to store the data into with the
// cl::location(x) modifier.
//
template <class DataType, bool ExternalStorage, bool isClass>
class opt_storage {};

// Define how to hold a class type object, such as a string.  Since we can
// inherit from a class, we do so.  This makes us exactly compatible with the
// object in all cases that it is used.
//
opt_storage<DataType, false, true>;

// Define a partial specialization to handle things we cannot inherit from.  In
// this case, we store an instance through containment, and overload operators
// to get at the value.
//
opt_storage<DataType, false, false>;

//===----------------------------------------------------------------------===//
// A scalar command line option.
//
template <class DataType, bool ExternalStorage = false,
          class ParserClass = parser<DataType>>
class opt
    : public Option,
      public opt_storage<DataType, ExternalStorage, std::is_class_v<DataType>> {
  ParserClass Parser;

  bool handleOccurrence(unsigned pos, StringRef ArgName,
                        StringRef Arg) override {}

  enum ValueExpected getValueExpectedFlagDefault() const override {}

  void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {}

  // Forward printing stuff to the parser...
  size_t getOptionWidth() const override {}

  void printOptionInfo(size_t GlobalWidth) const override {}

  void printOptionValue(size_t GlobalWidth, bool Force) const override {}

  template <class T, class = std::enable_if_t<std::is_assignable_v<T &, T>>>
  void setDefaultImpl() {}

  template <class T, class = std::enable_if_t<!std::is_assignable_v<T &, T>>>
  void setDefaultImpl(...) {}

  void setDefault() override {}

  void done() {}

public:
  // Command line options should not be copyable
  opt(const opt &) = delete;
  opt &operator=(const opt &) = delete;

  // setInitialValue - Used by the cl::init modifier...
  void setInitialValue(const DataType &V) {}

  ParserClass &getParser() {}

  template <class T> DataType &operator=(const T &Val) {}

  template <class... Mods>
  explicit opt(const Mods &... Ms)
      : Option(llvm::cl::Optional, NotHidden), Parser(*this) {}

  void setCallback(
      std::function<void(const typename ParserClass::parser_data_type &)> CB) {}

  std::function<void(const typename ParserClass::parser_data_type &)> Callback =
      [](const typename ParserClass::parser_data_type &) {};
};

extern template class opt<unsigned>;
extern template class opt<int>;
extern template class opt<std::string>;
extern template class opt<char>;
extern template class opt<bool>;

//===----------------------------------------------------------------------===//
// Default storage class definition: external storage.  This implementation
// assumes the user will specify a variable to store the data into with the
// cl::location(x) modifier.
//
template <class DataType, class StorageClass> class list_storage {};

// Define how to hold a class type object, such as a string.
// Originally this code inherited from std::vector. In transitioning to a new
// API for command line options we should change this. The new implementation
// of this list_storage specialization implements the minimum subset of the
// std::vector API required for all the current clients.
//
// FIXME: Reduce this API to a more narrow subset of std::vector
//
list_storage<DataType, bool>;

//===----------------------------------------------------------------------===//
// A list of command line options.
//
template <class DataType, class StorageClass = bool,
          class ParserClass = parser<DataType>>
class list : public Option, public list_storage<DataType, StorageClass> {
  std::vector<unsigned> Positions;
  ParserClass Parser;

  enum ValueExpected getValueExpectedFlagDefault() const override {}

  void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {}

  bool handleOccurrence(unsigned pos, StringRef ArgName,
                        StringRef Arg) override {}

  // Forward printing stuff to the parser...
  size_t getOptionWidth() const override {}

  void printOptionInfo(size_t GlobalWidth) const override {}

  // Unimplemented: list options don't currently store their default value.
  void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override {}

  void setDefault() override {}

  void done() {}

public:
  // Command line options should not be copyable
  list(const list &) = delete;
  list &operator=(const list &) = delete;

  ParserClass &getParser() {}

  unsigned getPosition(unsigned optnum) const {}

  void clear() {}

  // setInitialValues - Used by the cl::list_init modifier...
  void setInitialValues(ArrayRef<DataType> Vs) {}

  void setNumAdditionalVals(unsigned n) {}

  template <class... Mods>
  explicit list(const Mods &... Ms)
      : Option(ZeroOrMore, NotHidden), Parser(*this) {}

  void setCallback(
      std::function<void(const typename ParserClass::parser_data_type &)> CB) {}

  std::function<void(const typename ParserClass::parser_data_type &)> Callback =
      [](const typename ParserClass::parser_data_type &) {};
};

// Modifier to set the number of additional values.
struct multi_val {};

//===----------------------------------------------------------------------===//
// Default storage class definition: external storage.  This implementation
// assumes the user will specify a variable to store the data into with the
// cl::location(x) modifier.
//
template <class DataType, class StorageClass> class bits_storage {};

// Define how to hold bits.  Since we can inherit from a class, we do so.
// This makes us exactly compatible with the bits in all cases that it is used.
//
bits_storage<DataType, bool>;

//===----------------------------------------------------------------------===//
// A bit vector of command options.
//
template <class DataType, class Storage = bool,
          class ParserClass = parser<DataType>>
class bits : public Option, public bits_storage<DataType, Storage> {
  std::vector<unsigned> Positions;
  ParserClass Parser;

  enum ValueExpected getValueExpectedFlagDefault() const override {}

  void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {}

  bool handleOccurrence(unsigned pos, StringRef ArgName,
                        StringRef Arg) override {}

  // Forward printing stuff to the parser...
  size_t getOptionWidth() const override {}

  void printOptionInfo(size_t GlobalWidth) const override {}

  // Unimplemented: bits options don't currently store their default values.
  void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override {}

  void setDefault() override {}

  void done() {}

public:
  // Command line options should not be copyable
  bits(const bits &) = delete;
  bits &operator=(const bits &) = delete;

  ParserClass &getParser() {}

  unsigned getPosition(unsigned optnum) const {}

  template <class... Mods>
  explicit bits(const Mods &... Ms)
      : Option(ZeroOrMore, NotHidden), Parser(*this) {}

  void setCallback(
      std::function<void(const typename ParserClass::parser_data_type &)> CB) {}

  std::function<void(const typename ParserClass::parser_data_type &)> Callback =
      [](const typename ParserClass::parser_data_type &) {};
};

//===----------------------------------------------------------------------===//
// Aliased command line option (alias this name to a preexisting name)
//

class alias : public Option {};

// Modifier to set the option an alias aliases.
struct aliasopt {};

// Provide additional help at the end of the normal help output. All occurrences
// of cl::extrahelp will be accumulated and printed to stderr at the end of the
// regular help, just before exit is called.
struct extrahelp {};

void PrintVersionMessage();

/// This function just prints the help message, exactly the same way as if the
/// -help or -help-hidden option had been given on the command line.
///
/// \param Hidden if true will print hidden options
/// \param Categorized if true print options in categories
void PrintHelpMessage(bool Hidden = false, bool Categorized = false);

/// An array of optional enabled settings in the LLVM build configuration,
/// which may be of interest to compiler developers. For example, includes
/// "+assertions" if assertions are enabled. Used by printBuildConfig.
ArrayRef<StringRef> getCompilerBuildConfig();

/// Prints the compiler build configuration.
/// Designed for compiler developers, not compiler end-users.
/// Intended to be used in --version output when enabled.
void printBuildConfig(raw_ostream &OS);

//===----------------------------------------------------------------------===//
// Public interface for accessing registered options.
//

/// Use this to get a StringMap to all registered named options
/// (e.g. -help).
///
/// \return A reference to the StringMap used by the cl APIs to parse options.
///
/// Access to unnamed arguments (i.e. positional) are not provided because
/// it is expected that the client already has access to these.
///
/// Typical usage:
/// \code
/// main(int argc,char* argv[]) {
/// StringMap<llvm::cl::Option*> &opts = llvm::cl::getRegisteredOptions();
/// assert(opts.count("help") == 1)
/// opts["help"]->setDescription("Show alphabetical help information")
/// // More code
/// llvm::cl::ParseCommandLineOptions(argc,argv);
/// //More code
/// }
/// \endcode
///
/// This interface is useful for modifying options in libraries that are out of
/// the control of the client. The options should be modified before calling
/// llvm::cl::ParseCommandLineOptions().
///
/// Hopefully this API can be deprecated soon. Any situation where options need
/// to be modified by tools or libraries should be handled by sane APIs rather
/// than just handing around a global list.
StringMap<Option *> &
getRegisteredOptions(SubCommand &Sub = SubCommand::getTopLevel());

/// Use this to get all registered SubCommands from the provided parser.
///
/// \return A range of all SubCommand pointers registered with the parser.
///
/// Typical usage:
/// \code
/// main(int argc, char* argv[]) {
///   llvm::cl::ParseCommandLineOptions(argc, argv);
///   for (auto* S : llvm::cl::getRegisteredSubcommands()) {
///     if (*S) {
///       std::cout << "Executing subcommand: " << S->getName() << std::endl;
///       // Execute some function based on the name...
///     }
///   }
/// }
/// \endcode
///
/// This interface is useful for defining subcommands in libraries and
/// the dispatch from a single point (like in the main function).
iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator>
getRegisteredSubcommands();

//===----------------------------------------------------------------------===//
// Standalone command line processing utilities.
//

/// Tokenizes a command line that can contain escapes and quotes.
//
/// The quoting rules match those used by GCC and other tools that use
/// libiberty's buildargv() or expandargv() utilities, and do not match bash.
/// They differ from buildargv() on treatment of backslashes that do not escape
/// a special character to make it possible to accept most Windows file paths.
///
/// \param [in] Source The string to be split on whitespace with quotes.
/// \param [in] Saver Delegates back to the caller for saving parsed strings.
/// \param [in] MarkEOLs true if tokenizing a response file and you want end of
/// lines and end of the response file to be marked with a nullptr string.
/// \param [out] NewArgv All parsed strings are appended to NewArgv.
void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver,
                            SmallVectorImpl<const char *> &NewArgv,
                            bool MarkEOLs = false);

/// Tokenizes a string of Windows command line arguments, which may contain
/// quotes and escaped quotes.
///
/// See MSDN docs for CommandLineToArgvW for information on the quoting rules.
/// http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx
///
/// For handling a full Windows command line including the executable name at
/// the start, see TokenizeWindowsCommandLineFull below.
///
/// \param [in] Source The string to be split on whitespace with quotes.
/// \param [in] Saver Delegates back to the caller for saving parsed strings.
/// \param [in] MarkEOLs true if tokenizing a response file and you want end of
/// lines and end of the response file to be marked with a nullptr string.
/// \param [out] NewArgv All parsed strings are appended to NewArgv.
void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver,
                                SmallVectorImpl<const char *> &NewArgv,
                                bool MarkEOLs = false);

/// Tokenizes a Windows command line while attempting to avoid copies. If no
/// quoting or escaping was used, this produces substrings of the original
/// string. If a token requires unquoting, it will be allocated with the
/// StringSaver.
void TokenizeWindowsCommandLineNoCopy(StringRef Source, StringSaver &Saver,
                                      SmallVectorImpl<StringRef> &NewArgv);

/// Tokenizes a Windows full command line, including command name at the start.
///
/// This uses the same syntax rules as TokenizeWindowsCommandLine for all but
/// the first token. But the first token is expected to be parsed as the
/// executable file name in the way CreateProcess would do it, rather than the
/// way the C library startup code would do it: CreateProcess does not consider
/// that \ is ever an escape character (because " is not a valid filename char,
/// hence there's never a need to escape it to be used literally).
///
/// Parameters are the same as for TokenizeWindowsCommandLine. In particular,
/// if you set MarkEOLs = true, then the first word of every line will be
/// parsed using the special rules for command names, making this function
/// suitable for parsing a file full of commands to execute.
void TokenizeWindowsCommandLineFull(StringRef Source, StringSaver &Saver,
                                    SmallVectorImpl<const char *> &NewArgv,
                                    bool MarkEOLs = false);

/// String tokenization function type.  Should be compatible with either
/// Windows or Unix command line tokenizers.
TokenizerCallback;

/// Tokenizes content of configuration file.
///
/// \param [in] Source The string representing content of config file.
/// \param [in] Saver Delegates back to the caller for saving parsed strings.
/// \param [out] NewArgv All parsed strings are appended to NewArgv.
/// \param [in] MarkEOLs Added for compatibility with TokenizerCallback.
///
/// It works like TokenizeGNUCommandLine with ability to skip comment lines.
///
void tokenizeConfigFile(StringRef Source, StringSaver &Saver,
                        SmallVectorImpl<const char *> &NewArgv,
                        bool MarkEOLs = false);

/// Contains options that control response file expansion.
class ExpansionContext {};

/// A convenience helper which concatenates the options specified by the
/// environment variable EnvVar and command line options, then expands
/// response files recursively.
/// \return true if all @files were expanded successfully or there were none.
bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar,
                         SmallVectorImpl<const char *> &NewArgv);

/// A convenience helper which supports the typical use case of expansion
/// function call.
bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
                         SmallVectorImpl<const char *> &Argv);

/// A convenience helper which concatenates the options specified by the
/// environment variable EnvVar and command line options, then expands response
/// files recursively. The tokenizer is a predefined GNU or Windows one.
/// \return true if all @files were expanded successfully or there were none.
bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar,
                         StringSaver &Saver,
                         SmallVectorImpl<const char *> &NewArgv);

/// Mark all options not part of this category as cl::ReallyHidden.
///
/// \param Category the category of options to keep displaying
///
/// Some tools (like clang-format) like to be able to hide all options that are
/// not specific to the tool. This function allows a tool to specify a single
/// option category to display in the -help output.
void HideUnrelatedOptions(cl::OptionCategory &Category,
                          SubCommand &Sub = SubCommand::getTopLevel());

/// Mark all options not part of the categories as cl::ReallyHidden.
///
/// \param Categories the categories of options to keep displaying.
///
/// Some tools (like clang-format) like to be able to hide all options that are
/// not specific to the tool. This function allows a tool to specify a single
/// option category to display in the -help output.
void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,
                          SubCommand &Sub = SubCommand::getTopLevel());

/// Reset all command line options to a state that looks as if they have
/// never appeared on the command line.  This is useful for being able to parse
/// a command line multiple times (especially useful for writing tests).
void ResetAllOptionOccurrences();

/// Reset the command line parser back to its initial state.  This
/// removes
/// all options, categories, and subcommands and returns the parser to a state
/// where no options are supported.
void ResetCommandLineParser();

/// Parses `Arg` into the option handler `Handler`.
bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i);

} // end namespace cl

} // end namespace llvm

#endif // LLVM_SUPPORT_COMMANDLINE_H