Option.h revision 4c5e43da7792f75567b693105cc53e3f1992ad98
1//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_OPTION_OPTION_H
11#define LLVM_OPTION_OPTION_H
12
13#include "llvm/ADT/SmallVector.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Option/OptTable.h"
16#include "llvm/Support/ErrorHandling.h"
17
18namespace llvm {
19namespace opt {
20class Arg;
21class ArgList;
22/// ArgStringList - Type used for constructing argv lists for subprocesses.
23typedef SmallVector<const char*, 16> ArgStringList;
24
25/// Base flags for all options. Custom flags may be added after.
26enum DriverFlag {
27  HelpHidden       = (1 << 0),
28  RenderAsInput    = (1 << 1),
29  RenderJoined     = (1 << 2),
30  RenderSeparate   = (1 << 3)
31};
32
33/// Option - Abstract representation for a single form of driver
34/// argument.
35///
36/// An Option class represents a form of option that the driver
37/// takes, for example how many arguments the option has and how
38/// they can be provided. Individual option instances store
39/// additional information about what group the option is a member
40/// of (if any), if the option is an alias, and a number of
41/// flags. At runtime the driver parses the command line into
42/// concrete Arg instances, each of which corresponds to a
43/// particular Option instance.
44class Option {
45public:
46  enum OptionClass {
47    GroupClass = 0,
48    InputClass,
49    UnknownClass,
50    FlagClass,
51    JoinedClass,
52    SeparateClass,
53    RemainingArgsClass,
54    CommaJoinedClass,
55    MultiArgClass,
56    JoinedOrSeparateClass,
57    JoinedAndSeparateClass
58  };
59
60  enum RenderStyleKind {
61    RenderCommaJoinedStyle,
62    RenderJoinedStyle,
63    RenderSeparateStyle,
64    RenderValuesStyle
65  };
66
67protected:
68  const OptTable::Info *Info;
69  const OptTable *Owner;
70
71public:
72  Option(const OptTable::Info *Info, const OptTable *Owner);
73
74  bool isValid() const {
75    return Info != nullptr;
76  }
77
78  unsigned getID() const {
79    assert(Info && "Must have a valid info!");
80    return Info->ID;
81  }
82
83  OptionClass getKind() const {
84    assert(Info && "Must have a valid info!");
85    return OptionClass(Info->Kind);
86  }
87
88  /// \brief Get the name of this option without any prefix.
89  StringRef getName() const {
90    assert(Info && "Must have a valid info!");
91    return Info->Name;
92  }
93
94  const Option getGroup() const {
95    assert(Info && "Must have a valid info!");
96    assert(Owner && "Must have a valid owner!");
97    return Owner->getOption(Info->GroupID);
98  }
99
100  const Option getAlias() const {
101    assert(Info && "Must have a valid info!");
102    assert(Owner && "Must have a valid owner!");
103    return Owner->getOption(Info->AliasID);
104  }
105
106  /// \brief Get the alias arguments as a \0 separated list.
107  /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
108  const char *getAliasArgs() const {
109    assert(Info && "Must have a valid info!");
110    assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
111           "AliasArgs should be either 0 or non-empty.");
112
113    return Info->AliasArgs;
114  }
115
116  /// \brief Get the default prefix for this option.
117  StringRef getPrefix() const {
118    const char *Prefix = *Info->Prefixes;
119    return Prefix ? Prefix : StringRef();
120  }
121
122  /// \brief Get the name of this option with the default prefix.
123  std::string getPrefixedName() const {
124    std::string Ret = getPrefix();
125    Ret += getName();
126    return Ret;
127  }
128
129  unsigned getNumArgs() const { return Info->Param; }
130
131  bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
132
133  RenderStyleKind getRenderStyle() const {
134    if (Info->Flags & RenderJoined)
135      return RenderJoinedStyle;
136    if (Info->Flags & RenderSeparate)
137      return RenderSeparateStyle;
138    switch (getKind()) {
139    case GroupClass:
140    case InputClass:
141    case UnknownClass:
142      return RenderValuesStyle;
143    case JoinedClass:
144    case JoinedAndSeparateClass:
145      return RenderJoinedStyle;
146    case CommaJoinedClass:
147      return RenderCommaJoinedStyle;
148    case FlagClass:
149    case SeparateClass:
150    case MultiArgClass:
151    case JoinedOrSeparateClass:
152    case RemainingArgsClass:
153      return RenderSeparateStyle;
154    }
155    llvm_unreachable("Unexpected kind!");
156  }
157
158  /// Test if this option has the flag \a Val.
159  bool hasFlag(unsigned Val) const {
160    return Info->Flags & Val;
161  }
162
163  /// getUnaliasedOption - Return the final option this option
164  /// aliases (itself, if the option has no alias).
165  const Option getUnaliasedOption() const {
166    const Option Alias = getAlias();
167    if (Alias.isValid()) return Alias.getUnaliasedOption();
168    return *this;
169  }
170
171  /// getRenderName - Return the name to use when rendering this
172  /// option.
173  StringRef getRenderName() const {
174    return getUnaliasedOption().getName();
175  }
176
177  /// matches - Predicate for whether this option is part of the
178  /// given option (which may be a group).
179  ///
180  /// Note that matches against options which are an alias should never be
181  /// done -- aliases do not participate in matching and so such a query will
182  /// always be false.
183  bool matches(OptSpecifier ID) const;
184
185  /// accept - Potentially accept the current argument, returning a
186  /// new Arg instance, or 0 if the option does not accept this
187  /// argument (or the argument is missing values).
188  ///
189  /// If the option accepts the current argument, accept() sets
190  /// Index to the position where argument parsing should resume
191  /// (even if the argument is missing values).
192  ///
193  /// \param ArgSize The number of bytes taken up by the matched Option prefix
194  ///                and name. This is used to determine where joined values
195  ///                start.
196  Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
197
198  void dump() const;
199};
200
201} // end namespace opt
202} // end namespace llvm
203
204#endif
205