Convert Arg, ArgList, and Option to dump() to dbgs() rather than errs().
[oota-llvm.git] / include / llvm / Option / ArgList.h
index 7d09f8e6cc8396eb10ff80376aeafcec712a4d92..89771b5c3cf11392766aec5ea4bc8b814b809ef8 100644 (file)
@@ -7,21 +7,23 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_SUPPORT_ARGLIST_H_
-#define LLVM_SUPPORT_ARGLIST_H_
+#ifndef LLVM_OPTION_ARGLIST_H
+#define LLVM_OPTION_ARGLIST_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Option/Option.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Option/Arg.h"
 #include "llvm/Option/OptSpecifier.h"
-
+#include "llvm/Option/Option.h"
 #include <list>
+#include <memory>
 #include <string>
 #include <vector>
 
 namespace llvm {
 namespace opt {
-class Arg;
 class ArgList;
 class Option;
 
@@ -52,10 +54,10 @@ public:
   typedef std::forward_iterator_tag   iterator_category;
   typedef std::ptrdiff_t              difference_type;
 
-  arg_iterator(SmallVectorImpl<Arg*>::const_iterator it,
-                const ArgList &_Args, OptSpecifier _Id0 = 0U,
-                OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
-    : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
+  arg_iterator(SmallVectorImpl<Arg *>::const_iterator it, const ArgList &Args,
+               OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
+               OptSpecifier Id2 = 0U)
+      : Current(it), Args(Args), Id0(Id0), Id1(Id1), Id2(Id2) {
     SkipToNextArg();
   }
 
@@ -90,10 +92,6 @@ public:
 /// check for the presence of Arg instances for a particular Option
 /// and to iterate over groups of arguments.
 class ArgList {
-private:
-  ArgList(const ArgList &) LLVM_DELETED_FUNCTION;
-  void operator=(const ArgList &) LLVM_DELETED_FUNCTION;
-
 public:
   typedef SmallVector<Arg*, 16> arglist_type;
   typedef arglist_type::iterator iterator;
@@ -106,10 +104,25 @@ private:
   arglist_type Args;
 
 protected:
-  ArgList();
+  // Make the default special members protected so they won't be used to slice
+  // derived objects, but can still be used by derived objects to implement
+  // their own special members.
+  ArgList() = default;
+  // Explicit move operations to ensure the container is cleared post-move
+  // otherwise it could lead to a double-delete in the case of moving of an
+  // InputArgList which deletes the contents of the container. If we could fix
+  // up the ownership here (delegate storage/ownership to the derived class so
+  // it can be a container of unique_ptr) this would be simpler.
+  ArgList(ArgList &&RHS) : Args(std::move(RHS.Args)) { RHS.Args.clear(); }
+  ArgList &operator=(ArgList &&RHS) {
+    Args = std::move(RHS.Args);
+    RHS.Args.clear();
+    return *this;
+  }
+  // Protect the dtor to ensure this type is never destroyed polymorphically.
+  ~ArgList() = default;
 
 public:
-  virtual ~ArgList();
 
   /// @name Arg Access
   /// @{
@@ -146,6 +159,12 @@ public:
     return arg_iterator(Args.end(), *this);
   }
 
+  iterator_range<arg_iterator> filtered(OptSpecifier Id0 = 0U,
+                                        OptSpecifier Id1 = 0U,
+                                        OptSpecifier Id2 = 0U) const {
+    return make_range(filtered_begin(Id0, Id1, Id2), filtered_end());
+  }
+
   /// @}
   /// @name Arg Removal
   /// @{
@@ -161,22 +180,27 @@ public:
   ///
   /// \p Claim Whether the argument should be claimed, if it exists.
   bool hasArgNoClaim(OptSpecifier Id) const {
-    return getLastArgNoClaim(Id) != 0;
+    return getLastArgNoClaim(Id) != nullptr;
   }
   bool hasArg(OptSpecifier Id) const {
-    return getLastArg(Id) != 0;
+    return getLastArg(Id) != nullptr;
   }
   bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
-    return getLastArg(Id0, Id1) != 0;
+    return getLastArg(Id0, Id1) != nullptr;
   }
   bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
-    return getLastArg(Id0, Id1, Id2) != 0;
+    return getLastArg(Id0, Id1, Id2) != nullptr;
   }
 
   /// getLastArg - Return the last argument matching \p Id, or null.
   ///
   /// \p Claim Whether the argument should be claimed, if it exists.
   Arg *getLastArgNoClaim(OptSpecifier Id) const;
+  Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1) const;
+  Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1,
+                         OptSpecifier Id2) const;
+  Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+                         OptSpecifier Id3) const;
   Arg *getLastArg(OptSpecifier Id) const;
   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
@@ -223,8 +247,20 @@ public:
   /// negation are present, the last one wins.
   bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
 
