Option.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Option.h - Abstract Driver Options -----------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_OPTION_OPTION_H
  14. #define LLVM_OPTION_OPTION_H
  15. #include "llvm/ADT/SmallVector.h"
  16. #include "llvm/ADT/StringRef.h"
  17. #include "llvm/Option/OptSpecifier.h"
  18. #include "llvm/Option/OptTable.h"
  19. #include "llvm/Support/ErrorHandling.h"
  20. #include <cassert>
  21. #include <string>
  22. namespace llvm {
  23. class raw_ostream;
  24. namespace opt {
  25. class Arg;
  26. class ArgList;
  27. /// ArgStringList - Type used for constructing argv lists for subprocesses.
  28. using ArgStringList = SmallVector<const char *, 16>;
  29. /// Base flags for all options. Custom flags may be added after.
  30. enum DriverFlag {
  31. HelpHidden = (1 << 0),
  32. RenderAsInput = (1 << 1),
  33. RenderJoined = (1 << 2),
  34. RenderSeparate = (1 << 3)
  35. };
  36. /// Option - Abstract representation for a single form of driver
  37. /// argument.
  38. ///
  39. /// An Option class represents a form of option that the driver
  40. /// takes, for example how many arguments the option has and how
  41. /// they can be provided. Individual option instances store
  42. /// additional information about what group the option is a member
  43. /// of (if any), if the option is an alias, and a number of
  44. /// flags. At runtime the driver parses the command line into
  45. /// concrete Arg instances, each of which corresponds to a
  46. /// particular Option instance.
  47. class Option {
  48. public:
  49. enum OptionClass {
  50. GroupClass = 0,
  51. InputClass,
  52. UnknownClass,
  53. FlagClass,
  54. JoinedClass,
  55. ValuesClass,
  56. SeparateClass,
  57. RemainingArgsClass,
  58. RemainingArgsJoinedClass,
  59. CommaJoinedClass,
  60. MultiArgClass,
  61. JoinedOrSeparateClass,
  62. JoinedAndSeparateClass
  63. };
  64. enum RenderStyleKind {
  65. RenderCommaJoinedStyle,
  66. RenderJoinedStyle,
  67. RenderSeparateStyle,
  68. RenderValuesStyle
  69. };
  70. protected:
  71. const OptTable::Info *Info;
  72. const OptTable *Owner;
  73. public:
  74. Option(const OptTable::Info *Info, const OptTable *Owner);
  75. bool isValid() const {
  76. return Info != nullptr;
  77. }
  78. unsigned getID() const {
  79. assert(Info && "Must have a valid info!");
  80. return Info->ID;
  81. }
  82. OptionClass getKind() const {
  83. assert(Info && "Must have a valid info!");
  84. return OptionClass(Info->Kind);
  85. }
  86. /// Get the name of this option without any prefix.
  87. StringRef getName() const {
  88. assert(Info && "Must have a valid info!");
  89. return Info->Name;
  90. }
  91. const Option getGroup() const {
  92. assert(Info && "Must have a valid info!");
  93. assert(Owner && "Must have a valid owner!");
  94. return Owner->getOption(Info->GroupID);
  95. }
  96. const Option getAlias() const {
  97. assert(Info && "Must have a valid info!");
  98. assert(Owner && "Must have a valid owner!");
  99. return Owner->getOption(Info->AliasID);
  100. }
  101. /// Get the alias arguments as a \0 separated list.
  102. /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
  103. const char *getAliasArgs() const {
  104. assert(Info && "Must have a valid info!");
  105. assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
  106. "AliasArgs should be either 0 or non-empty.");
  107. return Info->AliasArgs;
  108. }
  109. /// Get the default prefix for this option.
  110. StringRef getPrefix() const {
  111. return Info->Prefixes.empty()
  112. ? StringRef()
  113. : static_cast<const StringRef &>(Info->Prefixes[0]);
  114. }
  115. /// Get the name of this option with the default prefix.
  116. std::string getPrefixedName() const {
  117. std::string Ret(getPrefix());
  118. Ret += getName();
  119. return Ret;
  120. }
  121. /// Get the help text for this option.
  122. StringRef getHelpText() const {
  123. assert(Info && "Must have a valid info!");
  124. return Info->HelpText;
  125. }
  126. /// Get the meta-variable list for this option.
  127. StringRef getMetaVar() const {
  128. assert(Info && "Must have a valid info!");
  129. return Info->MetaVar;
  130. }
  131. unsigned getNumArgs() const { return Info->Param; }
  132. bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
  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 ValuesClass:
  150. case SeparateClass:
  151. case MultiArgClass:
  152. case JoinedOrSeparateClass:
  153. case RemainingArgsClass:
  154. case RemainingArgsJoinedClass:
  155. return RenderSeparateStyle;
  156. }
  157. llvm_unreachable("Unexpected kind!");
  158. }
  159. /// Test if this option has the flag \a Val.
  160. bool hasFlag(unsigned Val) const {
  161. return Info->Flags & Val;
  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. /// getRenderName - Return the name to use when rendering this
  171. /// option.
  172. StringRef getRenderName() const {
  173. return getUnaliasedOption().getName();
  174. }
  175. /// matches - Predicate for whether this option is part of the
  176. /// given option (which may be a group).
  177. ///
  178. /// Note that matches against options which are an alias should never be
  179. /// done -- aliases do not participate in matching and so such a query will
  180. /// always be false.
  181. bool matches(OptSpecifier ID) const;
  182. /// Potentially accept the current argument, returning a new Arg instance,
  183. /// or 0 if the option does not accept this argument (or the argument is
  184. /// missing values).
  185. ///
  186. /// If the option accepts the current argument, accept() sets
  187. /// Index to the position where argument parsing should resume
  188. /// (even if the argument is missing values).
  189. ///
  190. /// \p CurArg The argument to be matched. It may be shorter than the
  191. /// underlying storage to represent a Joined argument.
  192. /// \p GroupedShortOption If true, we are handling the fallback case of
  193. /// parsing a prefix of the current argument as a short option.
  194. std::unique_ptr<Arg> accept(const ArgList &Args, StringRef CurArg,
  195. bool GroupedShortOption, unsigned &Index) const;
  196. private:
  197. std::unique_ptr<Arg> acceptInternal(const ArgList &Args, StringRef CurArg,
  198. unsigned &Index) const;
  199. public:
  200. void print(raw_ostream &O) const;
  201. void dump() const;
  202. };
  203. } // end namespace opt
  204. } // end namespace llvm
  205. #endif // LLVM_OPTION_OPTION_H
  206. #ifdef __GNUC__
  207. #pragma GCC diagnostic pop
  208. #endif