Skip to content
CommandLine.cpp 41.2 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"
#include "llvm/ADT/SmallString.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.  This assumes that leading dashes have already been stripped.
static Option *LookupOption(StringRef &Arg, StringRef &Value,
                            const StringMap<Option*> &OptionsMap) {
  // Reject all dashes.
  if (Arg.empty()) return 0;
  
  size_t EqualPos = Arg.find('=');
  
  // If we have an equals sign, remember the value.
  if (EqualPos == StringRef::npos) {
    // Look up the option.
    StringMap<Option*>::const_iterator I = OptionsMap.find(Arg);
    return I != OptionsMap.end() ? I->second : 0;
  // If the argument before the = is a valid option name, we match.  If not,
  // return Arg unmolested.
  StringMap<Option*>::const_iterator I =
    OptionsMap.find(Arg.substr(0, EqualPos));
  if (I == OptionsMap.end()) return 0;
  
  Value = Arg.substr(EqualPos+1);
  Arg = Arg.substr(0, EqualPos);
  return I->second;
Chris Lattner's avatar
Chris Lattner committed
}

/// ProvideOption - For Value, this differentiates between an empty value ("")
/// and a null value (StringRef()).  The later is accepted for arguments that
/// don't allow a value (-foo) the former is rejected (-foo=).
static inline bool ProvideOption(Option *Handler, StringRef ArgName,
  // Is this a multi-argument option?
  unsigned NumAdditionalVals = Handler->getNumAdditionalVals();

  // Enforce value requirements
  switch (Handler->getValueExpectedFlag()) {
  case ValueRequired:
    if (Value.data() == 0) {       // No value specified?
        return Handler->error("requires a value!");
      // Steal the next argument, like for '-o filename'
      Value = argv[++i];
Loading
Loading full blame...