diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h
index e6c4e12..9d86ba6 100644
--- a/include/clang/Driver/Option.h
+++ b/include/clang/Driver/Option.h
@@ -18,7 +18,6 @@
 namespace driver {
   class Arg;
   class ArgList;
-  class OptionGroup;
 
   /// Option - Abstract representation for a single form of driver
   /// argument.
@@ -63,11 +62,13 @@
     StringRef Name;
 
     /// Group this option is a member of, if any.
-    const OptionGroup *Group;
+    const Option *Group;
 
     /// Option that this is an alias for, if any.
     const Option *Alias;
 
+    unsigned NumArgs;
+
     /// Unsupported options will be rejected.
     bool Unsupported : 1;
 
@@ -94,16 +95,15 @@
     /// CC1Option - This option should be accepted by clang -cc1.
     bool CC1Option : 1;
 
-  protected:
-    Option(OptionClass Kind, OptSpecifier ID, const char *Name,
-           const OptionGroup *Group, const Option *Alias);
   public:
-    virtual ~Option();
+    Option(OptionClass Kind, OptSpecifier ID, const char *Name,
+           const Option *Group, const Option *Alias, unsigned Args);
+    ~Option();
 
     unsigned getID() const { return ID.getID(); }
     OptionClass getKind() const { return Kind; }
     StringRef getName() const { return Name; }
-    const OptionGroup *getGroup() const { return Group; }
+    const Option *getGroup() const { return Group; }
     const Option *getAlias() const { return Alias; }
 
     bool isUnsupported() const { return Unsupported; }
@@ -164,158 +164,9 @@
     /// If the option accepts the current argument, accept() sets
     /// Index to the position where argument parsing should resume
     /// (even if the argument is missing values).
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0;
+    Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     void dump() const;
-
-    static bool classof(const Option *) { return true; }
-  };
-
-  /// OptionGroup - A set of options which are can be handled uniformly
-  /// by the driver.
-  class OptionGroup : public Option {
-  public:
-    OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::GroupClass;
-    }
-    static bool classof(const OptionGroup *) { return true; }
-  };
-
-  // Dummy option classes.
-
-  /// InputOption - Dummy option class for representing driver inputs.
-  class InputOption : public Option {
-  public:
-    InputOption(OptSpecifier ID);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::InputClass;
-    }
-    static bool classof(const InputOption *) { return true; }
-  };
-
-  /// UnknownOption - Dummy option class for represent unknown arguments.
-  class UnknownOption : public Option {
-  public:
-    UnknownOption(OptSpecifier ID);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::UnknownClass;
-    }
-    static bool classof(const UnknownOption *) { return true; }
-  };
-
-  // Normal options.
-
-  class FlagOption : public Option {
-  public:
-    FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
-               const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::FlagClass;
-    }
-    static bool classof(const FlagOption *) { return true; }
-  };
-
-  class JoinedOption : public Option {
-  public:
-    JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
-                 const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::JoinedClass;
-    }
-    static bool classof(const JoinedOption *) { return true; }
-  };
-
-  class SeparateOption : public Option {
-  public:
-    SeparateOption(OptSpecifier ID, const char *Name,
-                   const OptionGroup *Group, const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::SeparateClass;
-    }
-    static bool classof(const SeparateOption *) { return true; }
-  };
-
-  class CommaJoinedOption : public Option {
-  public:
-    CommaJoinedOption(OptSpecifier ID, const char *Name,
-                      const OptionGroup *Group, const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::CommaJoinedClass;
-    }
-    static bool classof(const CommaJoinedOption *) { return true; }
-  };
-
-  // FIXME: Fold MultiArgOption into SeparateOption?
-
-  /// MultiArgOption - An option which takes multiple arguments (these
-  /// are always separate arguments).
-  class MultiArgOption : public Option {
-    unsigned NumArgs;
-
-  public:
-    MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
-                   const Option *Alias, unsigned NumArgs);
-
-    unsigned getNumArgs() const { return NumArgs; }
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::MultiArgClass;
-    }
-    static bool classof(const MultiArgOption *) { return true; }
-  };
-
-  /// JoinedOrSeparateOption - An option which either literally
-  /// prefixes its (non-empty) value, or is follwed by a value.
-  class JoinedOrSeparateOption : public Option {
-  public:
-    JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
-                           const OptionGroup *Group, const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::JoinedOrSeparateClass;
-    }
-    static bool classof(const JoinedOrSeparateOption *) { return true; }
-  };
-
-  /// JoinedAndSeparateOption - An option which literally prefixes its
-  /// value and is followed by another value.
-  class JoinedAndSeparateOption : public Option {
-  public:
-    JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
-                            const OptionGroup *Group, const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::JoinedAndSeparateClass;
-    }
-    static bool classof(const JoinedAndSeparateOption *) { return true; }
   };
 
 } // end namespace driver
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 87d533d..240d66f 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -981,7 +981,7 @@
        it != ie; ++it) {
     Arg *A = *it;
 
-    if (isa<InputOption>(A->getOption())) {
+    if (A->getOption().getKind() == Option::InputClass) {
       const char *Value = A->getValue(Args);
       types::ID Ty = types::TY_INVALID;
 
@@ -1337,7 +1337,7 @@
       // Suppress the warning automatically if this is just a flag, and it is an
       // instance of an argument we already claimed.
       const Option &Opt = A->getOption();
-      if (isa<FlagOption>(Opt)) {
+      if (Opt.getKind() == Option::FlagClass) {
         bool DuplicateClaimed = false;
 
         for (arg_iterator it = C.getArgs().filtered_begin(&Opt),
diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
index a3e38b2..f8fe059 100644
--- a/lib/Driver/OptTable.cpp
+++ b/lib/Driver/OptTable.cpp
@@ -131,33 +131,11 @@
 
 Option *OptTable::CreateOption(unsigned id) const {
   const Info &info = getInfo(id);
-  const OptionGroup *Group =
-    cast_or_null<OptionGroup>(getOption(info.GroupID));
+  const Option *Group = getOption(info.GroupID);
   const Option *Alias = getOption(info.AliasID);
 
-  Option *Opt = 0;
-  switch (info.Kind) {
-  case Option::InputClass:
-    Opt = new InputOption(id); break;
-  case Option::UnknownClass:
-    Opt = new UnknownOption(id); break;
-  case Option::GroupClass:
-    Opt = new OptionGroup(id, info.Name, Group); break;
-  case Option::FlagClass:
-    Opt = new FlagOption(id, info.Name, Group, Alias); break;
-  case Option::JoinedClass:
-    Opt = new JoinedOption(id, info.Name, Group, Alias); break;
-  case Option::SeparateClass:
-    Opt = new SeparateOption(id, info.Name, Group, Alias); break;
-  case Option::CommaJoinedClass:
-    Opt = new CommaJoinedOption(id, info.Name, Group, Alias); break;
-  case Option::MultiArgClass:
-    Opt = new MultiArgOption(id, info.Name, Group, Alias, info.Param); break;
-  case Option::JoinedOrSeparateClass:
-    Opt = new JoinedOrSeparateOption(id, info.Name, Group, Alias); break;
-  case Option::JoinedAndSeparateClass:
-    Opt = new JoinedAndSeparateOption(id, info.Name, Group, Alias); break;
-  }
+  Option *Opt = new Option(Option::OptionClass(info.Kind),
+                           id, info.Name, Group, Alias, info.Param);
 
   if (info.Flags & DriverOption)
     Opt->setDriverOption(true);
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
index 03360ea..054f7eb 100644
--- a/lib/Driver/Option.cpp
+++ b/lib/Driver/Option.cpp
@@ -18,9 +18,9 @@
 using namespace clang::driver;
 
 Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
-               const OptionGroup *_Group, const Option *_Alias)
+               const Option *_Group, const Option *_Alias, unsigned Args)
   : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
-    Unsupported(false), LinkerInput(false), NoOptAsInput(false),
+    NumArgs(Args), Unsupported(false), LinkerInput(false), NoOptAsInput(false),
     DriverOption(false), NoArgumentUnused(false), NoForward(false) {
 
   // Multi-level aliases are not supported, and alias options cannot
@@ -87,8 +87,8 @@
     Alias->dump();
   }
 
-  if (const MultiArgOption *MOA = dyn_cast<MultiArgOption>(this))
-    llvm::errs() << " NumArgs:" << MOA->getNumArgs();
+  if (Kind == MultiArgClass)
+    llvm::errs() << " NumArgs:" << NumArgs;
 
   llvm::errs() << ">\n";
 }
@@ -107,174 +107,98 @@
   return false;
 }
 
-OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
-                         const OptionGroup *Group)
-  : Option(Option::GroupClass, ID, Name, Group, 0) {
-}
+Arg *Option::accept(const ArgList &Args, unsigned &Index) const {
+  switch (Kind) {
+  case FlagClass:
+    if (getName().size() != strlen(Args.getArgString(Index)))
+      return 0;
 
-Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const {
-  llvm_unreachable("accept() should never be called on an OptionGroup");
-}
-
-InputOption::InputOption(OptSpecifier ID)
-  : Option(Option::InputClass, ID, "<input>", 0, 0) {
-}
-
-Arg *InputOption::accept(const ArgList &Args, unsigned &Index) const {
-  llvm_unreachable("accept() should never be called on an InputOption");
-}
-
-UnknownOption::UnknownOption(OptSpecifier ID)
-  : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
-}
-
-Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const {
-  llvm_unreachable("accept() should never be called on an UnknownOption");
-}
-
-FlagOption::FlagOption(OptSpecifier ID, const char *Name,
-                       const OptionGroup *Group, const Option *Alias)
-  : Option(Option::FlagClass, ID, Name, Group, Alias) {
-}
-
-Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const {
-  // Matches iff this is an exact match.
-  // FIXME: Avoid strlen.
-  if (getName().size() != strlen(Args.getArgString(Index)))
-    return 0;
-
-  return new Arg(getUnaliasedOption(), Index++);
-}
-
-JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
-                           const OptionGroup *Group, const Option *Alias)
-  : Option(Option::JoinedClass, ID, Name, Group, Alias) {
-}
-
-Arg *JoinedOption::accept(const ArgList &Args, unsigned &Index) const {
-  // Always matches.
-  const char *Value = Args.getArgString(Index) + getName().size();
-  return new Arg(getUnaliasedOption(), Index++, Value);
-}
-
-CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
-                                     const OptionGroup *Group,
-                                     const Option *Alias)
-  : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
-}
-
-Arg *CommaJoinedOption::accept(const ArgList &Args,
-                               unsigned &Index) const {
-  // Always matches.
-  const char *Str = Args.getArgString(Index) + getName().size();
-  Arg *A = new Arg(getUnaliasedOption(), Index++);
-
-  // Parse out the comma separated values.
-  const char *Prev = Str;
-  for (;; ++Str) {
-    char c = *Str;
-
-    if (!c || c == ',') {
-      if (Prev != Str) {
-        char *Value = new char[Str - Prev + 1];
-        memcpy(Value, Prev, Str - Prev);
-        Value[Str - Prev] = '\0';
-        A->getValues().push_back(Value);
-      }
-
-      if (!c)
-        break;
-
-      Prev = Str + 1;
-    }
-  }
-  A->setOwnsValues(true);
-
-  return A;
-}
-
-SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
-                               const OptionGroup *Group, const Option *Alias)
-  : Option(Option::SeparateClass, ID, Name, Group, Alias) {
-}
-
-Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const {
-  // Matches iff this is an exact match.
-  // FIXME: Avoid strlen.
-  if (getName().size() != strlen(Args.getArgString(Index)))
-    return 0;
-
-  Index += 2;
-  if (Index > Args.getNumInputArgStrings())
-    return 0;
-
-  return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
-}
-
-MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
-                               const OptionGroup *Group, const Option *Alias,
-                               unsigned _NumArgs)
-  : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
-  assert(NumArgs > 1  && "Invalid MultiArgOption!");
-}
-
-Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const {
-  // Matches iff this is an exact match.
-  // FIXME: Avoid strlen.
-  if (getName().size() != strlen(Args.getArgString(Index)))
-    return 0;
-
-  Index += 1 + NumArgs;
-  if (Index > Args.getNumInputArgStrings())
-    return 0;
-
-  Arg *A = new Arg(getUnaliasedOption(), Index - 1 - NumArgs,
-                   Args.getArgString(Index - NumArgs));
-  for (unsigned i = 1; i != NumArgs; ++i)
-    A->getValues().push_back(Args.getArgString(Index - NumArgs + i));
-  return A;
-}
-
-JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID,
-                                               const char *Name,
-                                               const OptionGroup *Group,
-                                               const Option *Alias)
-  : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
-}
-
-Arg *JoinedOrSeparateOption::accept(const ArgList &Args,
-                                    unsigned &Index) const {
-  // If this is not an exact match, it is a joined arg.
-  // FIXME: Avoid strlen.
-  if (getName().size() != strlen(Args.getArgString(Index))) {
+    return new Arg(getUnaliasedOption(), Index++);
+  case JoinedClass: {
     const char *Value = Args.getArgString(Index) + getName().size();
-    return new Arg(this, Index++, Value);
+    return new Arg(getUnaliasedOption(), Index++, Value);
   }
+  case CommaJoinedClass: {
+    // Always matches.
+    const char *Str = Args.getArgString(Index) + getName().size();
+    Arg *A = new Arg(getUnaliasedOption(), Index++);
 
-  // Otherwise it must be separate.
-  Index += 2;
-  if (Index > Args.getNumInputArgStrings())
-    return 0;
+    // Parse out the comma separated values.
+    const char *Prev = Str;
+    for (;; ++Str) {
+      char c = *Str;
 
-  return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
-}
+      if (!c || c == ',') {
+        if (Prev != Str) {
+          char *Value = new char[Str - Prev + 1];
+          memcpy(Value, Prev, Str - Prev);
+          Value[Str - Prev] = '\0';
+          A->getValues().push_back(Value);
+        }
 
-JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
-                                                 const char *Name,
-                                                 const OptionGroup *Group,
-                                                 const Option *Alias)
-  : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
-}
+        if (!c)
+          break;
 
-Arg *JoinedAndSeparateOption::accept(const ArgList &Args,
-                                     unsigned &Index) const {
-  // Always matches.
+        Prev = Str + 1;
+      }
+    }
+    A->setOwnsValues(true);
 
-  Index += 2;
-  if (Index > Args.getNumInputArgStrings())
-    return 0;
+    return A;
+  }
+  case SeparateClass:
+    // Matches iff this is an exact match.
+    // FIXME: Avoid strlen.
+    if (getName().size() != strlen(Args.getArgString(Index)))
+      return 0;
 
