237 lines
6.6 KiB
C
237 lines
6.6 KiB
C
|
//===- Option.h - Abstract Driver Options -----------------------*- 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
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#ifndef LLVM_OPTION_OPTION_H
|
||
|
#define LLVM_OPTION_OPTION_H
|
||
|
|
||
|
#include "llvm/ADT/SmallVector.h"
|
||
|
#include "llvm/ADT/StringRef.h"
|
||
|
#include "llvm/Option/OptSpecifier.h"
|
||
|
#include "llvm/Option/OptTable.h"
|
||
|
#include "llvm/Support/ErrorHandling.h"
|
||
|
#include <cassert>
|
||
|
#include <string>
|
||
|
|
||
|
namespace llvm {
|
||
|
|
||
|
class raw_ostream;
|
||
|
|
||
|
namespace opt {
|
||
|
|
||
|
class Arg;
|
||
|
class ArgList;
|
||
|
|
||
|
/// ArgStringList - Type used for constructing argv lists for subprocesses.
|
||
|
using ArgStringList = SmallVector<const char *, 16>;
|
||
|
|
||
|
/// Base flags for all options. Custom flags may be added after.
|
||
|
enum DriverFlag {
|
||
|
HelpHidden = (1 << 0),
|
||
|
RenderAsInput = (1 << 1),
|
||
|
RenderJoined = (1 << 2),
|
||
|
RenderSeparate = (1 << 3)
|
||
|
};
|
||
|
|
||
|
/// Option - Abstract representation for a single form of driver
|
||
|
/// argument.
|
||
|
///
|
||
|
/// An Option class represents a form of option that the driver
|
||
|
/// takes, for example how many arguments the option has and how
|
||
|
/// they can be provided. Individual option instances store
|
||
|
/// additional information about what group the option is a member
|
||
|
/// of (if any), if the option is an alias, and a number of
|
||
|
/// flags. At runtime the driver parses the command line into
|
||
|
/// concrete Arg instances, each of which corresponds to a
|
||
|
/// particular Option instance.
|
||
|
class Option {
|
||
|
public:
|
||
|
enum OptionClass {
|
||
|
GroupClass = 0,
|
||
|
InputClass,
|
||
|
UnknownClass,
|
||
|
FlagClass,
|
||
|
JoinedClass,
|
||
|
ValuesClass,
|
||
|
SeparateClass,
|
||
|
RemainingArgsClass,
|
||
|
RemainingArgsJoinedClass,
|
||
|
CommaJoinedClass,
|
||
|
MultiArgClass,
|
||
|
JoinedOrSeparateClass,
|
||
|
JoinedAndSeparateClass
|
||
|
};
|
||
|
|
||
|
enum RenderStyleKind {
|
||
|
RenderCommaJoinedStyle,
|
||
|
RenderJoinedStyle,
|
||
|
RenderSeparateStyle,
|
||
|
RenderValuesStyle
|
||
|
};
|
||
|
|
||
|
protected:
|
||
|
const OptTable::Info *Info;
|
||
|
const OptTable *Owner;
|
||
|
|
||
|
public:
|
||
|
Option(const OptTable::Info *Info, const OptTable *Owner);
|
||
|
|
||
|
bool isValid() const {
|
||
|
return Info != nullptr;
|
||
|
}
|
||
|
|
||
|
unsigned getID() const {
|
||
|
assert(Info && "Must have a valid info!");
|
||
|
return Info->ID;
|
||
|
}
|
||
|
|
||
|
OptionClass getKind() const {
|
||
|
assert(Info && "Must have a valid info!");
|
||
|
return OptionClass(Info->Kind);
|
||
|
}
|
||
|
|
||
|
/// Get the name of this option without any prefix.
|
||
|
StringRef getName() const {
|
||
|
assert(Info && "Must have a valid info!");
|
||
|
return Info->Name;
|
||
|
}
|
||
|
|
||
|
const Option getGroup() const {
|
||
|
assert(Info && "Must have a valid info!");
|
||
|
assert(Owner && "Must have a valid owner!");
|
||
|
return Owner->getOption(Info->GroupID);
|
||
|
}
|
||
|
|
||
|
const Option getAlias() const {
|
||
|
assert(Info && "Must have a valid info!");
|
||
|
assert(Owner && "Must have a valid owner!");
|
||
|
return Owner->getOption(Info->AliasID);
|
||
|
}
|
||
|
|
||
|
/// Get the alias arguments as a \0 separated list.
|
||
|
/// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
|
||
|
const char *getAliasArgs() const {
|
||
|
assert(Info && "Must have a valid info!");
|
||
|
assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
|
||
|
"AliasArgs should be either 0 or non-empty.");
|
||
|
|
||
|
return Info->AliasArgs;
|
||
|
}
|
||
|
|
||
|
/// Get the default prefix for this option.
|
||
|
StringRef getPrefix() const {
|
||
|
const char *Prefix = *Info->Prefixes;
|
||
|
return Prefix ? Prefix : StringRef();
|
||
|
}
|
||
|
|
||
|
/// Get the name of this option with the default prefix.
|
||
|
std::string getPrefixedName() const {
|
||
|
std::string Ret(getPrefix());
|
||
|
Ret += getName();
|
||
|
return Ret;
|
||
|
}
|
||
|
|
||
|
/// Get the help text for this option.
|
||
|
StringRef getHelpText() const {
|
||
|
assert(Info && "Must have a valid info!");
|
||
|
return Info->HelpText;
|
||
|
}
|
||
|
|
||
|
/// Get the meta-variable list for this option.
|
||
|
StringRef getMetaVar() const {
|
||
|
assert(Info && "Must have a valid info!");
|
||
|
return Info->MetaVar;
|
||
|
}
|
||
|
|
||
|
unsigned getNumArgs() const { return Info->Param; }
|
||
|
|
||
|
bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
|
||
|
|
||
|
RenderStyleKind getRenderStyle() const {
|
||
|
if (Info->Flags & RenderJoined)
|
||
|
return RenderJoinedStyle;
|
||
|
if (Info->Flags & RenderSeparate)
|
||
|
return RenderSeparateStyle;
|
||
|
switch (getKind()) {
|
||
|
case GroupClass:
|
||
|
case InputClass:
|
||
|
case UnknownClass:
|
||
|
return RenderValuesStyle;
|
||
|
case JoinedClass:
|
||
|
case JoinedAndSeparateClass:
|
||
|
return RenderJoinedStyle;
|
||
|
case CommaJoinedClass:
|
||
|
return RenderCommaJoinedStyle;
|
||
|
case FlagClass:
|
||
|
case ValuesClass:
|
||
|
case SeparateClass:
|
||
|
case MultiArgClass:
|
||
|
case JoinedOrSeparateClass:
|
||
|
case RemainingArgsClass:
|
||
|
case RemainingArgsJoinedClass:
|
||
|
return RenderSeparateStyle;
|
||
|
}
|
||
|
llvm_unreachable("Unexpected kind!");
|
||
|
}
|
||
|
|
||
|
/// Test if this option has the flag \a Val.
|
||
|
bool hasFlag(unsigned Val) const {
|
||
|
return Info->Flags & Val;
|
||
|
}
|
||
|
|
||
|
/// getUnaliasedOption - Return the final option this option
|
||
|
/// aliases (itself, if the option has no alias).
|
||
|
const Option getUnaliasedOption() const {
|
||
|
const Option Alias = getAlias();
|
||
|
if (Alias.isValid()) return Alias.getUnaliasedOption();
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/// getRenderName - Return the name to use when rendering this
|
||
|
/// option.
|
||
|
StringRef getRenderName() const {
|
||
|
return getUnaliasedOption().getName();
|
||
|
}
|
||
|
|
||
|
/// matches - Predicate for whether this option is part of the
|
||
|
/// given option (which may be a group).
|
||
|
///
|
||
|
/// Note that matches against options which are an alias should never be
|
||
|
/// done -- aliases do not participate in matching and so such a query will
|
||
|
/// always be false.
|
||
|
bool matches(OptSpecifier ID) const;
|
||
|
|
||
|
/// accept - Potentially accept the current argument, returning a
|
||
|
/// new Arg instance, or 0 if the option does not accept this
|
||
|
/// argument (or the argument is missing values).
|
||
|
///
|
||
|
/// If the option accepts the current argument, accept() sets
|
||
|
/// Index to the position where argument parsing should resume
|
||
|
/// (even if the argument is missing values).
|
||
|
///
|
||
|
/// \p CurArg The argument to be matched. It may be shorter than the
|
||
|
/// underlying storage to represent a Joined argument.
|
||
|
/// \p GroupedShortOption If true, we are handling the fallback case of
|
||
|
/// parsing a prefix of the current argument as a short option.
|
||
|
Arg *accept(const ArgList &Args, StringRef CurArg, bool GroupedShortOption,
|
||
|
unsigned &Index) const;
|
||
|
|
||
|
private:
|
||
|
Arg *acceptInternal(const ArgList &Args, StringRef CurArg,
|
||
|
unsigned &Index) const;
|
||
|
|
||
|
public:
|
||
|
void print(raw_ostream &O) const;
|
||
|
void dump() const;
|
||
|
};
|
||
|
|
||
|
} // end namespace opt
|
||
|
|
||
|
} // end namespace llvm
|
||
|
|
||
|
#endif // LLVM_OPTION_OPTION_H
|