Option.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. const char *Prefix = *Info->Prefixes;
  112. return Prefix ? Prefix : StringRef();
  113. }
  114. /// Get the name of this option with the default prefix.
  115. std::string getPrefixedName() const {
  116. std::string Ret(getPrefix());
  117. Ret += getName();
  118. return Ret;
  119. }
  120. /// Get the help text for this option.
  121. StringRef getHelpText() const {
  122. assert(Info && "Must have a valid info!");
  123. return Info->HelpText;
  124. }
  125. /// Get the meta-variable list for this option.
  126. StringRef getMetaVar() const {
  127. assert(Info && "Must have a valid info!");
  128. return Info->MetaVar;
  129. }
  130. unsigned getNumArgs() const { return Info->Param; }
  131. bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
  132. RenderStyleKind getRenderStyle() const {
  133. if (Info->Flags & RenderJoined)
  134. return RenderJoinedStyle;
  135. if (Info->Flags & RenderSeparate)
  136. return RenderSeparateStyle;
  137. switch (getKind()) {
  138. case GroupClass:
  139. case InputClass:
  140. case UnknownClass:
  141. return RenderValuesStyle;
  142. case JoinedClass:
  143. case JoinedAndSeparateClass:
  144. return RenderJoinedStyle;
  145. case CommaJoinedClass:
  146. return RenderCommaJoinedStyle;
  147. case FlagClass:
  148. case ValuesClass:
  149. case SeparateClass:
  150. case MultiArgClass:
  151. case JoinedOrSeparateClass:
  152. case RemainingArgsClass:
  153. case RemainingArgsJoinedClass:
  154. return RenderSeparateStyle;
  155. }
  156. llvm_unreachable("Unexpected kind!");
  157. }
  158. /// Test if this option has the flag \a Val.
  159. bool hasFlag(unsigned Val) const {
  160. return Info->Flags & Val;
  161. }
  162. /// getUnaliasedOption - Return the final option this option
  163. /// aliases (itself, if the option has no alias).
  164. const Option getUnaliasedOption() const {
  165. const Option Alias = getAlias();
  166. if (Alias.isValid()) return Alias.getUnaliasedOption();
  167. return *this;
  168. }
  169. /// getRenderName - Return the name to use when rendering this
  170. /// option.
  171. StringRef getRenderName() const {
  172. return getUnaliasedOption().getName();
  173. }
  174. /// matches - Predicate for whether this option is part of the
  175. /// given option (which may be a group).
  176. ///
  177. /// Note that matches against options which are an alias should never be
  178. /// done -- aliases do not participate in matching and so such a query will
  179. /// always be false.
  180. bool matches(OptSpecifier ID) const;
  181. /// Potentially accept the current argument, returning a new Arg instance,
  182. /// or 0 if the option does not accept this argument (or the argument is
  183. /// missing values).
  184. ///
  185. /// If the option accepts the current argument, accept() sets
  186. /// Index to the position where argument parsing should resume
  187. /// (even if the argument is missing values).
  188. ///
  189. /// \p CurArg The argument to be matched. It may be shorter than the
  190. /// underlying storage to represent a Joined argument.
  191. /// \p GroupedShortOption If true, we are handling the fallback case of
  192. /// parsing a prefix of the current argument as a short option.
  193. std::unique_ptr<Arg> accept(const ArgList &Args, StringRef CurArg,
  194. bool GroupedShortOption, unsigned &Index) const;
  195. private:
  196. std::unique_ptr<Arg> acceptInternal(const ArgList &Args, StringRef CurArg,
  197. unsigned &Index) const;
  198. public:
  199. void print(raw_ostream &O) const;
  200. void dump() const;
  201. };
  202. } // end namespace opt
  203. } // end namespace llvm
  204. #endif // LLVM_OPTION_OPTION_H
  205. #ifdef __GNUC__
  206. #pragma GCC diagnostic pop
  207. #endif