CommandLine.h revision b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6db
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>
28de551f91d8816632a76a065084caab9fab6aacffDan Gohman#include <climits>
29630fcb86785f96501126e52009619b475403dc62Misha Brukman#include <cstdarg>
30cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include <string>
31cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include <utility>
32630fcb86785f96501126e52009619b475403dc62Misha Brukman#include <vector>
33be583b914d8156b99d3da264d5adca37fee8dbc9John Criswell
34d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
357b3d73b7ecbecf423c3766e596b6086767444363Chris Lattner
36bf0ac3fe69aa9e1bfcffec36ea53dadbb97c6b4dChris Lattner/// cl Namespace - This namespace contains all of the command line option
37bf0ac3fe69aa9e1bfcffec36ea53dadbb97c6b4dChris Lattner/// processing machinery.  It is intentionally a short name to make qualified
38bf0ac3fe69aa9e1bfcffec36ea53dadbb97c6b4dChris Lattner/// usage concise.
39bf0ac3fe69aa9e1bfcffec36ea53dadbb97c6b4dChris Lattnernamespace cl {
40cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
41cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
42331de23705a719514e37c211f327379688f81b0dChris Lattner// ParseCommandLineOptions - Command line option processing entry point.
43cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
449a5263241d40d493445d7f386b4d76be088c3ac1Dan Gohmanvoid ParseCommandLineOptions(int argc, char **argv,
45beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov                             const char *Overview = 0,
46beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov                             bool ReadResponseFiles = false);
47cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
48cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
4906b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke// ParseEnvironmentOptions - Environment variable option processing alternate
5006b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke//                           entry point.
5106b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke//
52c48ef2ae36e2169872a828a5399ccd1993837915Brian Gaekevoid ParseEnvironmentOptions(const char *progName, const char *envvar,
53beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov                             const char *Overview = 0,
54beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov                             bool ReadResponseFiles = false);
5506b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke
56515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer///===---------------------------------------------------------------------===//
57515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer/// SetVersionPrinter - Override the default (LLVM specific) version printer
58515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer///                     used to print out the version when --version is given
593ab264a985de3d86e0d1f5716f6d633fd8538618Dan Gohman///                     on the command line. This allows other systems using the
60515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer///                     CommandLine utilities to print their own version string.
61515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencervoid SetVersionPrinter(void (*func)());
62515b5b379f3508f36f647bfdafce409e28a3d90bReid Spencer
6369d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattner
6469d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattner// MarkOptionsChanged - Internal helper function.
6569d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattnervoid MarkOptionsChanged();
6669d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattner
6706b06c5f00acffdab8c59e3dc5baca3eacca172aBrian Gaeke//===----------------------------------------------------------------------===//
68331de23705a719514e37c211f327379688f81b0dChris Lattner// Flags permitted to be passed to command line arguments
69331de23705a719514e37c211f327379688f81b0dChris Lattner//
70cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
711e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencerenum NumOccurrences {          // Flags for the number of occurrences allowed
72b5c520bfb6505caaa6ad8468b372530d44c8b253Misha Brukman  Optional        = 0x01,      // Zero or One occurrence
73b5c520bfb6505caaa6ad8468b372530d44c8b253Misha Brukman  ZeroOrMore      = 0x02,      // Zero or more occurrences allowed
74b5c520bfb6505caaa6ad8468b372530d44c8b253Misha Brukman  Required        = 0x03,      // One occurrence required
75b5c520bfb6505caaa6ad8468b372530d44c8b253Misha Brukman  OneOrMore       = 0x04,      // One or more occurrences required
76cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
77331de23705a719514e37c211f327379688f81b0dChris Lattner  // ConsumeAfter - Indicates that this option is fed anything that follows the
78331de23705a719514e37c211f327379688f81b0dChris Lattner  // last positional argument required by the application (it is an error if
79331de23705a719514e37c211f327379688f81b0dChris Lattner  // there are zero positional arguments, and a ConsumeAfter option is used).
80331de23705a719514e37c211f327379688f81b0dChris Lattner  // Thus, for example, all arguments to LLI are processed until a filename is
81331de23705a719514e37c211f327379688f81b0dChris Lattner  // found.  Once a filename is found, all of the succeeding arguments are
82331de23705a719514e37c211f327379688f81b0dChris Lattner  // passed, unprocessed, to the ConsumeAfter option.
83cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  //
84cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  ConsumeAfter    = 0x05,
85cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
8640f44f1f58f823994b7f4ec4005887c3955fb1e7Chris Lattner  OccurrencesMask  = 0x07
87cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
88cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
89cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerenum ValueExpected {           // Is a value required for the option?
90b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  ValueOptional   = 0x08,      // The value can appear... or not
91cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  ValueRequired   = 0x10,      // The value is required to appear!
92cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  ValueDisallowed = 0x18,      // A value may not be specified (for flags)
9340f44f1f58f823994b7f4ec4005887c3955fb1e7Chris Lattner  ValueMask       = 0x18
94cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
95cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
96cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerenum OptionHidden {            // Control whether -help shows this option
97cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  NotHidden       = 0x20,      // Option included in --help & --help-hidden
98cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  Hidden          = 0x40,      // -help doesn't, but --help-hidden does
99cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  ReallyHidden    = 0x60,      // Neither --help nor --help-hidden show this arg
10040f44f1f58f823994b7f4ec4005887c3955fb1e7Chris Lattner  HiddenMask      = 0x60
101cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
102cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
103331de23705a719514e37c211f327379688f81b0dChris Lattner// Formatting flags - This controls special features that the option might have
104331de23705a719514e37c211f327379688f81b0dChris Lattner// that cause it to be parsed differently...
105331de23705a719514e37c211f327379688f81b0dChris Lattner//
106331de23705a719514e37c211f327379688f81b0dChris Lattner// Prefix - This option allows arguments that are otherwise unrecognized to be
107331de23705a719514e37c211f327379688f81b0dChris Lattner// matched by options that are a prefix of the actual value.  This is useful for
108331de23705a719514e37c211f327379688f81b0dChris Lattner// cases like a linker, where options are typically of the form '-lfoo' or
109331de23705a719514e37c211f327379688f81b0dChris Lattner// '-L../../include' where -l or -L are the actual flags.  When prefix is
110331de23705a719514e37c211f327379688f81b0dChris Lattner// enabled, and used, the value for the flag comes from the suffix of the
111331de23705a719514e37c211f327379688f81b0dChris Lattner// argument.
112331de23705a719514e37c211f327379688f81b0dChris Lattner//
113331de23705a719514e37c211f327379688f81b0dChris Lattner// Grouping - With this option enabled, multiple letter options are allowed to
114331de23705a719514e37c211f327379688f81b0dChris Lattner// bunch together with only a single hyphen for the whole group.  This allows
115331de23705a719514e37c211f327379688f81b0dChris Lattner// emulation of the behavior that ls uses for example: ls -la === ls -l -a
116331de23705a719514e37c211f327379688f81b0dChris Lattner//
117331de23705a719514e37c211f327379688f81b0dChris Lattner
118331de23705a719514e37c211f327379688f81b0dChris Lattnerenum FormattingFlags {
119331de23705a719514e37c211f327379688f81b0dChris Lattner  NormalFormatting = 0x000,     // Nothing special
120331de23705a719514e37c211f327379688f81b0dChris Lattner  Positional       = 0x080,     // Is a positional argument, no '-' required
121331de23705a719514e37c211f327379688f81b0dChris Lattner  Prefix           = 0x100,     // Can this option directly prefix its value?
122331de23705a719514e37c211f327379688f81b0dChris Lattner  Grouping         = 0x180,     // Can this option group with other options?
12340f44f1f58f823994b7f4ec4005887c3955fb1e7Chris Lattner  FormattingMask   = 0x180      // Union of the above flags.
124331de23705a719514e37c211f327379688f81b0dChris Lattner};
125331de23705a719514e37c211f327379688f81b0dChris Lattner
1261e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencerenum MiscFlags {               // Miscellaneous flags to adjust argument
1271e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  CommaSeparated     = 0x200,  // Should this cl::list split between commas?
1281e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  PositionalEatsArgs = 0x400,  // Should this positional cl::list eat -args?
129d57160d097d6cdb966e5c851215acbd2bf1aa236Anton Korobeynikov  Sink               = 0x800,  // Should this cl::list eat all unknown options?
13000a7b52385a25ab8cd412ce4c0f0ce11176b6793Chris Lattner  MiscMask           = 0xE00   // Union of the above flags.
131b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner};
132b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner
133b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner
134cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
135cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
136cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner// Option Base class
137cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
138331de23705a719514e37c211f327379688f81b0dChris Lattnerclass alias;
139cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerclass Option {
140331de23705a719514e37c211f327379688f81b0dChris Lattner  friend class alias;
141cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
142dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  // handleOccurrences - Overriden by subclasses to handle the value passed into
143cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // an argument.  Should return true if there was an error processing the
144cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // argument and the program should exit.
145cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  //
14663b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  virtual bool handleOccurrence(unsigned pos, const char *ArgName,
1471e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                                const std::string &Arg) = 0;
148cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
149cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  virtual enum ValueExpected getValueExpectedFlagDefault() const {
15063b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    return ValueOptional;
151cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
152beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
153433fd76e51e9bd9a4933e2c1775a7410928112c8Chris Lattner  // Out of line virtual function to provide home for the class.
154433fd76e51e9bd9a4933e2c1775a7410928112c8Chris Lattner  virtual void anchor();
155beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1569878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  int NumOccurrences;     // The number of times specified
1579878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  int Flags;              // Flags for the argument
1589878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  unsigned Position;      // Position of last occurrence of the option
1597059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  unsigned AdditionalVals;// Greater than 0 for multi-valued option.
1609878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  Option *NextRegistered; // Singly linked list of registered options.
161cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
1629878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  const char *ArgStr;     // The argument string itself (ex: "help", "o")
1639878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  const char *HelpStr;    // The descriptive text message for --help
1649878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  const char *ValueStr;   // String describing what the value of this option is
165cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
166dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  inline enum NumOccurrences getNumOccurrencesFlag() const {
167f6143ef556ed01311d2043d38421302479f7866cChris Lattner    return static_cast<enum NumOccurrences>(Flags & OccurrencesMask);
168cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
169cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  inline enum ValueExpected getValueExpectedFlag() const {
170cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner    int VE = Flags & ValueMask;
1718b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner    return VE ? static_cast<enum ValueExpected>(VE)
1728b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner              : getValueExpectedFlagDefault();
173cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
174cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  inline enum OptionHidden getOptionHiddenFlag() const {
175f6143ef556ed01311d2043d38421302479f7866cChris Lattner    return static_cast<enum OptionHidden>(Flags & HiddenMask);
176cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
177331de23705a719514e37c211f327379688f81b0dChris Lattner  inline enum FormattingFlags getFormattingFlag() const {
178f6143ef556ed01311d2043d38421302479f7866cChris Lattner    return static_cast<enum FormattingFlags>(Flags & FormattingMask);
179331de23705a719514e37c211f327379688f81b0dChris Lattner  }
180b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  inline unsigned getMiscFlags() const {
181b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner    return Flags & MiscMask;
182b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  }
1831e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  inline unsigned getPosition() const { return Position; }
1847059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  inline unsigned getNumAdditionalVals() const { return AdditionalVals; }
185331de23705a719514e37c211f327379688f81b0dChris Lattner
186331de23705a719514e37c211f327379688f81b0dChris Lattner  // hasArgStr - Return true if the argstr != ""
187331de23705a719514e37c211f327379688f81b0dChris Lattner  bool hasArgStr() const { return ArgStr[0] != 0; }
188331de23705a719514e37c211f327379688f81b0dChris Lattner
189331de23705a719514e37c211f327379688f81b0dChris Lattner  //-------------------------------------------------------------------------===
190331de23705a719514e37c211f327379688f81b0dChris Lattner  // Accessor functions set by OptionModifiers
191331de23705a719514e37c211f327379688f81b0dChris Lattner  //
192331de23705a719514e37c211f327379688f81b0dChris Lattner  void setArgStr(const char *S) { ArgStr = S; }
193331de23705a719514e37c211f327379688f81b0dChris Lattner  void setDescription(const char *S) { HelpStr = S; }
194331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValueStr(const char *S) { ValueStr = S; }
195331de23705a719514e37c211f327379688f81b0dChris Lattner
196331de23705a719514e37c211f327379688f81b0dChris Lattner  void setFlag(unsigned Flag, unsigned FlagMask) {
197f3799d6317e38a996dcea50143cbc15543d8f5c4Chris Lattner    Flags &= ~FlagMask;
198331de23705a719514e37c211f327379688f81b0dChris Lattner    Flags |= Flag;
199331de23705a719514e37c211f327379688f81b0dChris Lattner  }
200331de23705a719514e37c211f327379688f81b0dChris Lattner
201dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  void setNumOccurrencesFlag(enum NumOccurrences Val) {
202dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman    setFlag(Val, OccurrencesMask);
203331de23705a719514e37c211f327379688f81b0dChris Lattner  }
204331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); }
205331de23705a719514e37c211f327379688f81b0dChris Lattner  void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); }
206331de23705a719514e37c211f327379688f81b0dChris Lattner  void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); }
207b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  void setMiscFlag(enum MiscFlags M) { setFlag(M, M); }
2081e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  void setPosition(unsigned pos) { Position = pos; }
209cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerprotected:
21027e9d457d4047cf0051e17d9ca39740875d11440Dan Gohman  explicit Option(unsigned DefaultFlags)
211f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : NumOccurrences(0), Flags(DefaultFlags | NormalFormatting), Position(0),
2127059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov      AdditionalVals(0), NextRegistered(0),
2137059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov      ArgStr(""), HelpStr(""), ValueStr("") {
214f6143ef556ed01311d2043d38421302479f7866cChris Lattner    assert(getNumOccurrencesFlag() != 0 &&
215f6143ef556ed01311d2043d38421302479f7866cChris Lattner           getOptionHiddenFlag() != 0 && "Not all default flags specified!");
216f6143ef556ed01311d2043d38421302479f7866cChris Lattner  }
217cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
2187059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  inline void setNumAdditionalVals(unsigned n)
2197059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  { AdditionalVals = n; }
220cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
2219878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  // addArgument - Register this argument with the commandline system.
222331de23705a719514e37c211f327379688f81b0dChris Lattner  //
2239878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  void addArgument();
224beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
2259878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  Option *getNextRegisteredOption() const { return NextRegistered; }
226331de23705a719514e37c211f327379688f81b0dChris Lattner
227cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // Return the width of the option tag for printing...
22834cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const = 0;
229cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
23063b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  // printOptionInfo - Print out information about this option.  The
231cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // to-be-maintained width is specified.
232cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  //
23334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const = 0;
234cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
23513d57320bd212483463d4f8992d5787b29eda5dfBill Wendling  virtual void getExtraOptionNames(std::vector<const char*> &) {}
236beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
237dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  // addOccurrence - Wrapper around handleOccurrence that enforces Flags
238cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  //
23963b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  bool addOccurrence(unsigned pos, const char *ArgName,
2407059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov                     const std::string &Value, bool MultiArg = false);
241cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
242cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  // Prints option name followed by message.  Always returns true.
243697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  bool error(std::string Message, const char *ArgName = 0);
244cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
245cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
246dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  inline int getNumOccurrences() const { return NumOccurrences; }
247cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  virtual ~Option() {}
248cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
249cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
250cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
251cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
252331de23705a719514e37c211f327379688f81b0dChris Lattner// Command line option modifiers that can be used to modify the behavior of
253331de23705a719514e37c211f327379688f81b0dChris Lattner// command line option parsers...
254cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
255331de23705a719514e37c211f327379688f81b0dChris Lattner
256331de23705a719514e37c211f327379688f81b0dChris Lattner// desc - Modifier to set the description shown in the --help output...
257331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct desc {
258331de23705a719514e37c211f327379688f81b0dChris Lattner  const char *Desc;
259331de23705a719514e37c211f327379688f81b0dChris Lattner  desc(const char *Str) : Desc(Str) {}
260331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Option &O) const { O.setDescription(Desc); }
261331de23705a719514e37c211f327379688f81b0dChris Lattner};
262331de23705a719514e37c211f327379688f81b0dChris Lattner
263331de23705a719514e37c211f327379688f81b0dChris Lattner// value_desc - Modifier to set the value description shown in the --help
264331de23705a719514e37c211f327379688f81b0dChris Lattner// output...
265331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct value_desc {
266331de23705a719514e37c211f327379688f81b0dChris Lattner  const char *Desc;
267331de23705a719514e37c211f327379688f81b0dChris Lattner  value_desc(const char *Str) : Desc(Str) {}
268331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Option &O) const { O.setValueStr(Desc); }
269331de23705a719514e37c211f327379688f81b0dChris Lattner};
270331de23705a719514e37c211f327379688f81b0dChris Lattner
271331de23705a719514e37c211f327379688f81b0dChris Lattner// init - Specify a default (initial) value for the command line argument, if
272331de23705a719514e37c211f327379688f81b0dChris Lattner// the default constructor for the argument type does not give you what you
273331de23705a719514e37c211f327379688f81b0dChris Lattner// want.  This is only valid on "opt" arguments, not on "list" arguments.
274331de23705a719514e37c211f327379688f81b0dChris Lattner//
275331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Ty>
276331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct initializer {
277331de23705a719514e37c211f327379688f81b0dChris Lattner  const Ty &Init;
278331de23705a719514e37c211f327379688f81b0dChris Lattner  initializer(const Ty &Val) : Init(Val) {}
279331de23705a719514e37c211f327379688f81b0dChris Lattner
280331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
281331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Opt &O) const { O.setInitialValue(Init); }
282cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
283cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
284331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Ty>
285331de23705a719514e37c211f327379688f81b0dChris Lattnerinitializer<Ty> init(const Ty &Val) {
286331de23705a719514e37c211f327379688f81b0dChris Lattner  return initializer<Ty>(Val);
287331de23705a719514e37c211f327379688f81b0dChris Lattner}
288331de23705a719514e37c211f327379688f81b0dChris Lattner
289331de23705a719514e37c211f327379688f81b0dChris Lattner
290331de23705a719514e37c211f327379688f81b0dChris Lattner// location - Allow the user to specify which external variable they want to
291331de23705a719514e37c211f327379688f81b0dChris Lattner// store the results of the command line argument processing into, if they don't
292331de23705a719514e37c211f327379688f81b0dChris Lattner// want to store it in the option itself.
293331de23705a719514e37c211f327379688f81b0dChris Lattner//
294331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Ty>
295331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct LocationClass {
296331de23705a719514e37c211f327379688f81b0dChris Lattner  Ty &Loc;
297331de23705a719514e37c211f327379688f81b0dChris Lattner  LocationClass(Ty &L) : Loc(L) {}
298331de23705a719514e37c211f327379688f81b0dChris Lattner
299331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
300331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Opt &O) const { O.setLocation(O, Loc); }
301331de23705a719514e37c211f327379688f81b0dChris Lattner};
302331de23705a719514e37c211f327379688f81b0dChris Lattner
303331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Ty>
304331de23705a719514e37c211f327379688f81b0dChris LattnerLocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
305331de23705a719514e37c211f327379688f81b0dChris Lattner
306331de23705a719514e37c211f327379688f81b0dChris Lattner
307cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
308331de23705a719514e37c211f327379688f81b0dChris Lattner// Enum valued command line option
309cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
310f8063f91227712cc726fca385dd8b88bf6400c84Reid Spencer#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC
311f8063f91227712cc726fca385dd8b88bf6400c84Reid Spencer#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC
312f8063f91227712cc726fca385dd8b88bf6400c84Reid Spencer#define clEnumValEnd (reinterpret_cast<void*>(0))
313331de23705a719514e37c211f327379688f81b0dChris Lattner
314331de23705a719514e37c211f327379688f81b0dChris Lattner// values - For custom data types, allow specifying a group of values together
315331de23705a719514e37c211f327379688f81b0dChris Lattner// as the values that go into the mapping that the option handler uses.  Note
316331de23705a719514e37c211f327379688f81b0dChris Lattner// that the values list must always have a 0 at the end of the list to indicate
317331de23705a719514e37c211f327379688f81b0dChris Lattner// that the list has ended.
318331de23705a719514e37c211f327379688f81b0dChris Lattner//
319331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
320331de23705a719514e37c211f327379688f81b0dChris Lattnerclass ValuesClass {
321331de23705a719514e37c211f327379688f81b0dChris Lattner  // Use a vector instead of a map, because the lists should be short,
322331de23705a719514e37c211f327379688f81b0dChris Lattner  // the overhead is less, and most importantly, it keeps them in the order
323331de23705a719514e37c211f327379688f81b0dChris Lattner  // inserted so we can print our option out nicely.
3243b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  SmallVector<std::pair<const char *, std::pair<int, const char *> >,4> Values;
325331de23705a719514e37c211f327379688f81b0dChris Lattner  void processValues(va_list Vals);
326cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
32763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  ValuesClass(const char *EnumName, DataType Val, const char *Desc,
328331de23705a719514e37c211f327379688f81b0dChris Lattner              va_list ValueArgs) {
329331de23705a719514e37c211f327379688f81b0dChris Lattner    // Insert the first value, which is required.
330331de23705a719514e37c211f327379688f81b0dChris Lattner    Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc)));
331331de23705a719514e37c211f327379688f81b0dChris Lattner
332331de23705a719514e37c211f327379688f81b0dChris Lattner    // Process the varargs portion of the values...
33313d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    while (const char *enumName = va_arg(ValueArgs, const char *)) {
3348b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner      DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int));
335331de23705a719514e37c211f327379688f81b0dChris Lattner      const char *EnumDesc = va_arg(ValueArgs, const char *);
33613d57320bd212483463d4f8992d5787b29eda5dfBill Wendling      Values.push_back(std::make_pair(enumName,      // Add value to value map
337331de23705a719514e37c211f327379688f81b0dChris Lattner                                      std::make_pair(EnumVal, EnumDesc)));
338331de23705a719514e37c211f327379688f81b0dChris Lattner    }
33971fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner  }
34071fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner
341331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
342331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(Opt &O) const {
34334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng    for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
34434cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng         i != e; ++i)
345331de23705a719514e37c211f327379688f81b0dChris Lattner      O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
346331de23705a719514e37c211f327379688f81b0dChris Lattner                                     Values[i].second.second);
34771fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner  }
348cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
349cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
350331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
351beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail GlushenkovValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
352a542b4c133de5da974632e9623ee4b426ebb3353Chris Lattner                                           const char *Desc, ...) {
353331de23705a719514e37c211f327379688f81b0dChris Lattner    va_list ValueArgs;
354331de23705a719514e37c211f327379688f81b0dChris Lattner    va_start(ValueArgs, Desc);
355331de23705a719514e37c211f327379688f81b0dChris Lattner    ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs);
356331de23705a719514e37c211f327379688f81b0dChris Lattner    va_end(ValueArgs);
357331de23705a719514e37c211f327379688f81b0dChris Lattner    return Vals;
358331de23705a719514e37c211f327379688f81b0dChris Lattner}
359cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
360cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
361cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
362331de23705a719514e37c211f327379688f81b0dChris Lattner// parser class - Parameterizable parser for different data types.  By default,
363331de23705a719514e37c211f327379688f81b0dChris Lattner// known data types (string, int, bool) have specialized parsers, that do what
364331de23705a719514e37c211f327379688f81b0dChris Lattner// you would expect.  The default parser, used for data types that are not
365331de23705a719514e37c211f327379688f81b0dChris Lattner// built-in, uses a mapping table to map specific options to values, which is
366331de23705a719514e37c211f327379688f81b0dChris Lattner// used, among other things, to handle enum types.
367331de23705a719514e37c211f327379688f81b0dChris Lattner
368331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
369331de23705a719514e37c211f327379688f81b0dChris Lattner// generic_parser_base - This class holds all the non-generic code that we do
370331de23705a719514e37c211f327379688f81b0dChris Lattner// not need replicated for every instance of the generic parser.  This also
371331de23705a719514e37c211f327379688f81b0dChris Lattner// allows us to put stuff into CommandLine.cpp
372cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
373331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct generic_parser_base {
374331de23705a719514e37c211f327379688f81b0dChris Lattner  virtual ~generic_parser_base() {}  // Base class should have virtual-dtor
375331de23705a719514e37c211f327379688f81b0dChris Lattner
376331de23705a719514e37c211f327379688f81b0dChris Lattner  // getNumOptions - Virtual function implemented by generic subclass to
377331de23705a719514e37c211f327379688f81b0dChris Lattner  // indicate how many entries are in Values.
378331de23705a719514e37c211f327379688f81b0dChris Lattner  //
379331de23705a719514e37c211f327379688f81b0dChris Lattner  virtual unsigned getNumOptions() const = 0;
380331de23705a719514e37c211f327379688f81b0dChris Lattner
381331de23705a719514e37c211f327379688f81b0dChris Lattner  // getOption - Return option name N.
382331de23705a719514e37c211f327379688f81b0dChris Lattner  virtual const char *getOption(unsigned N) const = 0;
38363b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
384331de23705a719514e37c211f327379688f81b0dChris Lattner  // getDescription - Return description N
385331de23705a719514e37c211f327379688f81b0dChris Lattner  virtual const char *getDescription(unsigned N) const = 0;
386331de23705a719514e37c211f327379688f81b0dChris Lattner
387331de23705a719514e37c211f327379688f81b0dChris Lattner  // Return the width of the option tag for printing...
38834cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth(const Option &O) const;
389331de23705a719514e37c211f327379688f81b0dChris Lattner
39063b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  // printOptionInfo - Print out information about this option.  The
391331de23705a719514e37c211f327379688f81b0dChris Lattner  // to-be-maintained width is specified.
392331de23705a719514e37c211f327379688f81b0dChris Lattner  //
39334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const;
394331de23705a719514e37c211f327379688f81b0dChris Lattner
395331de23705a719514e37c211f327379688f81b0dChris Lattner  void initialize(Option &O) {
396331de23705a719514e37c211f327379688f81b0dChris Lattner    // All of the modifiers for the option have been processed by now, so the
397331de23705a719514e37c211f327379688f81b0dChris Lattner    // argstr field should be stable, copy it down now.
398331de23705a719514e37c211f327379688f81b0dChris Lattner    //
399331de23705a719514e37c211f327379688f81b0dChris Lattner    hasArgStr = O.hasArgStr();
4009878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  }
401beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
4029878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  void getExtraOptionNames(std::vector<const char*> &OptionNames) {
403331de23705a719514e37c211f327379688f81b0dChris Lattner    // If there has been no argstr specified, that means that we need to add an
404331de23705a719514e37c211f327379688f81b0dChris Lattner    // argument for every possible option.  This ensures that our options are
405331de23705a719514e37c211f327379688f81b0dChris Lattner    // vectored to us.
406331de23705a719514e37c211f327379688f81b0dChris Lattner    if (!hasArgStr)
407331de23705a719514e37c211f327379688f81b0dChris Lattner      for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
4089878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner        OptionNames.push_back(getOption(i));
409cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
410cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
4119878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner
412331de23705a719514e37c211f327379688f81b0dChris Lattner  enum ValueExpected getValueExpectedFlagDefault() const {
413331de23705a719514e37c211f327379688f81b0dChris Lattner    // If there is an ArgStr specified, then we are of the form:
414331de23705a719514e37c211f327379688f81b0dChris Lattner    //
415331de23705a719514e37c211f327379688f81b0dChris Lattner    //    -opt=O2   or   -opt O2  or  -optO2
416331de23705a719514e37c211f327379688f81b0dChris Lattner    //
417331de23705a719514e37c211f327379688f81b0dChris Lattner    // In which case, the value is required.  Otherwise if an arg str has not
418331de23705a719514e37c211f327379688f81b0dChris Lattner    // been specified, we are of the form:
419331de23705a719514e37c211f327379688f81b0dChris Lattner    //
420bc0e998c497446f5448425b3cbd7f8f19a458764Misha Brukman    //    -O2 or O2 or -la (where -l and -a are separate options)
421331de23705a719514e37c211f327379688f81b0dChris Lattner    //
422331de23705a719514e37c211f327379688f81b0dChris Lattner    // If this is the case, we cannot allow a value.
423331de23705a719514e37c211f327379688f81b0dChris Lattner    //
424331de23705a719514e37c211f327379688f81b0dChris Lattner    if (hasArgStr)
425331de23705a719514e37c211f327379688f81b0dChris Lattner      return ValueRequired;
426331de23705a719514e37c211f327379688f81b0dChris Lattner    else
427331de23705a719514e37c211f327379688f81b0dChris Lattner      return ValueDisallowed;
428331de23705a719514e37c211f327379688f81b0dChris Lattner  }
429cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
430af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  // findOption - Return the option number corresponding to the specified
431af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  // argument string.  If the option is not found, getNumOptions() is returned.
432af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  //
433af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  unsigned findOption(const char *Name);
434af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner
435331de23705a719514e37c211f327379688f81b0dChris Lattnerprotected:
436331de23705a719514e37c211f327379688f81b0dChris Lattner  bool hasArgStr;
437331de23705a719514e37c211f327379688f81b0dChris Lattner};
438331de23705a719514e37c211f327379688f81b0dChris Lattner
439331de23705a719514e37c211f327379688f81b0dChris Lattner// Default parser implementation - This implementation depends on having a
440331de23705a719514e37c211f327379688f81b0dChris Lattner// mapping of recognized options to values of some sort.  In addition to this,
441331de23705a719514e37c211f327379688f81b0dChris Lattner// each entry in the mapping also tracks a help message that is printed with the
442331de23705a719514e37c211f327379688f81b0dChris Lattner// command line option for --help.  Because this is a simple mapping parser, the
443331de23705a719514e37c211f327379688f81b0dChris Lattner// data type can be any unsupported type.
444cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
445331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate <class DataType>
446331de23705a719514e37c211f327379688f81b0dChris Lattnerclass parser : public generic_parser_base {
447af7e82184d7d77e426056c7c233e860baeebe80fChris Lattnerprotected:
4483b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  SmallVector<std::pair<const char *,
4493b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner                        std::pair<DataType, const char *> >, 8> Values;
450af7e82184d7d77e426056c7c233e860baeebe80fChris Lattnerpublic:
451d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  typedef DataType parser_data_type;
452331de23705a719514e37c211f327379688f81b0dChris Lattner
453331de23705a719514e37c211f327379688f81b0dChris Lattner  // Implement virtual functions needed by generic_parser_base
454f8063f91227712cc726fca385dd8b88bf6400c84Reid Spencer  unsigned getNumOptions() const { return unsigned(Values.size()); }
455331de23705a719514e37c211f327379688f81b0dChris Lattner  const char *getOption(unsigned N) const { return Values[N].first; }
456331de23705a719514e37c211f327379688f81b0dChris Lattner  const char *getDescription(unsigned N) const {
457331de23705a719514e37c211f327379688f81b0dChris Lattner    return Values[N].second.second;
458cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
459331de23705a719514e37c211f327379688f81b0dChris Lattner
460d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // parse - Return true on error.
46163b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  bool parse(Option &O, const char *ArgName, const std::string &Arg,
462d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner             DataType &V) {
4637f4dd472e35569efefbeffef096c490075e3e824Chris Lattner    std::string ArgVal;
464331de23705a719514e37c211f327379688f81b0dChris Lattner    if (hasArgStr)
465331de23705a719514e37c211f327379688f81b0dChris Lattner      ArgVal = Arg;
466331de23705a719514e37c211f327379688f81b0dChris Lattner    else
467331de23705a719514e37c211f327379688f81b0dChris Lattner      ArgVal = ArgName;
468331de23705a719514e37c211f327379688f81b0dChris Lattner
46934cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng    for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
47034cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng         i != e; ++i)
471331de23705a719514e37c211f327379688f81b0dChris Lattner      if (ArgVal == Values[i].first) {
472d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner        V = Values[i].second.first;
473331de23705a719514e37c211f327379688f81b0dChris Lattner        return false;
474331de23705a719514e37c211f327379688f81b0dChris Lattner      }
475331de23705a719514e37c211f327379688f81b0dChris Lattner
476331de23705a719514e37c211f327379688f81b0dChris Lattner    return O.error(": Cannot find option named '" + ArgVal + "'!");
477331de23705a719514e37c211f327379688f81b0dChris Lattner  }
478cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
4793b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  /// addLiteralOption - Add an entry to the mapping table.
4803b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  ///
481331de23705a719514e37c211f327379688f81b0dChris Lattner  template <class DT>
482331de23705a719514e37c211f327379688f81b0dChris Lattner  void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) {
483af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner    assert(findOption(Name) == Values.size() && "Option already exists!");
4848b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner    Values.push_back(std::make_pair(Name,
4858b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner                             std::make_pair(static_cast<DataType>(V),HelpStr)));
48669d6f1358ca8c442a65fd8d5900f7296fbb2762dChris Lattner    MarkOptionsChanged();
487cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
488af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner
4893b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  /// removeLiteralOption - Remove the specified option.
4903b6078f584d856b3b0fb4dc3c4255502e605be1eChris Lattner  ///
491af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  void removeLiteralOption(const char *Name) {
492af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner    unsigned N = findOption(Name);
493af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner    assert(N != Values.size() && "Option not found!");
494af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner    Values.erase(Values.begin()+N);
495af7e82184d7d77e426056c7c233e860baeebe80fChris Lattner  }
496cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
497cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
498331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
499d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// basic_parser - Super class of parsers to provide boilerplate code
500cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
501d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnerstruct basic_parser_impl {  // non-template implementation of basic_parser<t>
502d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual ~basic_parser_impl() {}
503331de23705a719514e37c211f327379688f81b0dChris Lattner
504331de23705a719514e37c211f327379688f81b0dChris Lattner  enum ValueExpected getValueExpectedFlagDefault() const {
505d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    return ValueRequired;
506cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
50763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
50813d57320bd212483463d4f8992d5787b29eda5dfBill Wendling  void getExtraOptionNames(std::vector<const char*> &) {}
5099878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner
51013d57320bd212483463d4f8992d5787b29eda5dfBill Wendling  void initialize(Option &) {}
51163b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
512331de23705a719514e37c211f327379688f81b0dChris Lattner  // Return the width of the option tag for printing...
51334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  size_t getOptionWidth(const Option &O) const;
51463b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
515d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // printOptionInfo - Print out information about this option.  The
516331de23705a719514e37c211f327379688f81b0dChris Lattner  // to-be-maintained width is specified.
517331de23705a719514e37c211f327379688f81b0dChris Lattner  //
51834cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  void printOptionInfo(const Option &O, size_t GlobalWidth) const;
519d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner
520d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
521d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "value"; }
5227422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
5237422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
5247422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
525d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner};
526d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner
527d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// basic_parser - The real basic parser is just a template wrapper that provides
528d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// a typedef for the provided data type.
529d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//
530d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnertemplate<class DataType>
531d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnerstruct basic_parser : public basic_parser_impl {
532d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  typedef DataType parser_data_type;
533cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
534cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
535331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
536d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// parser<bool>
537cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
538331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<>
5391fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<bool> : public basic_parser<bool> {
540d64e0eb094a108bdcdf51328425904042aa6122bMike Stump  const char *ArgStr;
5411fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
542e8b64106ecf1057c7506d44ec8f64b5c83ee51c7Chris Lattner
543331de23705a719514e37c211f327379688f81b0dChris Lattner  // parse - Return true on error.
544d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
545cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
546d64e0eb094a108bdcdf51328425904042aa6122bMike Stump  template <class Opt>
547d64e0eb094a108bdcdf51328425904042aa6122bMike Stump  void initialize(Opt &O) {
548d64e0eb094a108bdcdf51328425904042aa6122bMike Stump    ArgStr = O.ArgStr;
549d64e0eb094a108bdcdf51328425904042aa6122bMike Stump  }
550d64e0eb094a108bdcdf51328425904042aa6122bMike Stump
551331de23705a719514e37c211f327379688f81b0dChris Lattner  enum ValueExpected getValueExpectedFlagDefault() const {
55263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    return ValueOptional;
553331de23705a719514e37c211f327379688f81b0dChris Lattner  }
554331de23705a719514e37c211f327379688f81b0dChris Lattner
5557422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // getValueName - Do not print =<value> at all.
556d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return 0; }
557beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
5587422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
5597422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
560331de23705a719514e37c211f327379688f81b0dChris Lattner};
561cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
5627422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
5637422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
56481da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen//--------------------------------------------------
56581da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen// parser<boolOrDefault>
56681da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesenenum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
56781da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesentemplate<>
56881da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesenclass parser<boolOrDefault> : public basic_parser<boolOrDefault> {
56981da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesenpublic:
57081da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  // parse - Return true on error.
571beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov  bool parse(Option &O, const char *ArgName, const std::string &Arg,
57281da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen             boolOrDefault &Val);
57381da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen
57481da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  enum ValueExpected getValueExpectedFlagDefault() const {
57581da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen    return ValueOptional;
57681da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  }
57781da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen
57881da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  // getValueName - Do not print =<value> at all.
57981da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  virtual const char *getValueName() const { return 0; }
580beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
58181da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  // An out-of-line virtual method to provide a 'home' for this class.
58281da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen  virtual void anchor();
58381da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen};
58481da02b553b86868637f27b89c6e919c31ed5b51Dale Johannesen
58581da02b553b86868637f27b89c6e919c31ed5b51Dale JohannesenEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
586cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
587331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
588d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// parser<int>
589331de23705a719514e37c211f327379688f81b0dChris Lattner//
590331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<>
5911fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<int> : public basic_parser<int> {
5921fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
593331de23705a719514e37c211f327379688f81b0dChris Lattner  // parse - Return true on error.
594d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  bool parse(Option &O, const char *ArgName, const std::string &Arg, int &Val);
595cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
596d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
597d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "int"; }
5987422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
5997422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6007422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
601d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner};
602cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
6037422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
6047422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
605cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
606d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//--------------------------------------------------
607d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner// parser<unsigned>
608d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner//
609d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattnertemplate<>
6101fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<unsigned> : public basic_parser<unsigned> {
6111fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
612d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner  // parse - Return true on error.
6131e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  bool parse(Option &O, const char *AN, const std::string &Arg, unsigned &Val);
614d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner
615d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner  // getValueName - Overload in subclass to provide a better default value.
616d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner  virtual const char *getValueName() const { return "uint"; }
6177422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
6187422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6197422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
620d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner};
621d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner
6227422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
623d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner
624d2a6fc397ee982936dee7dd5692b1481bcd9fe8fChris Lattner//--------------------------------------------------
625d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// parser<double>
626d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//
627d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnertemplate<>
6281fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<double> : public basic_parser<double> {
6291fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
630d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // parse - Return true on error.
631d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  bool parse(Option &O, const char *AN, const std::string &Arg, double &Val);
632cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
633d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
634d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "number"; }
6357422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
6367422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6377422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
638cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
639cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
6407422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
641331de23705a719514e37c211f327379688f81b0dChris Lattner
642d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//--------------------------------------------------
643d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner// parser<float>
644d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner//
645d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattnertemplate<>
6461fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<float> : public basic_parser<float> {
6471fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
648d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // parse - Return true on error.
649d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  bool parse(Option &O, const char *AN, const std::string &Arg, float &Val);
650d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner
651d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
652d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "number"; }
6537422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
6547422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6557422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
656d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner};
657331de23705a719514e37c211f327379688f81b0dChris Lattner
6587422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
659331de23705a719514e37c211f327379688f81b0dChris Lattner
660331de23705a719514e37c211f327379688f81b0dChris Lattner//--------------------------------------------------
6617f4dd472e35569efefbeffef096c490075e3e824Chris Lattner// parser<std::string>
662331de23705a719514e37c211f327379688f81b0dChris Lattner//
663331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<>
6641fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass parser<std::string> : public basic_parser<std::string> {
6651fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
666331de23705a719514e37c211f327379688f81b0dChris Lattner  // parse - Return true on error.
66713d57320bd212483463d4f8992d5787b29eda5dfBill Wendling  bool parse(Option &, const char *, const std::string &Arg,
668d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner             std::string &Value) {
669d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    Value = Arg;
670331de23705a719514e37c211f327379688f81b0dChris Lattner    return false;
671331de23705a719514e37c211f327379688f81b0dChris Lattner  }
672331de23705a719514e37c211f327379688f81b0dChris Lattner
673d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  // getValueName - Overload in subclass to provide a better default value.
674d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner  virtual const char *getValueName() const { return "string"; }
6757422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
6767422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  // An out-of-line virtual method to provide a 'home' for this class.
6777422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner  virtual void anchor();
678331de23705a719514e37c211f327379688f81b0dChris Lattner};
679331de23705a719514e37c211f327379688f81b0dChris Lattner
6807422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
6817422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
682b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling//--------------------------------------------------
683b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling// parser<char>
684b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling//
685b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendlingtemplate<>
686b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendlingclass parser<char> : public basic_parser<char> {
687b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendlingpublic:
688b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling  // parse - Return true on error.
689b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling  bool parse(Option &, const char *, const std::string &Arg,
690b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling             char &Value) {
691b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling    Value = Arg[0];
692b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling    return false;
693b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling  }
694b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling
695b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling  // getValueName - Overload in subclass to provide a better default value.
696b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling  virtual const char *getValueName() const { return "char"; }
697b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling
698b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling  // An out-of-line virtual method to provide a 'home' for this class.
699b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling  virtual void anchor();
700b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling};
701b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling
702b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill WendlingEXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
703b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill Wendling
704331de23705a719514e37c211f327379688f81b0dChris Lattner//===----------------------------------------------------------------------===//
705331de23705a719514e37c211f327379688f81b0dChris Lattner// applicator class - This class is used because we must use partial
706331de23705a719514e37c211f327379688f81b0dChris Lattner// specialization to handle literal string arguments specially (const char* does
707331de23705a719514e37c211f327379688f81b0dChris Lattner// not correctly respond to the apply method).  Because the syntax to use this
708331de23705a719514e37c211f327379688f81b0dChris Lattner// is a pain, we have the 'apply' method below to handle the nastiness...
709331de23705a719514e37c211f327379688f81b0dChris Lattner//
710331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Mod> struct applicator {
711331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
712331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(const Mod &M, Opt &O) { M.apply(O); }
713331de23705a719514e37c211f327379688f81b0dChris Lattner};
714331de23705a719514e37c211f327379688f81b0dChris Lattner
715331de23705a719514e37c211f327379688f81b0dChris Lattner// Handle const char* as a special case...
716331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<unsigned n> struct applicator<char[n]> {
717331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
718331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
719331de23705a719514e37c211f327379688f81b0dChris Lattner};
7204042332d4a8ba8e4d2b3a6d87a3af81fc73a0f98Chris Lattnertemplate<unsigned n> struct applicator<const char[n]> {
7214042332d4a8ba8e4d2b3a6d87a3af81fc73a0f98Chris Lattner  template<class Opt>
7224042332d4a8ba8e4d2b3a6d87a3af81fc73a0f98Chris Lattner  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
7234042332d4a8ba8e4d2b3a6d87a3af81fc73a0f98Chris Lattner};
724331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<> struct applicator<const char*> {
725331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class Opt>
726331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
727331de23705a719514e37c211f327379688f81b0dChris Lattner};
728331de23705a719514e37c211f327379688f81b0dChris Lattner
729dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukmantemplate<> struct applicator<NumOccurrences> {
730dd6cb6a43b78732f1a136583ccca4e715bae7d71Misha Brukman  static void opt(NumOccurrences NO, Option &O) { O.setNumOccurrencesFlag(NO); }
731331de23705a719514e37c211f327379688f81b0dChris Lattner};
732331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<> struct applicator<ValueExpected> {
733331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); }
734331de23705a719514e37c211f327379688f81b0dChris Lattner};
735331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<> struct applicator<OptionHidden> {
736331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); }
737331de23705a719514e37c211f327379688f81b0dChris Lattner};
738331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<> struct applicator<FormattingFlags> {
739331de23705a719514e37c211f327379688f81b0dChris Lattner  static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); }
740331de23705a719514e37c211f327379688f81b0dChris Lattner};
741b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattnertemplate<> struct applicator<MiscFlags> {
742b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner  static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); }
743b3b729b69b311468025ff1e25b3499fcbd83454aChris Lattner};
744331de23705a719514e37c211f327379688f81b0dChris Lattner
745331de23705a719514e37c211f327379688f81b0dChris Lattner// apply method - Apply a modifier to an option in a type safe way.
746331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class Mod, class Opt>
747331de23705a719514e37c211f327379688f81b0dChris Lattnervoid apply(const Mod &M, Opt *O) {
748331de23705a719514e37c211f327379688f81b0dChris Lattner  applicator<Mod>::opt(M, *O);
749331de23705a719514e37c211f327379688f81b0dChris Lattner}
750331de23705a719514e37c211f327379688f81b0dChris Lattner
751331de23705a719514e37c211f327379688f81b0dChris Lattner
752331de23705a719514e37c211f327379688f81b0dChris Lattner//===----------------------------------------------------------------------===//
753331de23705a719514e37c211f327379688f81b0dChris Lattner// opt_storage class
754331de23705a719514e37c211f327379688f81b0dChris Lattner
755331de23705a719514e37c211f327379688f81b0dChris Lattner// Default storage class definition: external storage.  This implementation
756331de23705a719514e37c211f327379688f81b0dChris Lattner// assumes the user will specify a variable to store the data into with the
757331de23705a719514e37c211f327379688f81b0dChris Lattner// cl::location(x) modifier.
758331de23705a719514e37c211f327379688f81b0dChris Lattner//
759331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType, bool ExternalStorage, bool isClass>
760331de23705a719514e37c211f327379688f81b0dChris Lattnerclass opt_storage {
761331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType *Location;   // Where to store the object...
762331de23705a719514e37c211f327379688f81b0dChris Lattner
76331fd5a571eb8048a1084dd8e20a49dd0785de11aBill Wendling  void check() const {
764331de23705a719514e37c211f327379688f81b0dChris Lattner    assert(Location != 0 && "cl::location(...) not specified for a command "
7653c7eb1f2ea231c046367023576311fbc4b1270e3Chris Lattner           "line option with external storage, "
7663c7eb1f2ea231c046367023576311fbc4b1270e3Chris Lattner           "or cl::init specified before cl::location()!!");
767331de23705a719514e37c211f327379688f81b0dChris Lattner  }
768cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
769331de23705a719514e37c211f327379688f81b0dChris Lattner  opt_storage() : Location(0) {}
770331de23705a719514e37c211f327379688f81b0dChris Lattner
771331de23705a719514e37c211f327379688f81b0dChris Lattner  bool setLocation(Option &O, DataType &L) {
772331de23705a719514e37c211f327379688f81b0dChris Lattner    if (Location)
773331de23705a719514e37c211f327379688f81b0dChris Lattner      return O.error(": cl::location(x) specified more than once!");
774331de23705a719514e37c211f327379688f81b0dChris Lattner    Location = &L;
775331de23705a719514e37c211f327379688f81b0dChris Lattner    return false;
776cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
777cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
778331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
779331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValue(const T &V) {
780331de23705a719514e37c211f327379688f81b0dChris Lattner    check();
781331de23705a719514e37c211f327379688f81b0dChris Lattner    *Location = V;
78271fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner  }
78371fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner
784331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType &getValue() { check(); return *Location; }
785331de23705a719514e37c211f327379688f81b0dChris Lattner  const DataType &getValue() const { check(); return *Location; }
786331de23705a719514e37c211f327379688f81b0dChris Lattner};
787331de23705a719514e37c211f327379688f81b0dChris Lattner
788331de23705a719514e37c211f327379688f81b0dChris Lattner
789331de23705a719514e37c211f327379688f81b0dChris Lattner// Define how to hold a class type object, such as a string.  Since we can
790331de23705a719514e37c211f327379688f81b0dChris Lattner// inherit from a class, we do so.  This makes us exactly compatible with the
791331de23705a719514e37c211f327379688f81b0dChris Lattner// object in all cases that it is used.
792331de23705a719514e37c211f327379688f81b0dChris Lattner//
793331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
7941fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass opt_storage<DataType,false,true> : public DataType {
7951fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
796331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
797331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValue(const T &V) { DataType::operator=(V); }
798331de23705a719514e37c211f327379688f81b0dChris Lattner
799331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType &getValue() { return *this; }
800331de23705a719514e37c211f327379688f81b0dChris Lattner  const DataType &getValue() const { return *this; }
801331de23705a719514e37c211f327379688f81b0dChris Lattner};
802331de23705a719514e37c211f327379688f81b0dChris Lattner
803331de23705a719514e37c211f327379688f81b0dChris Lattner// Define a partial specialization to handle things we cannot inherit from.  In
804331de23705a719514e37c211f327379688f81b0dChris Lattner// this case, we store an instance through containment, and overload operators
805331de23705a719514e37c211f327379688f81b0dChris Lattner// to get at the value.
806331de23705a719514e37c211f327379688f81b0dChris Lattner//
807331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
8081fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass opt_storage<DataType, false, false> {
8091fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
810331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType Value;
811331de23705a719514e37c211f327379688f81b0dChris Lattner
812331de23705a719514e37c211f327379688f81b0dChris Lattner  // Make sure we initialize the value with the default constructor for the
813331de23705a719514e37c211f327379688f81b0dChris Lattner  // type.
814331de23705a719514e37c211f327379688f81b0dChris Lattner  opt_storage() : Value(DataType()) {}
815331de23705a719514e37c211f327379688f81b0dChris Lattner
816331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
817331de23705a719514e37c211f327379688f81b0dChris Lattner  void setValue(const T &V) { Value = V; }
818331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType &getValue() { return Value; }
819331de23705a719514e37c211f327379688f81b0dChris Lattner  DataType getValue() const { return Value; }
8206a4dd24a995072c9c6f1ae45f19f94010d8389fbChris Lattner
8216a4dd24a995072c9c6f1ae45f19f94010d8389fbChris Lattner  // If the datatype is a pointer, support -> on it.
8226a4dd24a995072c9c6f1ae45f19f94010d8389fbChris Lattner  DataType operator->() const { return Value; }
823cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
824cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
825cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
826cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
827331de23705a719514e37c211f327379688f81b0dChris Lattner// opt - A scalar command line option.
828cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
829331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate <class DataType, bool ExternalStorage = false,
830331de23705a719514e37c211f327379688f81b0dChris Lattner          class ParserClass = parser<DataType> >
83163b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukmanclass opt : public Option,
832331de23705a719514e37c211f327379688f81b0dChris Lattner            public opt_storage<DataType, ExternalStorage,
8337b3d73b7ecbecf423c3766e596b6086767444363Chris Lattner                               is_class<DataType>::value> {
834331de23705a719514e37c211f327379688f81b0dChris Lattner  ParserClass Parser;
835331de23705a719514e37c211f327379688f81b0dChris Lattner
83663b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  virtual bool handleOccurrence(unsigned pos, const char *ArgName,
8371e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                                const std::string &Arg) {
8389eb59ec548b861d6ede05b4e6dc22aabf645e665Jeff Cohen    typename ParserClass::parser_data_type Val =
839e6ad5ea996673f76b62e495d268c8bf7c9b0d205Chris Lattner       typename ParserClass::parser_data_type();
840d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    if (Parser.parse(*this, ArgName, Arg, Val))
841d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner      return true;                            // Parse error!
84248fe63526e35ddaee7e98879596a569911f41319Sebastian Redl    this->setValue(Val);
84348fe63526e35ddaee7e98879596a569911f41319Sebastian Redl    this->setPosition(pos);
844d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    return false;
845331de23705a719514e37c211f327379688f81b0dChris Lattner  }
846331de23705a719514e37c211f327379688f81b0dChris Lattner
847cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  virtual enum ValueExpected getValueExpectedFlagDefault() const {
848331de23705a719514e37c211f327379688f81b0dChris Lattner    return Parser.getValueExpectedFlagDefault();
849cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
8509878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
8519878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    return Parser.getExtraOptionNames(OptionNames);
8529878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  }
853cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
854331de23705a719514e37c211f327379688f81b0dChris Lattner  // Forward printing stuff to the parser...
85534cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
85634cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const {
857331de23705a719514e37c211f327379688f81b0dChris Lattner    Parser.printOptionInfo(*this, GlobalWidth);
858331de23705a719514e37c211f327379688f81b0dChris Lattner  }
859cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
860331de23705a719514e37c211f327379688f81b0dChris Lattner  void done() {
8619878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    addArgument();
862331de23705a719514e37c211f327379688f81b0dChris Lattner    Parser.initialize(*this);
863331de23705a719514e37c211f327379688f81b0dChris Lattner  }
864331de23705a719514e37c211f327379688f81b0dChris Lattnerpublic:
865331de23705a719514e37c211f327379688f81b0dChris Lattner  // setInitialValue - Used by the cl::init modifier...
86631a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner  void setInitialValue(const DataType &V) { this->setValue(V); }
867331de23705a719514e37c211f327379688f81b0dChris Lattner
868331de23705a719514e37c211f327379688f81b0dChris Lattner  ParserClass &getParser() { return Parser; }
869331de23705a719514e37c211f327379688f81b0dChris Lattner
87031a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner  operator DataType() const { return this->getValue(); }
871331de23705a719514e37c211f327379688f81b0dChris Lattner
872331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
87331a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner  DataType &operator=(const T &Val) {
87431a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner    this->setValue(Val);
87531a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner    return this->getValue();
87631a6db0f2c94852e6dba7ca1e7f8df395cb3ad05Chris Lattner  }
877331de23705a719514e37c211f327379688f81b0dChris Lattner
878331de23705a719514e37c211f327379688f81b0dChris Lattner  // One option...
879331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t>
880cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit opt(const M0t &M0) : Option(Optional | NotHidden) {
881331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this);
882331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
883331de23705a719514e37c211f327379688f81b0dChris Lattner  }
884331de23705a719514e37c211f327379688f81b0dChris Lattner
885331de23705a719514e37c211f327379688f81b0dChris Lattner  // Two options...
886331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t>
887f6143ef556ed01311d2043d38421302479f7866cChris Lattner  opt(const M0t &M0, const M1t &M1) : Option(Optional | NotHidden) {
888331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this);
889331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
890331de23705a719514e37c211f327379688f81b0dChris Lattner  }
891331de23705a719514e37c211f327379688f81b0dChris Lattner
892331de23705a719514e37c211f327379688f81b0dChris Lattner  // Three options...
893331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t>
894f6143ef556ed01311d2043d38421302479f7866cChris Lattner  opt(const M0t &M0, const M1t &M1,
895f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M2t &M2) : Option(Optional | NotHidden) {
896331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this);
897331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
898331de23705a719514e37c211f327379688f81b0dChris Lattner  }
899331de23705a719514e37c211f327379688f81b0dChris Lattner  // Four options...
900331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t>
9016e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2,
902f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M3t &M3) : Option(Optional | NotHidden) {
903331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
904331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
905331de23705a719514e37c211f327379688f81b0dChris Lattner  }
906331de23705a719514e37c211f327379688f81b0dChris Lattner  // Five options...
907331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t, class M4t>
908331de23705a719514e37c211f327379688f81b0dChris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
909f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M4t &M4) : Option(Optional | NotHidden) {
910331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
911331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this);
912331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
913331de23705a719514e37c211f327379688f81b0dChris Lattner  }
914331de23705a719514e37c211f327379688f81b0dChris Lattner  // Six options...
915331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
916331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t>
917331de23705a719514e37c211f327379688f81b0dChris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
918f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M4t &M4, const M5t &M5) : Option(Optional | NotHidden) {
919331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
920331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this);
921331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
922331de23705a719514e37c211f327379688f81b0dChris Lattner  }
923331de23705a719514e37c211f327379688f81b0dChris Lattner  // Seven options...
924331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
925331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t, class M6t>
926331de23705a719514e37c211f327379688f81b0dChris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
927f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M4t &M4, const M5t &M5,
928f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M6t &M6) : Option(Optional | NotHidden) {
929331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
930331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this); apply(M6, this);
931331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
932331de23705a719514e37c211f327379688f81b0dChris Lattner  }
933331de23705a719514e37c211f327379688f81b0dChris Lattner  // Eight options...
934331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
935331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t, class M6t, class M7t>
936331de23705a719514e37c211f327379688f81b0dChris Lattner  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
9376e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner      const M4t &M4, const M5t &M5, const M6t &M6,
938f6143ef556ed01311d2043d38421302479f7866cChris Lattner      const M7t &M7) : Option(Optional | NotHidden) {
939331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
940331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
941331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
942331de23705a719514e37c211f327379688f81b0dChris Lattner  }
943cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
944cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
9457422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
9467422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
9477422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
948b587f9662a7b6f00f9ce48ddf2dea1a4fb18a6dbBill WendlingEXTERN_TEMPLATE_INSTANTIATION(class opt<char>);
9497422a761008ef63152417c5e69ddc31252fb6b10Chris LattnerEXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
9507422a761008ef63152417c5e69ddc31252fb6b10Chris Lattner
951331de23705a719514e37c211f327379688f81b0dChris Lattner//===----------------------------------------------------------------------===//
952331de23705a719514e37c211f327379688f81b0dChris Lattner// list_storage class
953331de23705a719514e37c211f327379688f81b0dChris Lattner
954331de23705a719514e37c211f327379688f81b0dChris Lattner// Default storage class definition: external storage.  This implementation
955331de23705a719514e37c211f327379688f81b0dChris Lattner// assumes the user will specify a variable to store the data into with the
956331de23705a719514e37c211f327379688f81b0dChris Lattner// cl::location(x) modifier.
957331de23705a719514e37c211f327379688f81b0dChris Lattner//
958331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType, class StorageClass>
959331de23705a719514e37c211f327379688f81b0dChris Lattnerclass list_storage {
960331de23705a719514e37c211f327379688f81b0dChris Lattner  StorageClass *Location;   // Where to store the object...
96171fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner
962cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
963331de23705a719514e37c211f327379688f81b0dChris Lattner  list_storage() : Location(0) {}
964331de23705a719514e37c211f327379688f81b0dChris Lattner
965331de23705a719514e37c211f327379688f81b0dChris Lattner  bool setLocation(Option &O, StorageClass &L) {
966331de23705a719514e37c211f327379688f81b0dChris Lattner    if (Location)
967331de23705a719514e37c211f327379688f81b0dChris Lattner      return O.error(": cl::location(x) specified more than once!");
968331de23705a719514e37c211f327379688f81b0dChris Lattner    Location = &L;
969331de23705a719514e37c211f327379688f81b0dChris Lattner    return false;
97071fb71628ab3f5280a7f4602f52ba365bca31f29Chris Lattner  }
971331de23705a719514e37c211f327379688f81b0dChris Lattner
972331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
973331de23705a719514e37c211f327379688f81b0dChris Lattner  void addValue(const T &V) {
974331de23705a719514e37c211f327379688f81b0dChris Lattner    assert(Location != 0 && "cl::location(...) not specified for a command "
975331de23705a719514e37c211f327379688f81b0dChris Lattner           "line option with external storage!");
976331de23705a719514e37c211f327379688f81b0dChris Lattner    Location->push_back(V);
977cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
978331de23705a719514e37c211f327379688f81b0dChris Lattner};
979331de23705a719514e37c211f327379688f81b0dChris Lattner
980331de23705a719514e37c211f327379688f81b0dChris Lattner
981331de23705a719514e37c211f327379688f81b0dChris Lattner// Define how to hold a class type object, such as a string.  Since we can
982331de23705a719514e37c211f327379688f81b0dChris Lattner// inherit from a class, we do so.  This makes us exactly compatible with the
983331de23705a719514e37c211f327379688f81b0dChris Lattner// object in all cases that it is used.
984331de23705a719514e37c211f327379688f81b0dChris Lattner//
985331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate<class DataType>
9861fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerclass list_storage<DataType, bool> : public std::vector<DataType> {
9871fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
988331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class T>
989331de23705a719514e37c211f327379688f81b0dChris Lattner  void addValue(const T &V) { push_back(V); }
990cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
991cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
992cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
993cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//===----------------------------------------------------------------------===//
994331de23705a719514e37c211f327379688f81b0dChris Lattner// list - A list of command line options.
995cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner//
996331de23705a719514e37c211f327379688f81b0dChris Lattnertemplate <class DataType, class Storage = bool,
997331de23705a719514e37c211f327379688f81b0dChris Lattner          class ParserClass = parser<DataType> >
998331de23705a719514e37c211f327379688f81b0dChris Lattnerclass list : public Option, public list_storage<DataType, Storage> {
9991e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  std::vector<unsigned> Positions;
1000331de23705a719514e37c211f327379688f81b0dChris Lattner  ParserClass Parser;
1001331de23705a719514e37c211f327379688f81b0dChris Lattner
1002cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  virtual enum ValueExpected getValueExpectedFlagDefault() const {
1003331de23705a719514e37c211f327379688f81b0dChris Lattner    return Parser.getValueExpectedFlagDefault();
1004cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner  }
10059878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
10069878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    return Parser.getExtraOptionNames(OptionNames);
10079878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  }
1008beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
100963b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  virtual bool handleOccurrence(unsigned pos, const char *ArgName,
10101e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                                const std::string &Arg) {
10118a207c16d2eb44ebcf94b13b0db047e46b7b0d30Reid Spencer    typename ParserClass::parser_data_type Val =
10128a207c16d2eb44ebcf94b13b0db047e46b7b0d30Reid Spencer      typename ParserClass::parser_data_type();
1013d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    if (Parser.parse(*this, ArgName, Arg, Val))
1014d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner      return true;  // Parse Error!
1015d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    addValue(Val);
10161e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    setPosition(pos);
10171e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    Positions.push_back(pos);
1018d23a35bc2b6db436b1d396872d26b49420890c3bChris Lattner    return false;
1019331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1020cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
1021331de23705a719514e37c211f327379688f81b0dChris Lattner  // Forward printing stuff to the parser...
102234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
102334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const {
1024331de23705a719514e37c211f327379688f81b0dChris Lattner    Parser.printOptionInfo(*this, GlobalWidth);
1025331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1026cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
1027331de23705a719514e37c211f327379688f81b0dChris Lattner  void done() {
10289878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    addArgument();
1029331de23705a719514e37c211f327379688f81b0dChris Lattner    Parser.initialize(*this);
1030331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1031cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
1032331de23705a719514e37c211f327379688f81b0dChris Lattner  ParserClass &getParser() { return Parser; }
1033331de23705a719514e37c211f327379688f81b0dChris Lattner
103463b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  unsigned getPosition(unsigned optnum) const {
10351e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    assert(optnum < this->size() && "Invalid option index");
103663b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    return Positions[optnum];
10371e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer  }
10381e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer
10397059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  void setNumAdditionalVals(unsigned n) {
10407059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov    Option::setNumAdditionalVals(n);
10417059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  }
10427059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov
1043331de23705a719514e37c211f327379688f81b0dChris Lattner  // One option...
1044331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t>
1045cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit list(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
1046331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this);
1047331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1048331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1049331de23705a719514e37c211f327379688f81b0dChris Lattner  // Two options...
1050331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t>
1051f6143ef556ed01311d2043d38421302479f7866cChris Lattner  list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
1052331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this);
1053331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1054331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1055331de23705a719514e37c211f327379688f81b0dChris Lattner  // Three options...
1056331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t>
1057f6143ef556ed01311d2043d38421302479f7866cChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2)
1058f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1059331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this);
1060331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1061331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1062331de23705a719514e37c211f327379688f81b0dChris Lattner  // Four options...
1063331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t>
10646e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
1065f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1066331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1067331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1068331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1069331de23705a719514e37c211f327379688f81b0dChris Lattner  // Five options...
1070331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t, class M4t>
1071331de23705a719514e37c211f327379688f81b0dChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1072f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4) : Option(ZeroOrMore | NotHidden) {
1073331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1074331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this);
1075331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1076331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1077331de23705a719514e37c211f327379688f81b0dChris Lattner  // Six options...
1078331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
1079331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t>
1080331de23705a719514e37c211f327379688f81b0dChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1081f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
1082331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1083331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this);
1084331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1085331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1086331de23705a719514e37c211f327379688f81b0dChris Lattner  // Seven options...
1087331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
1088331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t, class M6t>
1089331de23705a719514e37c211f327379688f81b0dChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1090f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4, const M5t &M5, const M6t &M6)
1091f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1092331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1093331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this); apply(M6, this);
1094331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1095331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1096331de23705a719514e37c211f327379688f81b0dChris Lattner  // Eight options...
1097331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t,
1098331de23705a719514e37c211f327379688f81b0dChris Lattner           class M4t, class M5t, class M6t, class M7t>
1099331de23705a719514e37c211f327379688f81b0dChris Lattner  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
11006e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner       const M4t &M4, const M5t &M5, const M6t &M6,
1101f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M7t &M7) : Option(ZeroOrMore | NotHidden) {
1102331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1103331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
1104331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1105331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1106cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
1107cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
11087059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov// multi_arg - Modifier to set the number of additional values.
11097059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkovstruct multi_val {
11107059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  unsigned AdditionalVals;
11117059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  explicit multi_val(unsigned N) : AdditionalVals(N) {}
11127059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov
11137059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  template <typename D, typename S, typename P>
11147059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov  void apply(list<D, S, P> &L) const { L.setNumAdditionalVals(AdditionalVals); }
11157059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov};
11167059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov
11177059d47a6e1a378232dce3e47b51434dec0ea608Mikhail Glushenkov
1118331de23705a719514e37c211f327379688f81b0dChris Lattner//===----------------------------------------------------------------------===//
1119eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// bits_storage class
1120eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1121eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// Default storage class definition: external storage.  This implementation
1122eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// assumes the user will specify a variable to store the data into with the
1123eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// cl::location(x) modifier.
1124eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//
1125eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeytemplate<class DataType, class StorageClass>
1126eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeyclass bits_storage {
1127a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  unsigned *Location;   // Where to store the bits...
1128beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1129eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1130eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  static unsigned Bit(const T &V) {
11313e41da29fb74a4f2a43a1539b612b2fb11bef375Reid Spencer    unsigned BitPos = reinterpret_cast<unsigned>(V);
1132de551f91d8816632a76a065084caab9fab6aacffDan Gohman    assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
1133eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey          "enum exceeds width of bit vector!");
1134eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return 1 << BitPos;
1135eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1136eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1137eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeypublic:
1138eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits_storage() : Location(0) {}
1139eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1140a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  bool setLocation(Option &O, unsigned &L) {
1141eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    if (Location)
1142eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey      return O.error(": cl::location(x) specified more than once!");
1143eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Location = &L;
1144eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return false;
1145eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1146eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1147eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1148eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  void addValue(const T &V) {
1149eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    assert(Location != 0 && "cl::location(...) not specified for a command "
1150eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey           "line option with external storage!");
1151eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    *Location |= Bit(V);
1152eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1153beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1154a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  unsigned getBits() { return *Location; }
1155beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1156eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1157eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bool isSet(const T &V) {
1158eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return (*Location & Bit(V)) != 0;
1159eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1160eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey};
1161eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1162eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1163beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov// Define how to hold bits.  Since we can inherit from a class, we do so.
1164eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// This makes us exactly compatible with the bits in all cases that it is used.
1165eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//
1166eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeytemplate<class DataType>
1167eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeyclass bits_storage<DataType, bool> {
1168a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  unsigned Bits;   // Where to store the bits...
1169beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1170eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1171eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  static unsigned Bit(const T &V) {
11723e41da29fb74a4f2a43a1539b612b2fb11bef375Reid Spencer    unsigned BitPos = reinterpret_cast<unsigned>(V);
1173de551f91d8816632a76a065084caab9fab6aacffDan Gohman    assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
1174eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey          "enum exceeds width of bit vector!");
1175eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return 1 << BitPos;
1176eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1177beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1178eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeypublic:
1179eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1180eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  void addValue(const T &V) {
1181eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Bits |=  Bit(V);
1182eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1183beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1184a2860651e8567fe8d8af3968955845b0755f50d0Jim Laskey  unsigned getBits() { return Bits; }
1185beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1186eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class T>
1187eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bool isSet(const T &V) {
1188eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return (Bits & Bit(V)) != 0;
1189eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1190eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey};
1191eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1192eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1193eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//===----------------------------------------------------------------------===//
1194eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey// bits - A bit vector of command options.
1195eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//
1196eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeytemplate <class DataType, class Storage = bool,
1197eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey          class ParserClass = parser<DataType> >
1198eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeyclass bits : public Option, public bits_storage<DataType, Storage> {
1199eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  std::vector<unsigned> Positions;
1200eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  ParserClass Parser;
1201eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1202eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  virtual enum ValueExpected getValueExpectedFlagDefault() const {
1203eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return Parser.getValueExpectedFlagDefault();
1204eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
12059878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
12069878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    return Parser.getExtraOptionNames(OptionNames);
12079878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner  }
1208beb4d8293d5311c4581fd3d914f865e358af53a5Mikhail Glushenkov
1209eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  virtual bool handleOccurrence(unsigned pos, const char *ArgName,
1210eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey                                const std::string &Arg) {
1211eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    typename ParserClass::parser_data_type Val =
1212eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey      typename ParserClass::parser_data_type();
1213eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    if (Parser.parse(*this, ArgName, Arg, Val))
1214eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey      return true;  // Parse Error!
1215eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    addValue(Val);
1216eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    setPosition(pos);
1217eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Positions.push_back(pos);
1218eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return false;
1219eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1220eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1221eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Forward printing stuff to the parser...
122234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
122334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const {
1224eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Parser.printOptionInfo(*this, GlobalWidth);
1225eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1226eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1227eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  void done() {
12289878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner    addArgument();
1229eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    Parser.initialize(*this);
1230eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1231eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskeypublic:
1232eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  ParserClass &getParser() { return Parser; }
1233eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1234eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  unsigned getPosition(unsigned optnum) const {
1235eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    assert(optnum < this->size() && "Invalid option index");
1236eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    return Positions[optnum];
1237eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1238eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1239eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // One option...
1240eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t>
1241cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit bits(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
1242eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this);
1243eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1244eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1245eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Two options...
1246eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t>
1247f6143ef556ed01311d2043d38421302479f7866cChris Lattner  bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
1248eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this);
1249eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1250eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1251eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Three options...
1252eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t>
1253f6143ef556ed01311d2043d38421302479f7866cChris Lattner  bits(const M0t &M0, const M1t &M1, const M2t &M2)
1254f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1255eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this);
1256eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1257eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1258eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Four options...
1259eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t>
1260f6143ef556ed01311d2043d38421302479f7866cChris Lattner  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
1261f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1262eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1263eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1264eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1265eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Five options...
1266eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t, class M4t>
1267eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1268f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4) : Option(ZeroOrMore | NotHidden) {
1269eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1270eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M4, this);
1271eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1272eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1273eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Six options...
1274eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t,
1275eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey           class M4t, class M5t>
1276eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1277f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
1278eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1279eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M4, this); apply(M5, this);
1280eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1281eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1282eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Seven options...
1283eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t,
1284eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey           class M4t, class M5t, class M6t>
1285eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
1286f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M4t &M4, const M5t &M5, const M6t &M6)
1287f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(ZeroOrMore | NotHidden) {
1288eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1289eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M4, this); apply(M5, this); apply(M6, this);
1290eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1291eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1292eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  // Eight options...
1293eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  template<class M0t, class M1t, class M2t, class M3t,
1294eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey           class M4t, class M5t, class M6t, class M7t>
1295eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
12966e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner       const M4t &M4, const M5t &M5, const M6t &M6,
1297f6143ef556ed01311d2043d38421302479f7866cChris Lattner       const M7t &M7) : Option(ZeroOrMore | NotHidden) {
1298eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1299eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
1300eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey    done();
1301eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey  }
1302eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey};
1303eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey
1304eb0c36d173591f24f29eeb1e9ec7d174b140d511Jim Laskey//===----------------------------------------------------------------------===//
1305331de23705a719514e37c211f327379688f81b0dChris Lattner// Aliased command line option (alias this name to a preexisting name)
1306331de23705a719514e37c211f327379688f81b0dChris Lattner//
1307331de23705a719514e37c211f327379688f81b0dChris Lattner
1308331de23705a719514e37c211f327379688f81b0dChris Lattnerclass alias : public Option {
1309331de23705a719514e37c211f327379688f81b0dChris Lattner  Option *AliasFor;
13100008f654bf08dc631a1abaa175dd08f1fd1be75eSteve Naroff  virtual bool handleOccurrence(unsigned pos, const char * /*ArgName*/,
13111e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer                                const std::string &Arg) {
13121e13fd23d34e53b63cb08c0fe54f0857757ec200Reid Spencer    return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
1313331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1314331de23705a719514e37c211f327379688f81b0dChris Lattner  // Handle printing stuff...
131534cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual size_t getOptionWidth() const;
131634cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  virtual void printOptionInfo(size_t GlobalWidth) const;
1317331de23705a719514e37c211f327379688f81b0dChris Lattner
1318331de23705a719514e37c211f327379688f81b0dChris Lattner  void done() {
1319331de23705a719514e37c211f327379688f81b0dChris Lattner    if (!hasArgStr())
1320331de23705a719514e37c211f327379688f81b0dChris Lattner      error(": cl::alias must have argument name specified!");
1321331de23705a719514e37c211f327379688f81b0dChris Lattner    if (AliasFor == 0)
1322331de23705a719514e37c211f327379688f81b0dChris Lattner      error(": cl::alias must have an cl::aliasopt(option) specified!");
13239878d6ae3a535e421f69e0c08e27b259ad1bdbdcChris Lattner      addArgument();
1324331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1325cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattnerpublic:
1326331de23705a719514e37c211f327379688f81b0dChris Lattner  void setAliasFor(Option &O) {
1327331de23705a719514e37c211f327379688f81b0dChris Lattner    if (AliasFor)
1328331de23705a719514e37c211f327379688f81b0dChris Lattner      error(": cl::alias must only have one cl::aliasopt(...) specified!");
1329331de23705a719514e37c211f327379688f81b0dChris Lattner    AliasFor = &O;
1330331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1331331de23705a719514e37c211f327379688f81b0dChris Lattner
1332331de23705a719514e37c211f327379688f81b0dChris Lattner  // One option...
1333331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t>
1334cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit alias(const M0t &M0) : Option(Optional | Hidden), AliasFor(0) {
1335331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this);
1336331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1337331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1338331de23705a719514e37c211f327379688f81b0dChris Lattner  // Two options...
1339331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t>
1340f6143ef556ed01311d2043d38421302479f7866cChris Lattner  alias(const M0t &M0, const M1t &M1) : Option(Optional | Hidden), AliasFor(0) {
1341331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this);
1342331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1343331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1344331de23705a719514e37c211f327379688f81b0dChris Lattner  // Three options...
1345331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t>
13466e18fa0e1c230ac1b551c34214dac82510974681Chris Lattner  alias(const M0t &M0, const M1t &M1, const M2t &M2)
1347f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(Optional | Hidden), AliasFor(0) {
1348331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this);
1349331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1350331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1351331de23705a719514e37c211f327379688f81b0dChris Lattner  // Four options...
1352331de23705a719514e37c211f327379688f81b0dChris Lattner  template<class M0t, class M1t, class M2t, class M3t>
1353331de23705a719514e37c211f327379688f81b0dChris Lattner  alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
1354f6143ef556ed01311d2043d38421302479f7866cChris Lattner    : Option(Optional | Hidden), AliasFor(0) {
1355331de23705a719514e37c211f327379688f81b0dChris Lattner    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
1356331de23705a719514e37c211f327379688f81b0dChris Lattner    done();
1357331de23705a719514e37c211f327379688f81b0dChris Lattner  }
1358331de23705a719514e37c211f327379688f81b0dChris Lattner};
1359331de23705a719514e37c211f327379688f81b0dChris Lattner
1360331de23705a719514e37c211f327379688f81b0dChris Lattner// aliasfor - Modifier to set the option an alias aliases.
1361331de23705a719514e37c211f327379688f81b0dChris Lattnerstruct aliasopt {
1362331de23705a719514e37c211f327379688f81b0dChris Lattner  Option &Opt;
1363cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman  explicit aliasopt(Option &O) : Opt(O) {}
1364331de23705a719514e37c211f327379688f81b0dChris Lattner  void apply(alias &A) const { A.setAliasFor(Opt); }
1365cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner};
1366cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
13679bbba091396922093687d11a181e5886c42c5dfdReid Spencer// extrahelp - provide additional help at the end of the normal help
13689bbba091396922093687d11a181e5886c42c5dfdReid Spencer// output. All occurrences of cl::extrahelp will be accumulated and
13699bbba091396922093687d11a181e5886c42c5dfdReid Spencer// printed to std::cerr at the end of the regular help, just before
13709bbba091396922093687d11a181e5886c42c5dfdReid Spencer// exit is called.
13719bbba091396922093687d11a181e5886c42c5dfdReid Spencerstruct extrahelp {
13729bbba091396922093687d11a181e5886c42c5dfdReid Spencer  const char * morehelp;
1373b5660dc8223bd5eb3d21d9855692617fcdec5663Dan Gohman  explicit extrahelp(const char* help);
13749bbba091396922093687d11a181e5886c42c5dfdReid Spencer};
13759bbba091396922093687d11a181e5886c42c5dfdReid Spencer
1376aed293dfba04b07a867491c11dfff4bf3eb6bdddDevang Patelvoid PrintVersionMessage();
13779bbba091396922093687d11a181e5886c42c5dfdReid Spencer// This function just prints the help message, exactly the same way as if the
13789bbba091396922093687d11a181e5886c42c5dfdReid Spencer// --help option had been given on the command line.
13799bbba091396922093687d11a181e5886c42c5dfdReid Spencer// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
13809bbba091396922093687d11a181e5886c42c5dfdReid Spencervoid PrintHelpMessage();
1381cc08ee507fc47d80a67c10a20b95587f7f06f0b7Reid Spencer
1382cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner} // End namespace cl
1383cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner
1384d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End namespace llvm
1385d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
1386cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#endif
1387