CommandLine.h revision 630fcb86785f96501126e52009619b475403dc62
1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//===- llvm/Support/CommandLine.h - Command line handler --------*- C++ -*-===//
263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//                     The LLVM Compiler Infrastructure
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//===----------------------------------------------------------------------===//
9cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
10cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner// This class implements a command line argument processor that is useful when
11cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner// creating a tool.  It provides a simple, minimalistic interface that is easily
12cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner// extensible and supports nonlocal (library) command line options.
13cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
14331de23705a719514e37c211f327379688f81b0dChris Lattner// Note that rather than trying to figure out what this code does, you should
15331de23705a719514e37c211f327379688f81b0dChris Lattner// read the library documentation located in docs/CommandLine.html or looks at
16331de23705a719514e37c211f327379688f81b0dChris Lattner// the many example usages in tools/*/*.cpp
17cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
18cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
19cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
20551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#ifndef LLVM_SUPPORT_COMMANDLINE_H
21551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#define LLVM_SUPPORT_COMMANDLINE_H
22cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
23551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/type_traits.h"
2466c5fd6c537269eaef0f630fa14360dcaff6a295Jeff Cohen#include "llvm/Support/DataTypes.h"
257422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner#include "llvm/Support/Compiler.h"
263b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner#include "llvm/ADT/SmallVector.h"
27630fcb86785f96501126e52009619b475403dc62Misha Brukman#include <cassert>
28630fcb86785f96501126e52009619b475403dc62Misha Brukman#include <cstdarg>
29cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include <string>
30cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include <utility>
31630fcb86785f96501126e52009619b475403dc62Misha Brukman#include <vector>
32be583b914d8156b99d3da264d5adca37fee8dbc9John Criswell
33d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
347b3d73b7ecbecf423c3766e596b6086767444363Chris Lattner
35bf0ac3fe69aa9e1bfcffec36ea53dadbb97c6b4dChris Lattner/// cl Namespace - This namespace contains all of the command line option
36bf0ac3fe69aa9e1bfcffec36ea53dadbb97c6b4dChris Lattner/// processing machinery.  It is intentionally a short name to make qualified
37bf0ac3fe69aa9e1bfcffec36ea53dadbb97c6b4dChris Lattner/// usage concise.
38bf0ac3fe69aa9e1bfcffec36ea53dadbb97c6b4dChris Lattnernamespace cl {
39cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
40cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
41331de23705a719514e37c211f327379688f81b0dChris Lattner// ParseCommandLineOptions - Command line option processing entry point.
42cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
439a5263241d40d493445d7f386b4d76be088c3ac1Dan Gohmanvoid ParseCommandLineOptions(int argc, char **argv,
44beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov                             const char *Overview = 0,
45beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov                             bool ReadResponseFiles = false);
46cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
47cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
4806b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke// ParseEnvironmentOptions - Environment variable option processing alternate
4906b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke//                           entry point.
5006b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke//
51c48ef2ae36e2169872a828a5399ccd1993837915Brian Gaekevoid ParseEnvironmentOptions(const char *progName, const char *envvar,
52beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov                             const char *Overview = 0,
53beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov                             bool ReadResponseFiles = false);
5406b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke
55515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer///===---------------------------------------------------------------------===//
56515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer/// SetVersionPrinter - Override the default (LLVM specific) version printer
57515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer///                     used to print out the version when --version is given
583ab264a985de3d86e0d1f5716f6d633fd8538618Dan Gohman///                     on the command line. This allows other systems using the
59515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer///                     CommandLine utilities to print their own version string.
60515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencervoid SetVersionPrinter(void (*func)());
61515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer
6269d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattner
6369d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattner// MarkOptionsChanged - Internal helper function.
6469d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattnervoid MarkOptionsChanged();
6569d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattner
6606b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke//===----------------------------------------------------------------------===//
67331de23705a719514e37c211f327379688f81b0dChris Lattner// Flags permitted to be passed to command line arguments
68331de23705a719514e37c211f327379688f81b0dChris Lattner//
69cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
701e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencerenum NumOccurrences {          // Flags for the number of occurrences allowed
71b5c520bfb6505caaa6ad8468b372530d44c8b253Misha Brukman  Optional        = 0x01,      // Zero or One occurrence
72b5c520bfb6505caaa6ad8468b372530d44c8b253Misha Brukman  ZeroOrMore      = 0x02,      // Zero or more occurrences allowed
73b5c520bfb6505caaa6ad8468b372530d44c8b253Misha Brukman  Required        = 0x03,      // One occurrence required
74b5c520bfb6505caaa6ad8468b372530d44c8b253Misha Brukman  OneOrMore       = 0x04,      // One or more occurrences required
75cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
76331de23705a719514e37c211f327379688f81b0dChris Lattner  // ConsumeAfter - Indicates that this option is fed anything that follows the
77331de23705a719514e37c211f327379688f81b0dChris Lattner  // last positional argument required by the application (it is an error if
78331de23705a719514e37c211f327379688f81b0dChris Lattner  // there are zero positional arguments, and a ConsumeAfter option is used).
79331de23705a719514e37c211f327379688f81b0dChris Lattner  // Thus, for example, all arguments to LLI are processed until a filename is
80331de23705a719514e37c211f327379688f81b0dChris Lattner  // found.  Once a filename is found, all of the succeeding arguments are
81331de23705a719514e37c211f327379688f81b0dChris Lattner  // passed, unprocessed, to the ConsumeAfter option.
82cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  //
83cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  ConsumeAfter    = 0x05,
84cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
8540f44f1f58f823994b7f4ec4005887c3955fb1e7Chris Lattner  OccurrencesMask  = 0x07
86cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
87cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
88cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerenum ValueExpected {           // Is a value required for the option?
89b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  ValueOptional   = 0x08,      // The value can appear... or not
90cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  ValueRequired   = 0x10,      // The value is required to appear!
91cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  ValueDisallowed = 0x18,      // A value may not be specified (for flags)
9240f44f1f58f823994b7f4ec4005887c3955fb1e7Chris Lattner  ValueMask       = 0x18
93cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
94cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
95cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerenum OptionHidden {            // Control whether -help shows this option
96cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  NotHidden       = 0x20,      // Option included in --help & --help-hidden
97cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  Hidden          = 0x40,      // -help doesn't, but --help-hidden does
98cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  ReallyHidden    = 0x60,      // Neither --help nor --help-hidden show this arg
9940f44f1f58f823994b7f4ec4005887c3955fb1e7Chris Lattner  HiddenMask      = 0x60
100cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
101cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
102331de23705a719514e37c211f327379688f81b0dChris Lattner// Formatting flags - This controls special features that the option might have
103331de23705a719514e37c211f327379688f81b0dChris Lattner// that cause it to be parsed differently...
104331de23705a719514e37c211f327379688f81b0dChris Lattner//
105331de23705a719514e37c211f327379688f81b0dChris Lattner// Prefix - This option allows arguments that are otherwise unrecognized to be
106331de23705a719514e37c211f327379688f81b0dChris Lattner// matched by options that are a prefix of the actual value.  This is useful for
107331de23705a719514e37c211f327379688f81b0dChris Lattner// cases like a linker, where options are typically of the form '-lfoo' or
108331de23705a719514e37c211f327379688f81b0dChris Lattner// '-L../../include' where -l or -L are the actual flags.  When prefix is
109331de23705a719514e37c211f327379688f81b0dChris Lattner// enabled, and used, the value for the flag comes from the suffix of the
110331de23705a719514e37c211f327379688f81b0dChris Lattner// argument.
111331de23705a719514e37c211f327379688f81b0dChris Lattner//
112331de23705a719514e37c211f327379688f81b0dChris Lattner// Grouping - With this option enabled, multiple letter options are allowed to
113331de23705a719514e37c211f327379688f81b0dChris Lattner// bunch together with only a single hyphen for the whole group.  This allows
114331de23705a719514e37c211f327379688f81b0dChris Lattner// emulation of the behavior that ls uses for example: ls -la === ls -l -a
115331de23705a719514e37c211f327379688f81b0dChris Lattner//
116331de23705a719514e37c211f327379688f81b0dChris Lattner
117331de23705a719514e37c211f327379688f81b0dChris Lattnerenum FormattingFlags {
118331de23705a719514e37c211f327379688f81b0dChris Lattner  NormalFormatting = 0x000,     // Nothing special
119331de23705a719514e37c211f327379688f81b0dChris Lattner  Positional       = 0x080,     // Is a positional argument, no '-' required
120331de23705a719514e37c211f327379688f81b0dChris Lattner  Prefix           = 0x100,     // Can this option directly prefix its value?
121331de23705a719514e37c211f327379688f81b0dChris Lattner  Grouping         = 0x180,     // Can this option group with other options?
12240f44f1f58f823994b7f4ec4005887c3955fb1e7Chris Lattner  FormattingMask   = 0x180      // Union of the above flags.
123331de23705a719514e37c211f327379688f81b0dChris Lattner};
124331de23705a719514e37c211f327379688f81b0dChris Lattner
1251e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencerenum MiscFlags {               // Miscellaneous flags to adjust argument
1261e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  CommaSeparated     = 0x200,  // Should this cl::list split between commas?
1271e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  PositionalEatsArgs = 0x400,  // Should this positional cl::list eat -args?
128d57160d097d6cdb966e5c851215acbd2bf1aa236Anton Korobeynikov  Sink               = 0x800,  // Should this cl::list eat all unknown options?
129d57160d097d6cdb966e5c851215acbd2bf1aa236Anton Korobeynikov  MiscMask           = 0xE00   // Union of the above flags.
130b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner};
131b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner
132b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner
133cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
134cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
135cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner// Option Base class
136cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
137331de23705a719514e37c211f327379688f81b0dChris Lattnerclass alias;
138cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerclass Option {
139331de23705a719514e37c211f327379688f81b0dChris Lattner  friend class alias;
140cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
141dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  // handleOccurrences - Overriden by subclasses to handle the value passed into
142cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // an argument.  Should return true if there was an error processing the
143cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // argument and the program should exit.
144cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  //
14563b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  virtual bool handleOccurrence(unsigned pos, const char *ArgName,
1461e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                                const std::string &Arg) = 0;
147cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
148cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  virtual enum ValueExpected getValueExpectedFlagDefault() const {
14963b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    return ValueOptional;
150cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
151beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
152433fd76e51e9bd9a4933e2c1775a7410928112c8Chris Lattner  // Out of line virtual function to provide home for the class.
153433fd76e51e9bd9a4933e2c1775a7410928112c8Chris Lattner  virtual void anchor();
154beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1559878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  int NumOccurrences;     // The number of times specified
1569878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  int Flags;              // Flags for the argument
1579878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  unsigned Position;      // Position of last occurrence of the option
1589878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  Option *NextRegistered; // Singly linked list of registered options.
159cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
1609878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  const char *ArgStr;     // The argument string itself (ex: "help", "o")
1619878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  const char *HelpStr;    // The descriptive text message for --help
1629878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  const char *ValueStr;   // String describing what the value of this option is
163cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
164dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  inline enum NumOccurrences getNumOccurrencesFlag() const {
165f6143ef556ed01311d2043d38421302479f7866cChris Lattner    return static_cast<enum NumOccurrences>(Flags & OccurrencesMask);
166cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
167cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  inline enum ValueExpected getValueExpectedFlag() const {
168cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner    int VE = Flags & ValueMask;
1698b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner    return VE ? static_cast<enum ValueExpected>(VE)
1708b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner              : getValueExpectedFlagDefault();
171cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
172cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  inline enum OptionHidden getOptionHiddenFlag() const {
173f6143ef556ed01311d2043d38421302479f7866cChris Lattner    return static_cast<enum OptionHidden>(Flags & HiddenMask);
174cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
175331de23705a719514e37c211f327379688f81b0dChris Lattner  inline enum FormattingFlags getFormattingFlag() const {
176f6143ef556ed01311d2043d38421302479f7866cChris Lattner    return static_cast<enum FormattingFlags>(Flags & FormattingMask);
177331de23705a719514e37c211f327379688f81b0dChris Lattner  }
178b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  inline unsigned getMiscFlags() const {
179b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner    return Flags & MiscMask;
180b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  }
1811e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  inline unsigned getPosition() const { return Position; }
182331de23705a719514e37c211f327379688f81b0dChris Lattner
183331de23705a719514e37c211f327379688f81b0dChris Lattner  // hasArgStr - Return true if the argstr != ""
184331de23705a719514e37c211f327379688f81b0dChris Lattner  bool hasArgStr() const { return ArgStr[0] != 0; }
185331de23705a719514e37c211f327379688f81b0dChris Lattner
186331de23705a719514e37c211f327379688f81b0dChris Lattner  //-------------------------------------------------------------------------===
187331de23705a719514e37c211f327379688f81b0dChris Lattner  // Accessor functions set by OptionModifiers
188331de23705a719514e37c211f327379688f81b0dChris Lattner  //
189331de23705a719514e37c211f327379688f81b0dChris Lattner  void setArgStr(const char *S) { ArgStr = S; }
190331de23705a719514e37c211f327379688f81b0dChris Lattner  void setDescription(const char *S) { HelpStr = S; }
191331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValueStr(const char *S) { ValueStr = S; }
192331de23705a719514e37c211f327379688f81b0dChris Lattner
193331de23705a719514e37c211f327379688f81b0dChris Lattner  void setFlag(unsigned Flag, unsigned FlagMask) {
194f3799d6317e38a996dcea50143cbc15543d8f5c4Chris Lattner    Flags &= ~FlagMask;
195331de23705a719514e37c211f327379688f81b0dChris Lattner    Flags |= Flag;
196331de23705a719514e37c211f327379688f81b0dChris Lattner  }
197331de23705a719514e37c211f327379688f81b0dChris Lattner
198dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  void setNumOccurrencesFlag(enum NumOccurrences Val) {
199dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman    setFlag(Val, OccurrencesMask);
200331de23705a719514e37c211f327379688f81b0dChris Lattner  }
201331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); }
202331de23705a719514e37c211f327379688f81b0dChris Lattner  void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); }
203331de23705a719514e37c211f327379688f81b0dChris Lattner  void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); }
204b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  void setMiscFlag(enum MiscFlags M) { setFlag(M, M); }
2051e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  void setPosition(unsigned pos) { Position = pos; }
206cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerprotected:
20727e9d457d4047cf0051e17d9ca39740875d11440Dan Gohman  explicit Option(unsigned DefaultFlags)
208f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : NumOccurrences(0), Flags(DefaultFlags | NormalFormatting), Position(0),
2099878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner      NextRegistered(0), ArgStr(""), HelpStr(""), ValueStr("") {
210f6143ef556ed01311d2043d38421302479f7866cChris Lattner    assert(getNumOccurrencesFlag() != 0 &&
211f6143ef556ed01311d2043d38421302479f7866cChris Lattner           getOptionHiddenFlag() != 0 && "Not all default flags specified!");
212f6143ef556ed01311d2043d38421302479f7866cChris Lattner  }
213cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
214cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
2159878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  // addArgument - Register this argument with the commandline system.
216331de23705a719514e37c211f327379688f81b0dChris Lattner  //
2179878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  void addArgument();
218beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
2199878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  Option *getNextRegisteredOption() const { return NextRegistered; }
220331de23705a719514e37c211f327379688f81b0dChris Lattner
221cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // Return the width of the option tag for printing...
22234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const = 0;
223cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
22463b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  // printOptionInfo - Print out information about this option.  The
225cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // to-be-maintained width is specified.
226cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  //
22734cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const = 0;
228cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
22913d57320bd212483463d4f8992d5787b29eda5dfBill Wendling  virtual void getExtraOptionNames(std::vector<const char*> &) {}
230beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
231dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  // addOccurrence - Wrapper around handleOccurrence that enforces Flags
232cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  //
23363b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  bool addOccurrence(unsigned pos, const char *ArgName,
2341e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                     const std::string &Value);
235cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
236cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // Prints option name followed by message.  Always returns true.
237697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  bool error(std::string Message, const char *ArgName = 0);
238cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
239cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
240dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  inline int getNumOccurrences() const { return NumOccurrences; }
241cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  virtual ~Option() {}
242cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
243cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
244cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
245cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
246331de23705a719514e37c211f327379688f81b0dChris Lattner// Command line option modifiers that can be used to modify the behavior of
247331de23705a719514e37c211f327379688f81b0dChris Lattner// command line option parsers...
248cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
249331de23705a719514e37c211f327379688f81b0dChris Lattner
250331de23705a719514e37c211f327379688f81b0dChris Lattner// desc - Modifier to set the description shown in the --help output...
251331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct desc {
252331de23705a719514e37c211f327379688f81b0dChris Lattner  const char *Desc;
253331de23705a719514e37c211f327379688f81b0dChris Lattner  desc(const char *Str) : Desc(Str) {}
254331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Option &O) const { O.setDescription(Desc); }
255331de23705a719514e37c211f327379688f81b0dChris Lattner};
256331de23705a719514e37c211f327379688f81b0dChris Lattner
257331de23705a719514e37c211f327379688f81b0dChris Lattner// value_desc - Modifier to set the value description shown in the --help
258331de23705a719514e37c211f327379688f81b0dChris Lattner// output...
259331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct value_desc {
260331de23705a719514e37c211f327379688f81b0dChris Lattner  const char *Desc;
261331de23705a719514e37c211f327379688f81b0dChris Lattner  value_desc(const char *Str) : Desc(Str) {}
262331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Option &O) const { O.setValueStr(Desc); }
263331de23705a719514e37c211f327379688f81b0dChris Lattner};
264331de23705a719514e37c211f327379688f81b0dChris Lattner
265331de23705a719514e37c211f327379688f81b0dChris Lattner// init - Specify a default (initial) value for the command line argument, if
266331de23705a719514e37c211f327379688f81b0dChris Lattner// the default constructor for the argument type does not give you what you
267331de23705a719514e37c211f327379688f81b0dChris Lattner// want.  This is only valid on "opt" arguments, not on "list" arguments.
268331de23705a719514e37c211f327379688f81b0dChris Lattner//
269331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Ty>
270331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct initializer {
271331de23705a719514e37c211f327379688f81b0dChris Lattner  const Ty &Init;
272331de23705a719514e37c211f327379688f81b0dChris Lattner  initializer(const Ty &Val) : Init(Val) {}
273331de23705a719514e37c211f327379688f81b0dChris Lattner
274331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
275331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Opt &O) const { O.setInitialValue(Init); }
276cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
277cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
278331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Ty>
279331de23705a719514e37c211f327379688f81b0dChris Lattnerinitializer<Ty> init(const Ty &Val) {
280331de23705a719514e37c211f327379688f81b0dChris Lattner  return initializer<Ty>(Val);
281331de23705a719514e37c211f327379688f81b0dChris Lattner}
282331de23705a719514e37c211f327379688f81b0dChris Lattner
283331de23705a719514e37c211f327379688f81b0dChris Lattner
284331de23705a719514e37c211f327379688f81b0dChris Lattner// location - Allow the user to specify which external variable they want to
285331de23705a719514e37c211f327379688f81b0dChris Lattner// store the results of the command line argument processing into, if they don't
286331de23705a719514e37c211f327379688f81b0dChris Lattner// want to store it in the option itself.
287331de23705a719514e37c211f327379688f81b0dChris Lattner//
288331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Ty>
289331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct LocationClass {
290331de23705a719514e37c211f327379688f81b0dChris Lattner  Ty &Loc;
291331de23705a719514e37c211f327379688f81b0dChris Lattner  LocationClass(Ty &L) : Loc(L) {}
292331de23705a719514e37c211f327379688f81b0dChris Lattner
293331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
294331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Opt &O) const { O.setLocation(O, Loc); }
295331de23705a719514e37c211f327379688f81b0dChris Lattner};
296331de23705a719514e37c211f327379688f81b0dChris Lattner
297331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Ty>
298331de23705a719514e37c211f327379688f81b0dChris LattnerLocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
299331de23705a719514e37c211f327379688f81b0dChris Lattner
300331de23705a719514e37c211f327379688f81b0dChris Lattner
301cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
302331de23705a719514e37c211f327379688f81b0dChris Lattner// Enum valued command line option
303cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
304f8063f91227712cc726fca385dd8b88bf6400c84Reid Spencer#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC
305f8063f91227712cc726fca385dd8b88bf6400c84Reid Spencer#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC
306f8063f91227712cc726fca385dd8b88bf6400c84Reid Spencer#define clEnumValEnd (reinterpret_cast<void*>(0))
307331de23705a719514e37c211f327379688f81b0dChris Lattner
308331de23705a719514e37c211f327379688f81b0dChris Lattner// values - For custom data types, allow specifying a group of values together
309331de23705a719514e37c211f327379688f81b0dChris Lattner// as the values that go into the mapping that the option handler uses.  Note
310331de23705a719514e37c211f327379688f81b0dChris Lattner// that the values list must always have a 0 at the end of the list to indicate
311331de23705a719514e37c211f327379688f81b0dChris Lattner// that the list has ended.
312331de23705a719514e37c211f327379688f81b0dChris Lattner//
313331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
314331de23705a719514e37c211f327379688f81b0dChris Lattnerclass ValuesClass {
315331de23705a719514e37c211f327379688f81b0dChris Lattner  // Use a vector instead of a map, because the lists should be short,
316331de23705a719514e37c211f327379688f81b0dChris Lattner  // the overhead is less, and most importantly, it keeps them in the order
317331de23705a719514e37c211f327379688f81b0dChris Lattner  // inserted so we can print our option out nicely.
3183b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  SmallVector<std::pair<const char *, std::pair<int, const char *> >,4> Values;
319331de23705a719514e37c211f327379688f81b0dChris Lattner  void processValues(va_list Vals);
320cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
32163b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  ValuesClass(const char *EnumName, DataType Val, const char *Desc,
322331de23705a719514e37c211f327379688f81b0dChris Lattner              va_list ValueArgs) {
323331de23705a719514e37c211f327379688f81b0dChris Lattner    // Insert the first value, which is required.
324331de23705a719514e37c211f327379688f81b0dChris Lattner    Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc)));
325331de23705a719514e37c211f327379688f81b0dChris Lattner
326331de23705a719514e37c211f327379688f81b0dChris Lattner    // Process the varargs portion of the values...
32713d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    while (const char *enumName = va_arg(ValueArgs, const char *)) {
3288b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner      DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int));
329331de23705a719514e37c211f327379688f81b0dChris Lattner      const char *EnumDesc = va_arg(ValueArgs, const char *);
33013d57320bd212483463d4f8992d5787b29eda5dfBill Wendling      Values.push_back(std::make_pair(enumName,      // Add value to value map
331331de23705a719514e37c211f327379688f81b0dChris Lattner                                      std::make_pair(EnumVal, EnumDesc)));
332331de23705a719514e37c211f327379688f81b0dChris Lattner    }
33371fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner  }
33471fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner
335331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
336331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Opt &O) const {
33734cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng    for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
33834cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng         i != e; ++i)
339331de23705a719514e37c211f327379688f81b0dChris Lattner      O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
340331de23705a719514e37c211f327379688f81b0dChris Lattner                                     Values[i].second.second);
34171fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner  }
342cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
343cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
344331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
345beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail GlushenkovValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
346a542b4c133de5da974632e9623ee4b426ebb3353Chris Lattner                                           const char *Desc, ...) {
347331de23705a719514e37c211f327379688f81b0dChris Lattner    va_list ValueArgs;
348331de23705a719514e37c211f327379688f81b0dChris Lattner    va_start(ValueArgs, Desc);
349331de23705a719514e37c211f327379688f81b0dChris Lattner    ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs);
350331de23705a719514e37c211f327379688f81b0dChris Lattner    va_end(ValueArgs);
351331de23705a719514e37c211f327379688f81b0dChris Lattner    return Vals;
352331de23705a719514e37c211f327379688f81b0dChris Lattner}
353cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
354cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
355cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
356331de23705a719514e37c211f327379688f81b0dChris Lattner// parser class - Parameterizable parser for different data types.  By default,
357331de23705a719514e37c211f327379688f81b0dChris Lattner// known data types (string, int, bool) have specialized parsers, that do what
358331de23705a719514e37c211f327379688f81b0dChris Lattner// you would expect.  The default parser, used for data types that are not
359331de23705a719514e37c211f327379688f81b0dChris Lattner// built-in, uses a mapping table to map specific options to values, which is
360331de23705a719514e37c211f327379688f81b0dChris Lattner// used, among other things, to handle enum types.
361331de23705a719514e37c211f327379688f81b0dChris Lattner
362331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
363331de23705a719514e37c211f327379688f81b0dChris Lattner// generic_parser_base - This class holds all the non-generic code that we do
364331de23705a719514e37c211f327379688f81b0dChris Lattner// not need replicated for every instance of the generic parser.  This also
365331de23705a719514e37c211f327379688f81b0dChris Lattner// allows us to put stuff into CommandLine.cpp
366cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
367331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct generic_parser_base {
368331de23705a719514e37c211f327379688f81b0dChris Lattner  virtual ~generic_parser_base() {}  // Base class should have virtual-dtor
369331de23705a719514e37c211f327379688f81b0dChris Lattner
370331de23705a719514e37c211f327379688f81b0dChris Lattner  // getNumOptions - Virtual function implemented by generic subclass to
371331de23705a719514e37c211f327379688f81b0dChris Lattner  // indicate how many entries are in Values.
372331de23705a719514e37c211f327379688f81b0dChris Lattner  //
373331de23705a719514e37c211f327379688f81b0dChris Lattner  virtual unsigned getNumOptions() const = 0;
374331de23705a719514e37c211f327379688f81b0dChris Lattner
375331de23705a719514e37c211f327379688f81b0dChris Lattner  // getOption - Return option name N.
376331de23705a719514e37c211f327379688f81b0dChris Lattner  virtual const char *getOption(unsigned N) const = 0;
37763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
378331de23705a719514e37c211f327379688f81b0dChris Lattner  // getDescription - Return description N
379331de23705a719514e37c211f327379688f81b0dChris Lattner  virtual const char *getDescription(unsigned N) const = 0;
380331de23705a719514e37c211f327379688f81b0dChris Lattner
381331de23705a719514e37c211f327379688f81b0dChris Lattner  // Return the width of the option tag for printing...
38234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth(const Option &O) const;
383331de23705a719514e37c211f327379688f81b0dChris Lattner
38463b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  // printOptionInfo - Print out information about this option.  The
385331de23705a719514e37c211f327379688f81b0dChris Lattner  // to-be-maintained width is specified.
386331de23705a719514e37c211f327379688f81b0dChris Lattner  //
38734cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const;
388331de23705a719514e37c211f327379688f81b0dChris Lattner
389331de23705a719514e37c211f327379688f81b0dChris Lattner  void initialize(Option &O) {
390331de23705a719514e37c211f327379688f81b0dChris Lattner    // All of the modifiers for the option have been processed by now, so the
391331de23705a719514e37c211f327379688f81b0dChris Lattner    // argstr field should be stable, copy it down now.
392331de23705a719514e37c211f327379688f81b0dChris Lattner    //
393331de23705a719514e37c211f327379688f81b0dChris Lattner    hasArgStr = O.hasArgStr();
3949878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  }
395beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
3969878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  void getExtraOptionNames(std::vector<const char*> &OptionNames) {
397331de23705a719514e37c211f327379688f81b0dChris Lattner    // If there has been no argstr specified, that means that we need to add an
398331de23705a719514e37c211f327379688f81b0dChris Lattner    // argument for every possible option.  This ensures that our options are
399331de23705a719514e37c211f327379688f81b0dChris Lattner    // vectored to us.
400331de23705a719514e37c211f327379688f81b0dChris Lattner    if (!hasArgStr)
401331de23705a719514e37c211f327379688f81b0dChris Lattner      for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
4029878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner        OptionNames.push_back(getOption(i));
403cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
404cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
4059878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner
406331de23705a719514e37c211f327379688f81b0dChris Lattner  enum ValueExpected getValueExpectedFlagDefault() const {
407331de23705a719514e37c211f327379688f81b0dChris Lattner    // If there is an ArgStr specified, then we are of the form:
408331de23705a719514e37c211f327379688f81b0dChris Lattner    //
409331de23705a719514e37c211f327379688f81b0dChris Lattner    //    -opt=O2   or   -opt O2  or  -optO2
410331de23705a719514e37c211f327379688f81b0dChris Lattner    //
411331de23705a719514e37c211f327379688f81b0dChris Lattner    // In which case, the value is required.  Otherwise if an arg str has not
412331de23705a719514e37c211f327379688f81b0dChris Lattner    // been specified, we are of the form:
413331de23705a719514e37c211f327379688f81b0dChris Lattner    //
414bc0e998c497446f5448425b3cbd7f8f19a458764Misha Brukman    //    -O2 or O2 or -la (where -l and -a are separate options)
415331de23705a719514e37c211f327379688f81b0dChris Lattner    //
416331de23705a719514e37c211f327379688f81b0dChris Lattner    // If this is the case, we cannot allow a value.
417331de23705a719514e37c211f327379688f81b0dChris Lattner    //
418331de23705a719514e37c211f327379688f81b0dChris Lattner    if (hasArgStr)
419331de23705a719514e37c211f327379688f81b0dChris Lattner      return ValueRequired;
420331de23705a719514e37c211f327379688f81b0dChris Lattner    else
421331de23705a719514e37c211f327379688f81b0dChris Lattner      return ValueDisallowed;
422331de23705a719514e37c211f327379688f81b0dChris Lattner  }
423cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
424af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  // findOption - Return the option number corresponding to the specified
425af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  // argument string.  If the option is not found, getNumOptions() is returned.
426af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  //
427af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  unsigned findOption(const char *Name);
428af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner
429331de23705a719514e37c211f327379688f81b0dChris Lattnerprotected:
430331de23705a719514e37c211f327379688f81b0dChris Lattner  bool hasArgStr;
431331de23705a719514e37c211f327379688f81b0dChris Lattner};
432331de23705a719514e37c211f327379688f81b0dChris Lattner
433331de23705a719514e37c211f327379688f81b0dChris Lattner// Default parser implementation - This implementation depends on having a
434331de23705a719514e37c211f327379688f81b0dChris Lattner// mapping of recognized options to values of some sort.  In addition to this,
435331de23705a719514e37c211f327379688f81b0dChris Lattner// each entry in the mapping also tracks a help message that is printed with the
436331de23705a719514e37c211f327379688f81b0dChris Lattner// command line option for --help.  Because this is a simple mapping parser, the
437331de23705a719514e37c211f327379688f81b0dChris Lattner// data type can be any unsupported type.
438cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
439331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate <class DataType>
440331de23705a719514e37c211f327379688f81b0dChris Lattnerclass parser : public generic_parser_base {
441af7e82184d7d77e426056c7c233e860baeebe80fChris Lattnerprotected:
4423b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  SmallVector<std::pair<const char *,
4433b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner                        std::pair<DataType, const char *> >, 8> Values;
444af7e82184d7d77e426056c7c233e860baeebe80fChris Lattnerpublic:
445d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  typedef DataType parser_data_type;
446331de23705a719514e37c211f327379688f81b0dChris Lattner
447331de23705a719514e37c211f327379688f81b0dChris Lattner  // Implement virtual functions needed by generic_parser_base
448f8063f91227712cc726fca385dd8b88bf6400c84Reid Spencer  unsigned getNumOptions() const { return unsigned(Values.size()); }
449331de23705a719514e37c211f327379688f81b0dChris Lattner  const char *getOption(unsigned N) const { return Values[N].first; }
450331de23705a719514e37c211f327379688f81b0dChris Lattner  const char *getDescription(unsigned N) const {
451331de23705a719514e37c211f327379688f81b0dChris Lattner    return Values[N].second.second;
452cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
453331de23705a719514e37c211f327379688f81b0dChris Lattner
454d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // parse - Return true on error.
45563b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  bool parse(Option &O, const char *ArgName, const std::string &Arg,
456d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner             DataType &V) {
4577f4dd472e35569efefbeffef096c490075e3e824Chris Lattner    std::string ArgVal;
458331de23705a719514e37c211f327379688f81b0dChris Lattner    if (hasArgStr)
459331de23705a719514e37c211f327379688f81b0dChris Lattner      ArgVal = Arg;
460331de23705a719514e37c211f327379688f81b0dChris Lattner    else
461331de23705a719514e37c211f327379688f81b0dChris Lattner      ArgVal = ArgName;
462331de23705a719514e37c211f327379688f81b0dChris Lattner
46334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng    for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
46434cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng         i != e; ++i)
465331de23705a719514e37c211f327379688f81b0dChris Lattner      if (ArgVal == Values[i].first) {
466d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner        V = Values[i].second.first;
467331de23705a719514e37c211f327379688f81b0dChris Lattner        return false;
468331de23705a719514e37c211f327379688f81b0dChris Lattner      }
469331de23705a719514e37c211f327379688f81b0dChris Lattner
470331de23705a719514e37c211f327379688f81b0dChris Lattner    return O.error(": Cannot find option named '" + ArgVal + "'!");
471331de23705a719514e37c211f327379688f81b0dChris Lattner  }
472cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
4733b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  /// addLiteralOption - Add an entry to the mapping table.
4743b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  ///
475331de23705a719514e37c211f327379688f81b0dChris Lattner  template <class DT>
476331de23705a719514e37c211f327379688f81b0dChris Lattner  void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) {
477af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner    assert(findOption(Name) == Values.size() && "Option already exists!");
4788b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner    Values.push_back(std::make_pair(Name,
4798b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner                             std::make_pair(static_cast<DataType>(V),HelpStr)));
48069d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattner    MarkOptionsChanged();
481cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
482af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner
4833b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  /// removeLiteralOption - Remove the specified option.
4843b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  ///
485af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  void removeLiteralOption(const char *Name) {
486af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner    unsigned N = findOption(Name);
487af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner    assert(N != Values.size() && "Option not found!");
488af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner    Values.erase(Values.begin()+N);
489af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  }
490cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
491cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
492331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
493d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// basic_parser - Super class of parsers to provide boilerplate code
494cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
495d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnerstruct basic_parser_impl {  // non-template implementation of basic_parser<t>
496d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual ~basic_parser_impl() {}
497331de23705a719514e37c211f327379688f81b0dChris Lattner
498331de23705a719514e37c211f327379688f81b0dChris Lattner  enum ValueExpected getValueExpectedFlagDefault() const {
499d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    return ValueRequired;
500cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
50163b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
50213d57320bd212483463d4f8992d5787b29eda5dfBill Wendling  void getExtraOptionNames(std::vector<const char*> &) {}
5039878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner
50413d57320bd212483463d4f8992d5787b29eda5dfBill Wendling  void initialize(Option &) {}
50563b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
506331de23705a719514e37c211f327379688f81b0dChris Lattner  // Return the width of the option tag for printing...
50734cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  size_t getOptionWidth(const Option &O) const;
50863b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
509d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // printOptionInfo - Print out information about this option.  The
510331de23705a719514e37c211f327379688f81b0dChris Lattner  // to-be-maintained width is specified.
511331de23705a719514e37c211f327379688f81b0dChris Lattner  //
51234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  void printOptionInfo(const Option &O, size_t GlobalWidth) const;
513d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner
514d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
515d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "value"; }
5167422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
5177422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
5187422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
519d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner};
520d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner
521d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// basic_parser - The real basic parser is just a template wrapper that provides
522d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// a typedef for the provided data type.
523d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//
524d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnertemplate<class DataType>
525d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnerstruct basic_parser : public basic_parser_impl {
526d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  typedef DataType parser_data_type;
527cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
528cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
529331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
530d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// parser<bool>
531cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
532331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<>
5331fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<bool> : public basic_parser<bool> {
5341fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
535331de23705a719514e37c211f327379688f81b0dChris Lattner  // parse - Return true on error.
536d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
537cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
538331de23705a719514e37c211f327379688f81b0dChris Lattner  enum ValueExpected getValueExpectedFlagDefault() const {
53963b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    return ValueOptional;
540331de23705a719514e37c211f327379688f81b0dChris Lattner  }
541331de23705a719514e37c211f327379688f81b0dChris Lattner
5427422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // getValueName - Do not print =<value> at all.
543d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return 0; }
544beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
5457422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
5467422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
547331de23705a719514e37c211f327379688f81b0dChris Lattner};
548cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
5497422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
5507422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
55181da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen//--------------------------------------------------
55281da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen// parser<boolOrDefault>
55381da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesenenum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
55481da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesentemplate<>
55581da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesenclass parser<boolOrDefault> : public basic_parser<boolOrDefault> {
55681da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesenpublic:
55781da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  // parse - Return true on error.
558beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov  bool parse(Option &O, const char *ArgName, const std::string &Arg,
55981da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen             boolOrDefault &Val);
56081da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen
56181da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  enum ValueExpected getValueExpectedFlagDefault() const {
56281da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen    return ValueOptional;
56381da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  }
56481da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen
56581da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  // getValueName - Do not print =<value> at all.
56681da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  virtual const char *getValueName() const { return 0; }
567beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
56881da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  // An out-of-line virtual method to provide a 'home' for this class.
56981da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  virtual void anchor();
57081da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen};
57181da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen
57281da02b553b86868637f27b89c6e919c31ed5b51Dale JohannesenEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
573cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
574331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
575d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// parser<int>
576331de23705a719514e37c211f327379688f81b0dChris Lattner//
577331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<>
5781fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<int> : public basic_parser<int> {
5791fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
580331de23705a719514e37c211f327379688f81b0dChris Lattner  // parse - Return true on error.
581d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  bool parse(Option &O, const char *ArgName, const std::string &Arg, int &Val);
582cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
583d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
584d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "int"; }
5857422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
5867422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
5877422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
588d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner};
589cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
5907422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
5917422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
592cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
593d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//--------------------------------------------------
594d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner// parser<unsigned>
595d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner//
596d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattnertemplate<>
5971fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<unsigned> : public basic_parser<unsigned> {
5981fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
599d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner  // parse - Return true on error.
6001e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  bool parse(Option &O, const char *AN, const std::string &Arg, unsigned &Val);
601d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner
602d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner  // getValueName - Overload in subclass to provide a better default value.
603d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner  virtual const char *getValueName() const { return "uint"; }
6047422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
6057422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6067422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
607d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner};
608d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner
6097422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
610d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner
611d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner//--------------------------------------------------
612d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// parser<double>
613d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//
614d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnertemplate<>
6151fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<double> : public basic_parser<double> {
6161fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
617d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // parse - Return true on error.
618d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  bool parse(Option &O, const char *AN, const std::string &Arg, double &Val);
619cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
620d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
621d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "number"; }
6227422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
6237422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6247422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
625cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
626cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
6277422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
628331de23705a719514e37c211f327379688f81b0dChris Lattner
629d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//--------------------------------------------------
630d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// parser<float>
631d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//
632d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnertemplate<>
6331fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<float> : public basic_parser<float> {
6341fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
635d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // parse - Return true on error.
636d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  bool parse(Option &O, const char *AN, const std::string &Arg, float &Val);
637d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner
638d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
639d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "number"; }
6407422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
6417422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6427422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
643d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner};
644331de23705a719514e37c211f327379688f81b0dChris Lattner
6457422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
646331de23705a719514e37c211f327379688f81b0dChris Lattner
647331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
6487f4dd472e35569efefbeffef096c490075e3e824Chris Lattner// parser<std::string>
649331de23705a719514e37c211f327379688f81b0dChris Lattner//
650331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<>
6511fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<std::string> : public basic_parser<std::string> {
6521fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
653331de23705a719514e37c211f327379688f81b0dChris Lattner  // parse - Return true on error.
65413d57320bd212483463d4f8992d5787b29eda5dfBill Wendling  bool parse(Option &, const char *, const std::string &Arg,
655d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner             std::string &Value) {
656d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    Value = Arg;
657331de23705a719514e37c211f327379688f81b0dChris Lattner    return false;
658331de23705a719514e37c211f327379688f81b0dChris Lattner  }
659331de23705a719514e37c211f327379688f81b0dChris Lattner
660d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
661d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "string"; }
6627422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
6637422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6647422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
665331de23705a719514e37c211f327379688f81b0dChris Lattner};
666331de23705a719514e37c211f327379688f81b0dChris Lattner
6677422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
6687422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
669331de23705a719514e37c211f327379688f81b0dChris Lattner//===----------------------------------------------------------------------===//
670331de23705a719514e37c211f327379688f81b0dChris Lattner// applicator class - This class is used because we must use partial
671331de23705a719514e37c211f327379688f81b0dChris Lattner// specialization to handle literal string arguments specially (const char* does
672331de23705a719514e37c211f327379688f81b0dChris Lattner// not correctly respond to the apply method).  Because the syntax to use this
673331de23705a719514e37c211f327379688f81b0dChris Lattner// is a pain, we have the 'apply' method below to handle the nastiness...
674331de23705a719514e37c211f327379688f81b0dChris Lattner//
675331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Mod> struct applicator {
676331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
677331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(const Mod &M, Opt &O) { M.apply(O); }
678331de23705a719514e37c211f327379688f81b0dChris Lattner};
679331de23705a719514e37c211f327379688f81b0dChris Lattner
680331de23705a719514e37c211f327379688f81b0dChris Lattner// Handle const char* as a special case...
681331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<unsigned n> struct applicator<char[n]> {
682331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
683331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
684331de23705a719514e37c211f327379688f81b0dChris Lattner};
6854042332d4a8ba8e4d2b3a6d87a3af81fc73a0f98Chris Lattnertemplate<unsigned n> struct applicator<const char[n]> {
6864042332d4a8ba8e4d2b3a6d87a3af81fc73a0f98Chris Lattner  template<class Opt>
6874042332d4a8ba8e4d2b3a6d87a3af81fc73a0f98Chris Lattner  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
6884042332d4a8ba8e4d2b3a6d87a3af81fc73a0f98Chris Lattner};
689331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<> struct applicator<const char*> {
690331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
691331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
692331de23705a719514e37c211f327379688f81b0dChris Lattner};
693331de23705a719514e37c211f327379688f81b0dChris Lattner
694dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukmantemplate<> struct applicator<NumOccurrences> {
695dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  static void opt(NumOccurrences NO, Option &O) { O.setNumOccurrencesFlag(NO); }
696331de23705a719514e37c211f327379688f81b0dChris Lattner};
697331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<> struct applicator<ValueExpected> {
698331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); }
699331de23705a719514e37c211f327379688f81b0dChris Lattner};
700331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<> struct applicator<OptionHidden> {
701331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); }
702331de23705a719514e37c211f327379688f81b0dChris Lattner};
703331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<> struct applicator<FormattingFlags> {
704331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); }
705331de23705a719514e37c211f327379688f81b0dChris Lattner};
706b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattnertemplate<> struct applicator<MiscFlags> {
707b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); }
708b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner};
709331de23705a719514e37c211f327379688f81b0dChris Lattner
710331de23705a719514e37c211f327379688f81b0dChris Lattner// apply method - Apply a modifier to an option in a type safe way.
711331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Mod, class Opt>
712331de23705a719514e37c211f327379688f81b0dChris Lattnervoid apply(const Mod &M, Opt *O) {
713331de23705a719514e37c211f327379688f81b0dChris Lattner  applicator<Mod>::opt(M, *O);
714331de23705a719514e37c211f327379688f81b0dChris Lattner}
715331de23705a719514e37c211f327379688f81b0dChris Lattner
716331de23705a719514e37c211f327379688f81b0dChris Lattner
717331de23705a719514e37c211f327379688f81b0dChris Lattner//===----------------------------------------------------------------------===//
718331de23705a719514e37c211f327379688f81b0dChris Lattner// opt_storage class
719331de23705a719514e37c211f327379688f81b0dChris Lattner
720331de23705a719514e37c211f327379688f81b0dChris Lattner// Default storage class definition: external storage.  This implementation
721331de23705a719514e37c211f327379688f81b0dChris Lattner// assumes the user will specify a variable to store the data into with the
722331de23705a719514e37c211f327379688f81b0dChris Lattner// cl::location(x) modifier.
723331de23705a719514e37c211f327379688f81b0dChris Lattner//
724331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType, bool ExternalStorage, bool isClass>
725331de23705a719514e37c211f327379688f81b0dChris Lattnerclass opt_storage {
726331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType *Location;   // Where to store the object...
727331de23705a719514e37c211f327379688f81b0dChris Lattner
728331de23705a719514e37c211f327379688f81b0dChris Lattner  void check() {
729331de23705a719514e37c211f327379688f81b0dChris Lattner    assert(Location != 0 && "cl::location(...) not specified for a command "
7303c7eb1f2ea231c046367023576311fbc4b1270e3Chris Lattner           "line option with external storage, "
7313c7eb1f2ea231c046367023576311fbc4b1270e3Chris Lattner           "or cl::init specified before cl::location()!!");
732331de23705a719514e37c211f327379688f81b0dChris Lattner  }
733cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
734331de23705a719514e37c211f327379688f81b0dChris Lattner  opt_storage() : Location(0) {}
735331de23705a719514e37c211f327379688f81b0dChris Lattner
736331de23705a719514e37c211f327379688f81b0dChris Lattner  bool setLocation(Option &O, DataType &L) {
737331de23705a719514e37c211f327379688f81b0dChris Lattner    if (Location)
738331de23705a719514e37c211f327379688f81b0dChris Lattner      return O.error(": cl::location(x) specified more than once!");
739331de23705a719514e37c211f327379688f81b0dChris Lattner    Location = &L;
740331de23705a719514e37c211f327379688f81b0dChris Lattner    return false;
741cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
742cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
743331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
744331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValue(const T &V) {
745331de23705a719514e37c211f327379688f81b0dChris Lattner    check();
746331de23705a719514e37c211f327379688f81b0dChris Lattner    *Location = V;
74771fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner  }
74871fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner
749331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType &getValue() { check(); return *Location; }
750331de23705a719514e37c211f327379688f81b0dChris Lattner  const DataType &getValue() const { check(); return *Location; }
751331de23705a719514e37c211f327379688f81b0dChris Lattner};
752331de23705a719514e37c211f327379688f81b0dChris Lattner
753331de23705a719514e37c211f327379688f81b0dChris Lattner
754331de23705a719514e37c211f327379688f81b0dChris Lattner// Define how to hold a class type object, such as a string.  Since we can
755331de23705a719514e37c211f327379688f81b0dChris Lattner// inherit from a class, we do so.  This makes us exactly compatible with the
756331de23705a719514e37c211f327379688f81b0dChris Lattner// object in all cases that it is used.
757331de23705a719514e37c211f327379688f81b0dChris Lattner//
758331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
7591fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass opt_storage<DataType,false,true> : public DataType {
7601fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
761331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
762331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValue(const T &V) { DataType::operator=(V); }
763331de23705a719514e37c211f327379688f81b0dChris Lattner
764331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType &getValue() { return *this; }
765331de23705a719514e37c211f327379688f81b0dChris Lattner  const DataType &getValue() const { return *this; }
766331de23705a719514e37c211f327379688f81b0dChris Lattner};
767331de23705a719514e37c211f327379688f81b0dChris Lattner
768331de23705a719514e37c211f327379688f81b0dChris Lattner// Define a partial specialization to handle things we cannot inherit from.  In
769331de23705a719514e37c211f327379688f81b0dChris Lattner// this case, we store an instance through containment, and overload operators
770331de23705a719514e37c211f327379688f81b0dChris Lattner// to get at the value.
771331de23705a719514e37c211f327379688f81b0dChris Lattner//
772331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
7731fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass opt_storage<DataType, false, false> {
7741fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
775331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType Value;
776331de23705a719514e37c211f327379688f81b0dChris Lattner
777331de23705a719514e37c211f327379688f81b0dChris Lattner  // Make sure we initialize the value with the default constructor for the
778331de23705a719514e37c211f327379688f81b0dChris Lattner  // type.
779331de23705a719514e37c211f327379688f81b0dChris Lattner  opt_storage() : Value(DataType()) {}
780331de23705a719514e37c211f327379688f81b0dChris Lattner
781331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
782331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValue(const T &V) { Value = V; }
783331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType &getValue() { return Value; }
784331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType getValue() const { return Value; }
7856a4dd24a995072c9c6f1ae45f19f94010d8389fbChris Lattner
7866a4dd24a995072c9c6f1ae45f19f94010d8389fbChris Lattner  // If the datatype is a pointer, support -> on it.
7876a4dd24a995072c9c6f1ae45f19f94010d8389fbChris Lattner  DataType operator->() const { return Value; }
788cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
789cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
790cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
791cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
792331de23705a719514e37c211f327379688f81b0dChris Lattner// opt - A scalar command line option.
793cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
794331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate <class DataType, bool ExternalStorage = false,
795331de23705a719514e37c211f327379688f81b0dChris Lattner          class ParserClass = parser<DataType> >
79663b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukmanclass opt : public Option,
797331de23705a719514e37c211f327379688f81b0dChris Lattner            public opt_storage<DataType, ExternalStorage,
7987b3d73b7ecbecf423c3766e596b6086767444363Chris Lattner                               is_class<DataType>::value> {
799331de23705a719514e37c211f327379688f81b0dChris Lattner  ParserClass Parser;
800331de23705a719514e37c211f327379688f81b0dChris Lattner
80163b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  virtual bool handleOccurrence(unsigned pos, const char *ArgName,
8021e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                                const std::string &Arg) {
8039eb59ec548b861d6ede05b4e6dc22aabf645e665Jeff Cohen    typename ParserClass::parser_data_type Val =
804e6ad5ea996673f76b62e495d268c8bf7c9b0d205Chris Lattner       typename ParserClass::parser_data_type();
805d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    if (Parser.parse(*this, ArgName, Arg, Val))
806d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner      return true;                            // Parse error!
807d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    setValue(Val);
8081e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    setPosition(pos);
809d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    return false;
810331de23705a719514e37c211f327379688f81b0dChris Lattner  }
811331de23705a719514e37c211f327379688f81b0dChris Lattner
812cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  virtual enum ValueExpected getValueExpectedFlagDefault() const {
813331de23705a719514e37c211f327379688f81b0dChris Lattner    return Parser.getValueExpectedFlagDefault();
814cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
8159878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
8169878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    return Parser.getExtraOptionNames(OptionNames);
8179878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  }
818cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
819331de23705a719514e37c211f327379688f81b0dChris Lattner  // Forward printing stuff to the parser...
82034cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
82134cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const {
822331de23705a719514e37c211f327379688f81b0dChris Lattner    Parser.printOptionInfo(*this, GlobalWidth);
823331de23705a719514e37c211f327379688f81b0dChris Lattner  }
824cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
825331de23705a719514e37c211f327379688f81b0dChris Lattner  void done() {
8269878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    addArgument();
827331de23705a719514e37c211f327379688f81b0dChris Lattner    Parser.initialize(*this);
828331de23705a719514e37c211f327379688f81b0dChris Lattner  }
829331de23705a719514e37c211f327379688f81b0dChris Lattnerpublic:
830331de23705a719514e37c211f327379688f81b0dChris Lattner  // setInitialValue - Used by the cl::init modifier...
83131a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner  void setInitialValue(const DataType &V) { this->setValue(V); }
832331de23705a719514e37c211f327379688f81b0dChris Lattner
833331de23705a719514e37c211f327379688f81b0dChris Lattner  ParserClass &getParser() { return Parser; }
834331de23705a719514e37c211f327379688f81b0dChris Lattner
83531a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner  operator DataType() const { return this->getValue(); }
836331de23705a719514e37c211f327379688f81b0dChris Lattner
837331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
83831a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner  DataType &operator=(const T &Val) {
83931a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner    this->setValue(Val);
84031a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner    return this->getValue();
84131a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner  }
842331de23705a719514e37c211f327379688f81b0dChris Lattner
843331de23705a719514e37c211f327379688f81b0dChris Lattner  // One option...
844331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t>
845cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit opt(const M0t &M0) : Option(Optional | NotHidden) {
846331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this);
847331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
848331de23705a719514e37c211f327379688f81b0dChris Lattner  }
849331de23705a719514e37c211f327379688f81b0dChris Lattner
850331de23705a719514e37c211f327379688f81b0dChris Lattner  // Two options...
851331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t>
852f6143ef556ed01311d2043d38421302479f7866cChris Lattner  opt(const M0t &M0, const M1t &M1) : Option(Optional | NotHidden) {
853331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this);
854331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
855331de23705a719514e37c211f327379688f81b0dChris Lattner  }
856331de23705a719514e37c211f327379688f81b0dChris Lattner
857331de23705a719514e37c211f327379688f81b0dChris Lattner  // Three options...
858331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t>
859f6143ef556ed01311d2043d38421302479f7866cChris Lattner  opt(const M0t &M0, const M1t &M1,
860f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M2t &M2) : Option(Optional | NotHidden) {
861331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this);
862331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
863331de23705a719514e37c211f327379688f81b0dChris Lattner  }
864331de23705a719514e37c211f327379688f81b0dChris Lattner  // Four options...
865331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t>
8666e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2,
867f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M3t &M3) : Option(Optional | NotHidden) {
868331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
869331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
870331de23705a719514e37c211f327379688f81b0dChris Lattner  }
871331de23705a719514e37c211f327379688f81b0dChris Lattner  // Five options...
872331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t, class M4t>
873331de23705a719514e37c211f327379688f81b0dChris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
874f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M4t &M4) : Option(Optional | NotHidden) {
875331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
876331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this);
877331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
878331de23705a719514e37c211f327379688f81b0dChris Lattner  }
879331de23705a719514e37c211f327379688f81b0dChris Lattner  // Six options...
880331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
881331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t>
882331de23705a719514e37c211f327379688f81b0dChris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
883f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M4t &M4, const M5t &M5) : Option(Optional | NotHidden) {
884331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
885331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this);
886331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
887331de23705a719514e37c211f327379688f81b0dChris Lattner  }
888331de23705a719514e37c211f327379688f81b0dChris Lattner  // Seven options...
889331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
890331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t, class M6t>
891331de23705a719514e37c211f327379688f81b0dChris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
892f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M4t &M4, const M5t &M5,
893f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M6t &M6) : Option(Optional | NotHidden) {
894331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
895331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this); apply(M6, this);
896331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
897331de23705a719514e37c211f327379688f81b0dChris Lattner  }
898331de23705a719514e37c211f327379688f81b0dChris Lattner  // Eight options...
899331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
900331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t, class M6t, class M7t>
901331de23705a719514e37c211f327379688f81b0dChris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
9026e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner      const M4t &M4, const M5t &M5, const M6t &M6,
903f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M7t &M7) : Option(Optional | NotHidden) {
904331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
905331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
906331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
907331de23705a719514e37c211f327379688f81b0dChris Lattner  }
908cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
909cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
9107422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
9117422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
9127422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
9137422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
9147422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
915331de23705a719514e37c211f327379688f81b0dChris Lattner//===----------------------------------------------------------------------===//
916331de23705a719514e37c211f327379688f81b0dChris Lattner// list_storage class
917331de23705a719514e37c211f327379688f81b0dChris Lattner
918331de23705a719514e37c211f327379688f81b0dChris Lattner// Default storage class definition: external storage.  This implementation
919331de23705a719514e37c211f327379688f81b0dChris Lattner// assumes the user will specify a variable to store the data into with the
920331de23705a719514e37c211f327379688f81b0dChris Lattner// cl::location(x) modifier.
921331de23705a719514e37c211f327379688f81b0dChris Lattner//
922331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType, class StorageClass>
923331de23705a719514e37c211f327379688f81b0dChris Lattnerclass list_storage {
924331de23705a719514e37c211f327379688f81b0dChris Lattner  StorageClass *Location;   // Where to store the object...
92571fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner
926cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
927331de23705a719514e37c211f327379688f81b0dChris Lattner  list_storage() : Location(0) {}
928331de23705a719514e37c211f327379688f81b0dChris Lattner
929331de23705a719514e37c211f327379688f81b0dChris Lattner  bool setLocation(Option &O, StorageClass &L) {
930331de23705a719514e37c211f327379688f81b0dChris Lattner    if (Location)
931331de23705a719514e37c211f327379688f81b0dChris Lattner      return O.error(": cl::location(x) specified more than once!");
932331de23705a719514e37c211f327379688f81b0dChris Lattner    Location = &L;
933331de23705a719514e37c211f327379688f81b0dChris Lattner    return false;
93471fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner  }
935331de23705a719514e37c211f327379688f81b0dChris Lattner
936331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
937331de23705a719514e37c211f327379688f81b0dChris Lattner  void addValue(const T &V) {
938331de23705a719514e37c211f327379688f81b0dChris Lattner    assert(Location != 0 && "cl::location(...) not specified for a command "
939331de23705a719514e37c211f327379688f81b0dChris Lattner           "line option with external storage!");
940331de23705a719514e37c211f327379688f81b0dChris Lattner    Location->push_back(V);
941cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
942331de23705a719514e37c211f327379688f81b0dChris Lattner};
943331de23705a719514e37c211f327379688f81b0dChris Lattner
944331de23705a719514e37c211f327379688f81b0dChris Lattner
945331de23705a719514e37c211f327379688f81b0dChris Lattner// Define how to hold a class type object, such as a string.  Since we can
946331de23705a719514e37c211f327379688f81b0dChris Lattner// inherit from a class, we do so.  This makes us exactly compatible with the
947331de23705a719514e37c211f327379688f81b0dChris Lattner// object in all cases that it is used.
948331de23705a719514e37c211f327379688f81b0dChris Lattner//
949331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
9501fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass list_storage<DataType, bool> : public std::vector<DataType> {
9511fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
952331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
953331de23705a719514e37c211f327379688f81b0dChris Lattner  void addValue(const T &V) { push_back(V); }
954cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
955cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
956cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
957cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
958331de23705a719514e37c211f327379688f81b0dChris Lattner// list - A list of command line options.
959cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
960331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate <class DataType, class Storage = bool,
961331de23705a719514e37c211f327379688f81b0dChris Lattner          class ParserClass = parser<DataType> >
962331de23705a719514e37c211f327379688f81b0dChris Lattnerclass list : public Option, public list_storage<DataType, Storage> {
9631e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  std::vector<unsigned> Positions;
964331de23705a719514e37c211f327379688f81b0dChris Lattner  ParserClass Parser;
965331de23705a719514e37c211f327379688f81b0dChris Lattner
966cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  virtual enum ValueExpected getValueExpectedFlagDefault() const {
967331de23705a719514e37c211f327379688f81b0dChris Lattner    return Parser.getValueExpectedFlagDefault();
968cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
9699878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
9709878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    return Parser.getExtraOptionNames(OptionNames);
9719878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  }
972beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
97363b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  virtual bool handleOccurrence(unsigned pos, const char *ArgName,
9741e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                                const std::string &Arg) {
9758a207c16d2eb44ebcf94b13b0db047e46b7b0d30Reid Spencer    typename ParserClass::parser_data_type Val =
9768a207c16d2eb44ebcf94b13b0db047e46b7b0d30Reid Spencer      typename ParserClass::parser_data_type();
977d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    if (Parser.parse(*this, ArgName, Arg, Val))
978d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner      return true;  // Parse Error!
979d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    addValue(Val);
9801e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    setPosition(pos);
9811e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    Positions.push_back(pos);
982d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    return false;
983331de23705a719514e37c211f327379688f81b0dChris Lattner  }
984cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
985331de23705a719514e37c211f327379688f81b0dChris Lattner  // Forward printing stuff to the parser...
98634cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
98734cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const {
988331de23705a719514e37c211f327379688f81b0dChris Lattner    Parser.printOptionInfo(*this, GlobalWidth);
989331de23705a719514e37c211f327379688f81b0dChris Lattner  }
990cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
991331de23705a719514e37c211f327379688f81b0dChris Lattner  void done() {
9929878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    addArgument();
993331de23705a719514e37c211f327379688f81b0dChris Lattner    Parser.initialize(*this);
994331de23705a719514e37c211f327379688f81b0dChris Lattner  }
995cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
996331de23705a719514e37c211f327379688f81b0dChris Lattner  ParserClass &getParser() { return Parser; }
997331de23705a719514e37c211f327379688f81b0dChris Lattner
99863b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  unsigned getPosition(unsigned optnum) const {
9991e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    assert(optnum < this->size() && "Invalid option index");
100063b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    return Positions[optnum];
10011e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  }
10021e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer
1003331de23705a719514e37c211f327379688f81b0dChris Lattner  // One option...
1004331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t>
1005cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit list(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
1006331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this);
1007331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1008331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1009331de23705a719514e37c211f327379688f81b0dChris Lattner  // Two options...
1010331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t>
1011f6143ef556ed01311d2043d38421302479f7866cChris Lattner  list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
1012331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this);
1013331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1014331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1015331de23705a719514e37c211f327379688f81b0dChris Lattner  // Three options...
1016331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t>
1017f6143ef556ed01311d2043d38421302479f7866cChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2)
1018f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1019331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this);
1020331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1021331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1022331de23705a719514e37c211f327379688f81b0dChris Lattner  // Four options...
1023331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t>
10246e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
1025f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1026331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1027331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1028331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1029331de23705a719514e37c211f327379688f81b0dChris Lattner  // Five options...
1030331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t, class M4t>
1031331de23705a719514e37c211f327379688f81b0dChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1032f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4) : Option(ZeroOrMore | NotHidden) {
1033331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1034331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this);
1035331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1036331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1037331de23705a719514e37c211f327379688f81b0dChris Lattner  // Six options...
1038331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
1039331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t>
1040331de23705a719514e37c211f327379688f81b0dChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1041f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
1042331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1043331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this);
1044331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1045331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1046331de23705a719514e37c211f327379688f81b0dChris Lattner  // Seven options...
1047331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
1048331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t, class M6t>
1049331de23705a719514e37c211f327379688f81b0dChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1050f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4, const M5t &M5, const M6t &M6)
1051f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1052331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1053331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this); apply(M6, this);
1054331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1055331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1056331de23705a719514e37c211f327379688f81b0dChris Lattner  // Eight options...
1057331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
1058331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t, class M6t, class M7t>
1059331de23705a719514e37c211f327379688f81b0dChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
10606e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner       const M4t &M4, const M5t &M5, const M6t &M6,
1061f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M7t &M7) : Option(ZeroOrMore | NotHidden) {
1062331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1063331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
1064331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1065331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1066cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
1067cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
1068331de23705a719514e37c211f327379688f81b0dChris Lattner//===----------------------------------------------------------------------===//
1069eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// bits_storage class
1070eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1071eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// Default storage class definition: external storage.  This implementation
1072eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// assumes the user will specify a variable to store the data into with the
1073eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// cl::location(x) modifier.
1074eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//
1075eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeytemplate<class DataType, class StorageClass>
1076eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeyclass bits_storage {
1077a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  unsigned *Location;   // Where to store the bits...
1078beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1079eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1080eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  static unsigned Bit(const T &V) {
10813e41da29fb74a4f2a43a1539b612b2fb11bef375Reid Spencer    unsigned BitPos = reinterpret_cast<unsigned>(V);
1082a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey    assert(BitPos < sizeof(unsigned) * 8 &&
1083eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey          "enum exceeds width of bit vector!");
1084eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return 1 << BitPos;
1085eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1086eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1087eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeypublic:
1088eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits_storage() : Location(0) {}
1089eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1090a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  bool setLocation(Option &O, unsigned &L) {
1091eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    if (Location)
1092eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey      return O.error(": cl::location(x) specified more than once!");
1093eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Location = &L;
1094eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return false;
1095eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1096eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1097eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1098eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  void addValue(const T &V) {
1099eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    assert(Location != 0 && "cl::location(...) not specified for a command "
1100eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey           "line option with external storage!");
1101eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    *Location |= Bit(V);
1102eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1103beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1104a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  unsigned getBits() { return *Location; }
1105beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1106eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1107eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bool isSet(const T &V) {
1108eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return (*Location & Bit(V)) != 0;
1109eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1110eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey};
1111eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1112eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1113beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov// Define how to hold bits.  Since we can inherit from a class, we do so.
1114eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// This makes us exactly compatible with the bits in all cases that it is used.
1115eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//
1116eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeytemplate<class DataType>
1117eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeyclass bits_storage<DataType, bool> {
1118a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  unsigned Bits;   // Where to store the bits...
1119beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1120eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1121eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  static unsigned Bit(const T &V) {
11223e41da29fb74a4f2a43a1539b612b2fb11bef375Reid Spencer    unsigned BitPos = reinterpret_cast<unsigned>(V);
1123a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey    assert(BitPos < sizeof(unsigned) * 8 &&
1124eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey          "enum exceeds width of bit vector!");
1125eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return 1 << BitPos;
1126eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1127beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1128eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeypublic:
1129eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1130eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  void addValue(const T &V) {
1131eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Bits |=  Bit(V);
1132eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1133beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1134a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  unsigned getBits() { return Bits; }
1135beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1136eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1137eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bool isSet(const T &V) {
1138eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return (Bits & Bit(V)) != 0;
1139eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1140eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey};
1141eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1142eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1143eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//===----------------------------------------------------------------------===//
1144eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// bits - A bit vector of command options.
1145eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//
1146eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeytemplate <class DataType, class Storage = bool,
1147eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey          class ParserClass = parser<DataType> >
1148eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeyclass bits : public Option, public bits_storage<DataType, Storage> {
1149eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  std::vector<unsigned> Positions;
1150eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  ParserClass Parser;
1151eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1152eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  virtual enum ValueExpected getValueExpectedFlagDefault() const {
1153eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return Parser.getValueExpectedFlagDefault();
1154eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
11559878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
11569878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    return Parser.getExtraOptionNames(OptionNames);
11579878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  }
1158beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1159eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  virtual bool handleOccurrence(unsigned pos, const char *ArgName,
1160eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey                                const std::string &Arg) {
1161eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    typename ParserClass::parser_data_type Val =
1162eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey      typename ParserClass::parser_data_type();
1163eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    if (Parser.parse(*this, ArgName, Arg, Val))
1164eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey      return true;  // Parse Error!
1165eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    addValue(Val);
1166eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    setPosition(pos);
1167eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Positions.push_back(pos);
1168eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return false;
1169eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1170eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1171eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Forward printing stuff to the parser...
117234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
117334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const {
1174eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Parser.printOptionInfo(*this, GlobalWidth);
1175eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1176eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1177eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  void done() {
11789878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    addArgument();
1179eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Parser.initialize(*this);
1180eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1181eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeypublic:
1182eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  ParserClass &getParser() { return Parser; }
1183eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1184eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  unsigned getPosition(unsigned optnum) const {
1185eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    assert(optnum < this->size() && "Invalid option index");
1186eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return Positions[optnum];
1187eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1188eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1189eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // One option...
1190eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t>
1191cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit bits(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
1192eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this);
1193eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1194eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1195eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Two options...
1196eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t>
1197f6143ef556ed01311d2043d38421302479f7866cChris Lattner  bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
1198eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this);
1199eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1200eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1201eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Three options...
1202eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t>
1203f6143ef556ed01311d2043d38421302479f7866cChris Lattner  bits(const M0t &M0, const M1t &M1, const M2t &M2)
1204f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1205eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this);
1206eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1207eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1208eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Four options...
1209eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t>
1210f6143ef556ed01311d2043d38421302479f7866cChris Lattner  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
1211f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1212eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1213eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1214eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1215eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Five options...
1216eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t, class M4t>
1217eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1218f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4) : Option(ZeroOrMore | NotHidden) {
1219eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1220eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M4, this);
1221eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1222eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1223eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Six options...
1224eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t,
1225eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey           class M4t, class M5t>
1226eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1227f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
1228eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1229eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M4, this); apply(M5, this);
1230eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1231eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1232eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Seven options...
1233eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t,
1234eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey           class M4t, class M5t, class M6t>
1235eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1236f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4, const M5t &M5, const M6t &M6)
1237f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1238eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1239eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M4, this); apply(M5, this); apply(M6, this);
1240eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1241eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1242eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Eight options...
1243eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t,
1244eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey           class M4t, class M5t, class M6t, class M7t>
1245eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
12466e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner       const M4t &M4, const M5t &M5, const M6t &M6,
1247f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M7t &M7) : Option(ZeroOrMore | NotHidden) {
1248eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1249eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
1250eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1251eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1252eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey};
1253eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1254eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//===----------------------------------------------------------------------===//
1255331de23705a719514e37c211f327379688f81b0dChris Lattner// Aliased command line option (alias this name to a preexisting name)
1256331de23705a719514e37c211f327379688f81b0dChris Lattner//
1257331de23705a719514e37c211f327379688f81b0dChris Lattner
1258331de23705a719514e37c211f327379688f81b0dChris Lattnerclass alias : public Option {
1259331de23705a719514e37c211f327379688f81b0dChris Lattner  Option *AliasFor;
12600008f654bf08dc631a1abaa175dd08f1fd1be75eSteve Naroff  virtual bool handleOccurrence(unsigned pos, const char * /*ArgName*/,
12611e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                                const std::string &Arg) {
12621e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
1263331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1264331de23705a719514e37c211f327379688f81b0dChris Lattner  // Handle printing stuff...
126534cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const;
126634cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const;
1267331de23705a719514e37c211f327379688f81b0dChris Lattner
1268331de23705a719514e37c211f327379688f81b0dChris Lattner  void done() {
1269331de23705a719514e37c211f327379688f81b0dChris Lattner    if (!hasArgStr())
1270331de23705a719514e37c211f327379688f81b0dChris Lattner      error(": cl::alias must have argument name specified!");
1271331de23705a719514e37c211f327379688f81b0dChris Lattner    if (AliasFor == 0)
1272331de23705a719514e37c211f327379688f81b0dChris Lattner      error(": cl::alias must have an cl::aliasopt(option) specified!");
12739878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner      addArgument();
1274331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1275cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
1276331de23705a719514e37c211f327379688f81b0dChris Lattner  void setAliasFor(Option &O) {
1277331de23705a719514e37c211f327379688f81b0dChris Lattner    if (AliasFor)
1278331de23705a719514e37c211f327379688f81b0dChris Lattner      error(": cl::alias must only have one cl::aliasopt(...) specified!");
1279331de23705a719514e37c211f327379688f81b0dChris Lattner    AliasFor = &O;
1280331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1281331de23705a719514e37c211f327379688f81b0dChris Lattner
1282331de23705a719514e37c211f327379688f81b0dChris Lattner  // One option...
1283331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t>
1284cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit alias(const M0t &M0) : Option(Optional | Hidden), AliasFor(0) {
1285331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this);
1286331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1287331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1288331de23705a719514e37c211f327379688f81b0dChris Lattner  // Two options...
1289331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t>
1290f6143ef556ed01311d2043d38421302479f7866cChris Lattner  alias(const M0t &M0, const M1t &M1) : Option(Optional | Hidden), AliasFor(0) {
1291331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this);
1292331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1293331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1294331de23705a719514e37c211f327379688f81b0dChris Lattner  // Three options...
1295331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t>
12966e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner  alias(const M0t &M0, const M1t &M1, const M2t &M2)
1297f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(Optional | Hidden), AliasFor(0) {
1298331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this);
1299331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1300331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1301331de23705a719514e37c211f327379688f81b0dChris Lattner  // Four options...
1302331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t>
1303331de23705a719514e37c211f327379688f81b0dChris Lattner  alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
1304f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(Optional | Hidden), AliasFor(0) {
1305331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1306331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1307331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1308331de23705a719514e37c211f327379688f81b0dChris Lattner};
1309331de23705a719514e37c211f327379688f81b0dChris Lattner
1310331de23705a719514e37c211f327379688f81b0dChris Lattner// aliasfor - Modifier to set the option an alias aliases.
1311331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct aliasopt {
1312331de23705a719514e37c211f327379688f81b0dChris Lattner  Option &Opt;
1313cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit aliasopt(Option &O) : Opt(O) {}
1314331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(alias &A) const { A.setAliasFor(Opt); }
1315cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
1316cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
13179bbba091396922093687d11a181e5886c42c5dfdReid Spencer// extrahelp - provide additional help at the end of the normal help
13189bbba091396922093687d11a181e5886c42c5dfdReid Spencer// output. All occurrences of cl::extrahelp will be accumulated and
13199bbba091396922093687d11a181e5886c42c5dfdReid Spencer// printed to std::cerr at the end of the regular help, just before
13209bbba091396922093687d11a181e5886c42c5dfdReid Spencer// exit is called.
13219bbba091396922093687d11a181e5886c42c5dfdReid Spencerstruct extrahelp {
13229bbba091396922093687d11a181e5886c42c5dfdReid Spencer  const char * morehelp;
1323b5660dc8223bd5eb3d21d9855692617fcdec5663Dan Gohman  explicit extrahelp(const char* help);
13249bbba091396922093687d11a181e5886c42c5dfdReid Spencer};
13259bbba091396922093687d11a181e5886c42c5dfdReid Spencer
1326aed293dfba04b07a867491c11dfff4bf3eb6bdddDevang Patelvoid PrintVersionMessage();
13279bbba091396922093687d11a181e5886c42c5dfdReid Spencer// This function just prints the help message, exactly the same way as if the
13289bbba091396922093687d11a181e5886c42c5dfdReid Spencer// --help option had been given on the command line.
13299bbba091396922093687d11a181e5886c42c5dfdReid Spencer// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
13309bbba091396922093687d11a181e5886c42c5dfdReid Spencervoid PrintHelpMessage();
1331cc08ee507fc47d80a67c10a20b95587f7f06f0b7Reid Spencer
1332cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner} // End namespace cl
1333cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
1334d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End namespace llvm
1335d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
1336cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#endif
1337