-  return new Arg(getUnaliasedOption(), Index - 2,
-                 Args.getArgString(Index-2)+getName().size(),
-                 Args.getArgString(Index-1));
+    Index += 2;
+    if (Index > Args.getNumInputArgStrings())
+      return 0;
+
+    return new Arg(getUnaliasedOption(),
+                   Index - 2, Args.getArgString(Index - 1));
+  case MultiArgClass: {
+    // Matches iff this is an exact match.
+    // FIXME: Avoid strlen.
+    if (getName().size() != strlen(Args.getArgString(Index)))
+      return 0;
+
+    Index += 1 + NumArgs;
+    if (Index > Args.getNumInputArgStrings())
+      return 0;
+
+    Arg *A = new Arg(getUnaliasedOption(), Index - 1 - NumArgs,
+                      Args.getArgString(Index - NumArgs));
+    for (unsigned i = 1; i != NumArgs; ++i)
+      A->getValues().push_back(Args.getArgString(Index - NumArgs + i));
+    return A;
+  }
+  case JoinedOrSeparateClass: {
+    // If this is not an exact match, it is a joined arg.
+    // FIXME: Avoid strlen.
+    if (getName().size() != strlen(Args.getArgString(Index))) {
+      const char *Value = Args.getArgString(Index) + getName().size();
+      return new Arg(this, Index++, Value);
+    }
+
+    // Otherwise it must be separate.
+    Index += 2;
+    if (Index > Args.getNumInputArgStrings())
+      return 0;
+
+    return new Arg(getUnaliasedOption(),
+                   Index - 2, Args.getArgString(Index - 1));
+  }
+  case JoinedAndSeparateClass:
+    // Always matches.
+    Index += 2;
+    if (Index > Args.getNumInputArgStrings())
+      return 0;
+
+    return new Arg(getUnaliasedOption(), Index - 2,
+                   Args.getArgString(Index-2)+getName().size(),
+                   Args.getArgString(Index-1));
+  }
+  llvm_unreachable("Invalid option kind!");
 }
