xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Option/Arg.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- Arg.h - Parsed Argument Classes --------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// Defines the llvm::Arg class for parsed arguments.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_OPTION_ARG_H
15 #define LLVM_OPTION_ARG_H
16 
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Option/Option.h"
20 #include "llvm/Support/Compiler.h"
21 #include <string>
22 
23 namespace llvm {
24 
25 class raw_ostream;
26 
27 namespace opt {
28 
29 class ArgList;
30 
31 /// A concrete instance of a particular driver option.
32 ///
33 /// The Arg class encodes just enough information to be able to
34 /// derive the argument values efficiently.
35 class Arg {
36 private:
37   /// The option this argument is an instance of.
38   const Option Opt;
39 
40   /// The argument this argument was derived from (during tool chain
41   /// argument translation), if any.
42   const Arg *BaseArg;
43 
44   /// How this instance of the option was spelled.
45   StringRef Spelling;
46 
47   /// The index at which this argument appears in the containing
48   /// ArgList.
49   unsigned Index;
50 
51   /// Was this argument used to affect compilation?
52   ///
53   /// This is used to generate an "argument unused" warning (without
54   /// clang::driver::options::TargetSpecific) or "unsupported option" error
55   /// (with TargetSpecific).
56   mutable unsigned Claimed : 1;
57 
58   /// Used by an unclaimed option with the TargetSpecific flag. If set, report
59   /// an "argument unused" warning instead of an "unsupported option" error.
60   unsigned IgnoredTargetSpecific : 1;
61 
62   /// Does this argument own its values?
63   mutable unsigned OwnsValues : 1;
64 
65   /// The argument values, as C strings.
66   SmallVector<const char *, 2> Values;
67 
68   /// If this arg was created through an alias, this is the original alias arg.
69   /// For example, *this might be "-finput-charset=utf-8" and Alias might
70   /// point to an arg representing "/source-charset:utf-8".
71   std::unique_ptr<Arg> Alias;
72 
73 public:
74   LLVM_ABI Arg(const Option Opt, StringRef Spelling, unsigned Index,
75                const Arg *BaseArg = nullptr);
76   LLVM_ABI Arg(const Option Opt, StringRef Spelling, unsigned Index,
77                const char *Value0, const Arg *BaseArg = nullptr);
78   LLVM_ABI Arg(const Option Opt, StringRef Spelling, unsigned Index,
79                const char *Value0, const char *Value1,
80                const Arg *BaseArg = nullptr);
81   Arg(const Arg &) = delete;
82   Arg &operator=(const Arg &) = delete;
83   LLVM_ABI ~Arg();
84 
getOption()85   const Option &getOption() const { return Opt; }
86 
87   /// Returns the used prefix and name of the option:
88   /// For `--foo=bar`, returns `--foo=`.
89   /// This is often the wrong function to call:
90   /// * Use `getValue()` to get `bar`.
91   /// * Use `getAsString()` to get a string suitable for printing an Arg in
92   ///   a diagnostic.
getSpelling()93   StringRef getSpelling() const { return Spelling; }
94 
getIndex()95   unsigned getIndex() const { return Index; }
96 
97   /// Return the base argument which generated this arg.
98   ///
99   /// This is either the argument itself or the argument it was
100   /// derived from during tool chain specific argument translation.
getBaseArg()101   const Arg &getBaseArg() const {
102     return BaseArg ? *BaseArg : *this;
103   }
getBaseArg()104   Arg &getBaseArg() { return BaseArg ? const_cast<Arg &>(*BaseArg) : *this; }
setBaseArg(const Arg * BaseArg)105   void setBaseArg(const Arg *BaseArg) { this->BaseArg = BaseArg; }
106 
107   /// Args are converted to their unaliased form.  For args that originally
108   /// came from an alias, this returns the alias the arg was produced from.
getAlias()109   const Arg* getAlias() const { return Alias.get(); }
setAlias(std::unique_ptr<Arg> Alias)110   void setAlias(std::unique_ptr<Arg> Alias) { this->Alias = std::move(Alias); }
111 
getOwnsValues()112   bool getOwnsValues() const { return OwnsValues; }
setOwnsValues(bool Value)113   void setOwnsValues(bool Value) const { OwnsValues = Value; }
114 
isClaimed()115   bool isClaimed() const { return getBaseArg().Claimed; }
claim()116   void claim() const { getBaseArg().Claimed = true; }
117 
isIgnoredTargetSpecific()118   bool isIgnoredTargetSpecific() const {
119     return getBaseArg().IgnoredTargetSpecific;
120   }
ignoreTargetSpecific()121   void ignoreTargetSpecific() {
122     getBaseArg().IgnoredTargetSpecific = true;
123   }
124 
getNumValues()125   unsigned getNumValues() const { return Values.size(); }
126 
127   const char *getValue(unsigned N = 0) const {
128     return Values[N];
129   }
130 
getValues()131   SmallVectorImpl<const char *> &getValues() { return Values; }
getValues()132   const SmallVectorImpl<const char *> &getValues() const { return Values; }
133 
containsValue(StringRef Value)134   bool containsValue(StringRef Value) const {
135     return llvm::is_contained(Values, Value);
136   }
137 
138   /// Append the argument onto the given array as strings.
139   LLVM_ABI void render(const ArgList &Args, ArgStringList &Output) const;
140 
141   /// Append the argument, render as an input, onto the given
142   /// array as strings.
143   ///
144   /// The distinction is that some options only render their values
145   /// when rendered as a input (e.g., Xlinker).
146   LLVM_ABI void renderAsInput(const ArgList &Args, ArgStringList &Output) const;
147 
148   LLVM_ABI void print(raw_ostream &O) const;
149   LLVM_ABI void dump() const;
150 
151   /// Return a formatted version of the argument and its values, for
152   /// diagnostics. Since this is for diagnostics, if this Arg was produced
153   /// through an alias, this returns the string representation of the alias
154   /// that the user wrote.
155   LLVM_ABI std::string getAsString(const ArgList &Args) const;
156 };
157 
158 } // end namespace opt
159 
160 } // end namespace llvm
161 
162 #endif // LLVM_OPTION_ARG_H
163