+  /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative
+  /// form \p Neg, return true if the option or its alias is present, false if
+  /// the negation is present, and \p Default if none of the options are
+  /// given. If multiple options are present, the last one wins.
+  bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
+               bool Default = true) const;
+
   /// AddLastArg - Render only the last argument match \p Id0, if present.
   void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
+  void AddLastArg(ArgStringList &Output, OptSpecifier Id0,
+                  OptSpecifier Id1) const;
+
+  /// AddAllArgs - Render all arguments matching any of the given ids.
+  void AddAllArgs(ArgStringList &Output, ArrayRef<OptSpecifier> Ids) const;
 
   /// AddAllArgs - Render all arguments matching the given ids.
   void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
@@ -257,26 +293,26 @@ public:
   /// @name Arg Synthesis
   /// @{
 
-  /// MakeArgString - Construct a constant string pointer whose
+  /// Construct a constant string pointer whose
   /// lifetime will match that of the ArgList.
-  virtual const char *MakeArgString(StringRef Str) const = 0;
-  const char *MakeArgString(const char *Str) const {
-    return MakeArgString(StringRef(Str));
+  virtual const char *MakeArgStringRef(StringRef Str) const = 0;
+  const char *MakeArgString(const Twine &Str) const {
+    SmallString<256> Buf;
+    return MakeArgStringRef(Str.toStringRef(Buf));
   }
-  const char *MakeArgString(std::string Str) const {
-    return MakeArgString(StringRef(Str));
-  }
-  const char *MakeArgString(const Twine &Str) const;
 
   /// \brief Create an arg string for (\p LHS + \p RHS), reusing the
   /// string at \p Index if possible.
   const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS,
                                         StringRef RHS) const;
 
+  void print(raw_ostream &O) const;
+  void dump() const;
+
   /// @}
 };
 
-class InputArgList : public ArgList  {
+class InputArgList final : public ArgList {
 private:
   /// List of argument strings used by the contained Args.
   ///
@@ -295,15 +331,30 @@ private:
   /// The number of original input argument strings.
   unsigned NumInputArgStrings;
 
+  /// Release allocated arguments.
+  void releaseMemory();
+
 public:
   InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
-  ~InputArgList();
+  InputArgList(InputArgList &&RHS)
+      : ArgList(std::move(RHS)), ArgStrings(std::move(RHS.ArgStrings)),
+        SynthesizedStrings(std::move(RHS.SynthesizedStrings)),
+        NumInputArgStrings(RHS.NumInputArgStrings) {}
+  InputArgList &operator=(InputArgList &&RHS) {
+    releaseMemory();
+    ArgList::operator=(std::move(RHS));
+    ArgStrings = std::move(RHS.ArgStrings);
+    SynthesizedStrings = std::move(RHS.SynthesizedStrings);
+    NumInputArgStrings = RHS.NumInputArgStrings;
+    return *this;
+  }
+  ~InputArgList() { releaseMemory(); }
 
-  virtual const char *getArgString(unsigned Index) const {
+  const char *getArgString(unsigned Index) const override {
     return ArgStrings[Index];
   }
 
-  virtual unsigned getNumInputArgStrings() const {
+  unsigned getNumInputArgStrings() const override {
     return NumInputArgStrings;
   }
 
@@ -315,29 +366,29 @@ public:
   unsigned MakeIndex(StringRef String0) const;
   unsigned MakeIndex(StringRef String0, StringRef String1) const;
 
-  virtual const char *MakeArgString(StringRef Str) const;
+  using ArgList::MakeArgString;
+  const char *MakeArgStringRef(StringRef Str) const override;
 
   /// @}
 };
 
 /// DerivedArgList - An ordered collection of driver arguments,
 /// whose storage may be in another argument list.
-class DerivedArgList : public ArgList {
+class DerivedArgList final : public ArgList {
   const InputArgList &BaseArgs;
 
   /// The list of arguments we synthesized.
-  mutable arglist_type SynthesizedArgs;
+  mutable SmallVector<std::unique_ptr<Arg>, 16> SynthesizedArgs;
 
 public:
   /// Construct a new derived arg list from \p BaseArgs.
   DerivedArgList(const InputArgList &BaseArgs);
-  ~DerivedArgList();
 
-  virtual const char *getArgString(unsigned Index) const {
+  const char *getArgString(unsigned Index) const override {
     return BaseArgs.getArgString(Index);
   }
 
-  virtual unsigned getNumInputArgStrings() const {
+  unsigned getNumInputArgStrings() const override {
     return BaseArgs.getNumInputArgStrings();
   }
 
@@ -350,11 +401,10 @@ public:
 
   /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
   /// (to be freed).
-  void AddSynthesizedArg(Arg *A) {
-    SynthesizedArgs.push_back(A);
-  }
+  void AddSynthesizedArg(Arg *A);
 
-  virtual const char *MakeArgString(StringRef Str) const;
+  using ArgList::MakeArgString;
+  const char *MakeArgStringRef(StringRef Str) const override;
 
   /// AddFlagArg - Construct a new FlagArg for the given option \p Id and
   /// append it to the argument list.