blob: dc69fa230001393217098b0073eba62a3bc17394 [file] [log] [blame]
//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_DRIVER_OPTION_H_
#define CLANG_DRIVER_OPTION_H_
#include "clang/Driver/OptTable.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "clang/Basic/LLVM.h"
namespace clang {
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.
///
/// 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,
SeparateClass,
CommaJoinedClass,
MultiArgClass,
JoinedOrSeparateClass,
JoinedAndSeparateClass
};
enum RenderStyleKind {
RenderCommaJoinedStyle,
RenderJoinedStyle,
RenderSeparateStyle,
RenderValuesStyle
};
private:
const OptTable::Info *Info;
const OptTable *Owner;
public:
Option(const OptTable::Info *Info, const OptTable *Owner);
~Option();
bool isValid() const {
return Info != 0;
}
unsigned getID() const { return Info->ID; }
OptionClass getKind() const { return OptionClass(Info->Kind); }
StringRef getName() const { return Info->Name; }
const Option getGroup() const { return Owner->getOption(Info->GroupID); }
const Option getAlias() const { return Owner->getOption(Info->AliasID); }
unsigned getNumArgs() const { return Info->Param; }
bool isUnsupported() const { return Info->Flags & options::Unsupported; }
bool isLinkerInput() const { return Info->Flags & options::LinkerInput; }
bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;}
RenderStyleKind getRenderStyle() const {
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!");
}
bool isDriverOption() const { return Info->Flags & options::DriverOption; }
bool hasNoArgumentUnused() const {
return Info->Flags & options::NoArgumentUnused;
}
bool hasNoForward() const { return Info->Flags & options::NoForward; }
bool isCC1Option() const { return Info->Flags & options::CC1Option; }
bool hasForwardToGCC() const {
return !hasNoForward() && !isDriverOption() && !isLinkerInput();
}
/// 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).
Arg *accept(const ArgList &Args, unsigned &Index) const;
void dump() const;
};
} // end namespace driver
} // end namespace clang
#endif