Skip to content
CommandLine.cpp 41.4 KiB
Newer Older
Chris Lattner's avatar
Chris Lattner committed
//===-- CommandLine.cpp - Command line parser implementation --------------===//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
Chris Lattner's avatar
Chris Lattner committed
//
// 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 could try
// reading the library documentation located in docs/CommandLine.html
//
Chris Lattner's avatar
Chris Lattner committed
//===----------------------------------------------------------------------===//

Reid Spencer's avatar
Reid Spencer committed
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ManagedStatic.h"
Chris Lattner's avatar
Chris Lattner committed
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/System/Host.h"
Chris Lattner's avatar
Chris Lattner committed
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
Chris Lattner's avatar
Chris Lattner committed
#include "llvm/Config/config.h"
Chris Lattner's avatar
Chris Lattner committed
#include <set>
#include <cerrno>
Chris Lattner's avatar
Chris Lattner committed
#include <cstdlib>
using namespace llvm;
Chris Lattner's avatar
Chris Lattner committed
using namespace cl;

//===----------------------------------------------------------------------===//
// Template instantiations and anchors.
//
TEMPLATE_INSTANTIATION(class basic_parser<bool>);
TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
TEMPLATE_INSTANTIATION(class basic_parser<int>);
TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
TEMPLATE_INSTANTIATION(class basic_parser<double>);
TEMPLATE_INSTANTIATION(class basic_parser<float>);
TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
TEMPLATE_INSTANTIATION(class basic_parser<char>);

TEMPLATE_INSTANTIATION(class opt<unsigned>);
TEMPLATE_INSTANTIATION(class opt<int>);
TEMPLATE_INSTANTIATION(class opt<std::string>);
TEMPLATE_INSTANTIATION(class opt<char>);
TEMPLATE_INSTANTIATION(class opt<bool>);

void Option::anchor() {}
void basic_parser_impl::anchor() {}
void parser<bool>::anchor() {}
void parser<boolOrDefault>::anchor() {}
void parser<int>::anchor() {}
void parser<unsigned>::anchor() {}
void parser<double>::anchor() {}
void parser<float>::anchor() {}
void parser<std::string>::anchor() {}

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

// Globals for name and overview of program.  Program name is not a string to
// avoid static ctor/dtor issues.
static char ProgramName[80] = "<premain>";
static const char *ProgramOverview = 0;

// This collects additional help to be printed.
static ManagedStatic<std::vector<const char*> > MoreHelp;
extrahelp::extrahelp(const char *Help)
  MoreHelp->push_back(Help);
static bool OptionListChanged = false;

// MarkOptionsChanged - Internal helper function.
void cl::MarkOptionsChanged() {
  OptionListChanged = true;
}

/// RegisteredOptionList - This is the list of the command line options that
/// have statically constructed themselves.
static Option *RegisteredOptionList = 0;

void Option::addArgument() {
  assert(NextRegistered == 0 && "argument multiply registered!");
  NextRegistered = RegisteredOptionList;
  RegisteredOptionList = this;
Chris Lattner's avatar
Chris Lattner committed
//===----------------------------------------------------------------------===//
// Basic, shared command line option processing machinery.
/// GetOptionInfo - Scan the list of registered options, turning them into data
/// structures that are easier to handle.
static void GetOptionInfo(std::vector<Option*> &PositionalOpts,
                          std::vector<Option*> &SinkOpts,
                          StringMap<Option*> &OptionsMap) {
  Option *CAOpt = 0;  // The ConsumeAfter option if it exists.
  for (Option *O = RegisteredOptionList; O; O = O->getNextRegisteredOption()) {
    // If this option wants to handle multiple option names, get the full set.
    // This handles enum options like "-O1 -O2" etc.
    O->getExtraOptionNames(OptionNames);
    if (O->ArgStr[0])
      OptionNames.push_back(O->ArgStr);
    for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
      if (OptionsMap.GetOrCreateValue(OptionNames[i], O).second != O) {
        errs() << ProgramName << ": CommandLine Error: Argument '"
             << OptionNames[i] << "' defined more than once!\n";
    // Remember information about positional options.
    if (O->getFormattingFlag() == cl::Positional)
      PositionalOpts.push_back(O);
    else if (O->getMiscFlags() & cl::Sink) // Remember sink options
    else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
        O->error("Cannot specify more than one option with cl::ConsumeAfter!");
  if (CAOpt)
    PositionalOpts.push_back(CAOpt);
  // Make sure that they are in order of registration not backwards.
  std::reverse(PositionalOpts.begin(), PositionalOpts.end());
/// LookupOption - Lookup the option specified by the specified option on the
/// command line.  If there is a value specified (after an equal sign) return
/// that as well.
static Option *LookupOption(const char *&Arg, const char *&Value,
                            StringMap<Option*> &OptionsMap) {
  while (*Arg == '-') ++Arg;  // Eat leading dashes
  const char *ArgEnd = Arg;
  while (*ArgEnd && *ArgEnd != '=')
    ++ArgEnd; // Scan till end of argument name.
  if (*ArgEnd == '=')  // If we have an equals sign...
    Value = ArgEnd+1;  // Get the value, not the equals
  StringMap<Option*>::iterator I =
    OptionsMap.find(llvm::StringRef(Arg, ArgEnd-Arg));
  return I != OptionsMap.end() ? I->second : 0;
Chris Lattner's avatar
Chris Lattner committed
}

static inline bool ProvideOption(Option *Handler, const char *ArgName,
                                 const char *Value, int argc, char **argv,
                                 int &i) {
  // Is this a multi-argument option?
  unsigned NumAdditionalVals = Handler->getNumAdditionalVals();

  // Enforce value requirements
  switch (Handler->getValueExpectedFlag()) {
  case ValueRequired:
    if (Value == 0) {       // No value specified?
      if (i+1 < argc) {     // Steal the next argument, like for '-o filename'
        Value = argv[++i];
      } else {
        return Handler->error("requires a value!");
    if (NumAdditionalVals > 0)
      return Handler->error("multi-valued option specified"
      " with ValueDisallowed modifier!");

      return Handler->error("does not allow a value! '" +
                            std::string(Value) + "' specified.");
  case ValueOptional:
  default:
Loading
Loading full blame...