зеркало из https://github.com/microsoft/clang-1.git
Reduce the amount of state in the Option class by relying on the data from OptTable::Info.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162299 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a796b6c4b9
Коммит
04a4279160
|
@ -15,21 +15,6 @@
|
|||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
namespace options {
|
||||
enum DriverFlag {
|
||||
DriverOption = (1 << 0),
|
||||
HelpHidden = (1 << 1),
|
||||
LinkerInput = (1 << 2),
|
||||
NoArgumentUnused = (1 << 3),
|
||||
NoForward = (1 << 4),
|
||||
RenderAsInput = (1 << 5),
|
||||
RenderJoined = (1 << 6),
|
||||
RenderSeparate = (1 << 7),
|
||||
Unsupported = (1 << 8),
|
||||
CC1Option = (1 << 9)
|
||||
};
|
||||
}
|
||||
|
||||
class Arg;
|
||||
class ArgList;
|
||||
class InputArgList;
|
||||
|
@ -123,9 +108,7 @@ namespace options {
|
|||
}
|
||||
|
||||
/// \brief Should the help for the given option be hidden by default.
|
||||
bool isOptionHelpHidden(OptSpecifier id) const {
|
||||
return getInfo(id).Flags & options::HelpHidden;
|
||||
}
|
||||
bool isOptionHelpHidden(OptSpecifier id) const;
|
||||
|
||||
/// \brief Get the help text to use to describe this option.
|
||||
const char *getOptionHelpText(OptSpecifier id) const {
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
#ifndef CLANG_DRIVER_OPTION_H_
|
||||
#define CLANG_DRIVER_OPTION_H_
|
||||
|
||||
#include "clang/Driver/OptSpecifier.h"
|
||||
#include "clang/Driver/OptTable.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
|
||||
namespace clang {
|
||||
|
@ -19,6 +20,21 @@ namespace driver {
|
|||
class Arg;
|
||||
class ArgList;
|
||||
|
||||
namespace options {
|
||||
enum DriverFlag {
|
||||
DriverOption = (1 << 0),
|
||||
HelpHidden = (1 << 1),
|
||||
LinkerInput = (1 << 2),
|
||||
NoArgumentUnused = (1 << 3),
|
||||
NoForward = (1 << 4),
|
||||
RenderAsInput = (1 << 5),
|
||||
RenderJoined = (1 << 6),
|
||||
RenderSeparate = (1 << 7),
|
||||
Unsupported = (1 << 8),
|
||||
CC1Option = (1 << 9)
|
||||
};
|
||||
}
|
||||
|
||||
/// Option - Abstract representation for a single form of driver
|
||||
/// argument.
|
||||
///
|
||||
|
@ -53,87 +69,72 @@ namespace driver {
|
|||
};
|
||||
|
||||
private:
|
||||
OptionClass Kind;
|
||||
const OptTable::Info *Info;
|
||||
|
||||
/// The option ID.
|
||||
OptSpecifier ID;
|
||||
|
||||
/// The option name.
|
||||
StringRef Name;
|
||||
|
||||
/// Group this option is a member of, if any.
|
||||
const Option *Group;
|
||||
|
||||
/// Option that this is an alias for, if any.
|
||||
const Option *Alias;
|
||||
|
||||
unsigned NumArgs;
|
||||
|
||||
/// Unsupported options will be rejected.
|
||||
bool Unsupported : 1;
|
||||
|
||||
/// Treat this option like a linker input?
|
||||
bool LinkerInput : 1;
|
||||
|
||||
/// When rendering as an input, don't render the option.
|
||||
|
||||
// FIXME: We should ditch the render/renderAsInput distinction.
|
||||
bool NoOptAsInput : 1;
|
||||
|
||||
/// The style to using when rendering arguments parsed by this option.
|
||||
unsigned RenderStyle : 2;
|
||||
|
||||
/// This option is only consumed by the driver.
|
||||
bool DriverOption : 1;
|
||||
|
||||
/// This option should not report argument unused errors.
|
||||
bool NoArgumentUnused : 1;
|
||||
|
||||
/// This option should not be implicitly forwarded.
|
||||
bool NoForward : 1;
|
||||
|
||||
/// CC1Option - This option should be accepted by clang -cc1.
|
||||
bool CC1Option : 1;
|
||||
|
||||
public:
|
||||
Option(OptionClass Kind, OptSpecifier ID, const char *Name,
|
||||
const Option *Group, const Option *Alias, unsigned Args);
|
||||
Option(const OptTable::Info *Info, OptSpecifier ID,
|
||||
const Option *Group, const Option *Alias);
|
||||
~Option();
|
||||
|
||||
unsigned getID() const { return ID.getID(); }
|
||||
OptionClass getKind() const { return Kind; }
|
||||
StringRef getName() const { return Name; }
|
||||
OptionClass getKind() const { return OptionClass(Info->Kind); }
|
||||
StringRef getName() const { return Info->Name; }
|
||||
const Option *getGroup() const { return Group; }
|
||||
const Option *getAlias() const { return Alias; }
|
||||
|
||||
bool isUnsupported() const { return Unsupported; }
|
||||
void setUnsupported(bool Value) { Unsupported = Value; }
|
||||
unsigned getNumArgs() const { return Info->Param; }
|
||||
|
||||
bool isLinkerInput() const { return LinkerInput; }
|
||||
void setLinkerInput(bool Value) { LinkerInput = Value; }
|
||||
bool isUnsupported() const { return Info->Flags & options::Unsupported; }
|
||||
|
||||
bool hasNoOptAsInput() const { return NoOptAsInput; }
|
||||
void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
|
||||
bool isLinkerInput() const { return Info->Flags & options::LinkerInput; }
|
||||
|
||||
bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;}
|
||||
|
||||
RenderStyleKind getRenderStyle() const {
|
||||
return RenderStyleKind(RenderStyle);
|
||||
if (Info->Flags & options::RenderJoined)
|
||||
return RenderJoinedStyle;
|
||||
if (Info->Flags & options::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 SeparateClass:
|
||||
case MultiArgClass:
|
||||
case JoinedOrSeparateClass:
|
||||
return RenderSeparateStyle;
|
||||
}
|
||||
llvm_unreachable("Unexpected kind!");
|
||||
}
|
||||
void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
|
||||
|
||||
bool isDriverOption() const { return DriverOption; }
|
||||
void setDriverOption(bool Value) { DriverOption = Value; }
|
||||
bool isDriverOption() const { return Info->Flags & options::DriverOption; }
|
||||
|
||||
bool hasNoArgumentUnused() const { return NoArgumentUnused; }
|
||||
void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
|
||||
bool hasNoArgumentUnused() const {
|
||||
return Info->Flags & options::NoArgumentUnused;
|
||||
}
|
||||
|
||||
bool hasNoForward() const { return NoForward; }
|
||||
void setNoForward(bool Value) { NoForward = Value; }
|
||||
bool hasNoForward() const { return Info->Flags & options::NoForward; }
|
||||
|
||||
bool isCC1Option() const { return CC1Option; }
|
||||
void setIsCC1Option(bool Value) { CC1Option = Value; }
|
||||
bool isCC1Option() const { return Info->Flags & options::CC1Option; }
|
||||
|
||||
bool hasForwardToGCC() const {
|
||||
return !NoForward && !DriverOption && !LinkerInput;
|
||||
return !hasNoForward() && !isDriverOption() && !isLinkerInput();
|
||||
}
|
||||
|
||||
/// getUnaliasedOption - Return the final option this option
|
||||
|
|
|
@ -129,38 +129,16 @@ OptTable::~OptTable() {
|
|||
delete[] Options;
|
||||
}
|
||||
|
||||
bool OptTable::isOptionHelpHidden(OptSpecifier id) const {
|
||||
return getInfo(id).Flags & options::HelpHidden;
|
||||
}
|
||||
|
||||
Option *OptTable::CreateOption(unsigned id) const {
|
||||
const Info &info = getInfo(id);
|
||||
const Option *Group = getOption(info.GroupID);
|
||||
const Option *Alias = getOption(info.AliasID);
|
||||
|
||||
Option *Opt = new Option(Option::OptionClass(info.Kind),
|
||||
id, info.Name, Group, Alias, info.Param);
|
||||
|
||||
if (info.Flags & DriverOption)
|
||||
Opt->setDriverOption(true);
|
||||
if (info.Flags & LinkerInput)
|
||||
Opt->setLinkerInput(true);
|
||||
if (info.Flags & NoArgumentUnused)
|
||||
Opt->setNoArgumentUnused(true);
|
||||
if (info.Flags & NoForward)
|
||||
Opt->setNoForward(true);
|
||||
if (info.Flags & RenderAsInput)
|
||||
Opt->setNoOptAsInput(true);
|
||||
if (info.Flags & RenderJoined) {
|
||||
assert((info.Kind == Option::JoinedOrSeparateClass ||
|
||||
info.Kind == Option::SeparateClass) && "Invalid option.");
|
||||
Opt->setRenderStyle(Option::RenderJoinedStyle);
|
||||
}
|
||||
if (info.Flags & RenderSeparate) {
|
||||
assert((info.Kind == Option::JoinedOrSeparateClass ||
|
||||
info.Kind == Option::JoinedClass) && "Invalid option.");
|
||||
Opt->setRenderStyle(Option::RenderSeparateStyle);
|
||||
}
|
||||
if (info.Flags & Unsupported)
|
||||
Opt->setUnsupported(true);
|
||||
if (info.Flags & CC1Option)
|
||||
Opt->setIsCC1Option(true);
|
||||
Option *Opt = new Option(&info, id, Group, Alias);
|
||||
|
||||
return Opt;
|
||||
}
|
||||
|
|
|
@ -17,42 +17,15 @@
|
|||
#include <algorithm>
|
||||
using namespace clang::driver;
|
||||
|
||||
Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
|
||||
const Option *_Group, const Option *_Alias, unsigned Args)
|
||||
: Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
|
||||
NumArgs(Args), Unsupported(false), LinkerInput(false), NoOptAsInput(false),
|
||||
DriverOption(false), NoArgumentUnused(false), NoForward(false) {
|
||||
Option::Option(const OptTable::Info *info, OptSpecifier _ID,
|
||||
const Option *_Group, const Option *_Alias)
|
||||
: Info(info), ID(_ID.getID()), Group(_Group), Alias(_Alias) {
|
||||
|
||||
// Multi-level aliases are not supported, and alias options cannot
|
||||
// have groups. This just simplifies option tracking, it is not an
|
||||
// inherent limitation.
|
||||
assert((!Alias || (!Alias->Alias && !Group)) &&
|
||||
"Multi-level aliases and aliases with groups are unsupported.");
|
||||
|
||||
// Initialize rendering options based on the class.
|
||||
switch (Kind) {
|
||||
case GroupClass:
|
||||
case InputClass:
|
||||
case UnknownClass:
|
||||
RenderStyle = RenderValuesStyle;
|
||||
break;
|
||||
|
||||
case JoinedClass:
|
||||
case JoinedAndSeparateClass:
|
||||
RenderStyle = RenderJoinedStyle;
|
||||
break;
|
||||
|
||||
case CommaJoinedClass:
|
||||
RenderStyle = RenderCommaJoinedStyle;
|
||||
break;
|
||||
|
||||
case FlagClass:
|
||||
case SeparateClass:
|
||||
case MultiArgClass:
|
||||
case JoinedOrSeparateClass:
|
||||
RenderStyle = RenderSeparateStyle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Option::~Option() {
|
||||
|
@ -60,7 +33,7 @@ Option::~Option() {
|
|||
|
||||
void Option::dump() const {
|
||||
llvm::errs() << "<";
|
||||
switch (Kind) {
|
||||
switch (getKind()) {
|
||||
#define P(N) case N: llvm::errs() << #N; break
|
||||
P(GroupClass);
|
||||
P(InputClass);
|
||||
|
@ -75,7 +48,7 @@ void Option::dump() const {
|
|||
#undef P
|
||||
}
|
||||
|
||||
llvm::errs() << " Name:\"" << Name << '"';
|
||||
llvm::errs() << " Name:\"" << getName() << '"';
|
||||
|
||||
if (Group) {
|
||||
llvm::errs() << " Group:";
|
||||
|
@ -87,8 +60,8 @@ void Option::dump() const {
|
|||
Alias->dump();
|
||||
}
|
||||
|
||||
if (Kind == MultiArgClass)
|
||||
llvm::errs() << " NumArgs:" << NumArgs;
|
||||
if (getKind() == MultiArgClass)
|
||||
llvm::errs() << " NumArgs:" << getNumArgs();
|
||||
|
||||
llvm::errs() << ">\n";
|
||||
}
|
||||
|
@ -108,7 +81,7 @@ bool Option::matches(OptSpecifier Opt) const {
|
|||
}
|
||||
|
||||
Arg *Option::accept(const ArgList &Args, unsigned &Index) const {
|
||||
switch (Kind) {
|
||||
switch (getKind()) {
|
||||
case FlagClass:
|
||||
if (getName().size() != strlen(Args.getArgString(Index)))
|
||||
return 0;
|
||||
|
@ -164,14 +137,14 @@ Arg *Option::accept(const ArgList &Args, unsigned &Index) const {
|
|||
if (getName().size() != strlen(Args.getArgString(Index)))
|
||||
return 0;
|
||||
|
||||
Index += 1 + NumArgs;
|
||||
Index += 1 + getNumArgs();
|
||||
if (Index > Args.getNumInputArgStrings())
|
||||
return 0;
|
||||
|
||||
Arg *A = new Arg(getUnaliasedOption(), Index - 1 - NumArgs,
|
||||
Args.getArgString(Index - NumArgs));
|
||||
for (unsigned i = 1; i != NumArgs; ++i)
|
||||
A->getValues().push_back(Args.getArgString(Index - NumArgs + i));
|
||||
Arg *A = new Arg(getUnaliasedOption(), Index - 1 - getNumArgs(),
|
||||
Args.getArgString(Index - getNumArgs()));
|
||||
for (unsigned i = 1; i != getNumArgs(); ++i)
|
||||
A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
|
||||
return A;
|
||||
}
|
||||
case JoinedOrSeparateClass: {
|
||||
|
|
Загрузка…
Ссылка в новой задаче