OptTable.cpp revision 0f9098e093089e935066729ea06bc86c23d9a432
1//===--- Options.cpp - Option info table --------------------------------*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Driver/Options.h"
11
12#include "clang/Driver/Option.h"
13#include <cassert>
14
15using namespace clang;
16using namespace clang::driver;
17using namespace clang::driver::options;
18
19struct Info {
20  Option::OptionClass Kind;
21  const char *Name;
22  unsigned GroupID;
23  unsigned AliasID;
24  const char *Flags;
25  unsigned Param;
26};
27
28static Info OptionInfos[] = {
29#define OPTION(ID, KIND, NAME, GROUP, ALIAS, FLAGS, PARAM)      \
30  { Option::KIND##Class, NAME, GROUP, ALIAS, FLAGS, PARAM },
31#include "clang/Driver/Options.def"
32};
33static const unsigned numOptions = sizeof(OptionInfos) / sizeof(OptionInfos[0]);
34
35static Info &getInfo(unsigned id) {
36  assert(id > 0 && id - 1 < numOptions && "Invalid Option ID.");
37  return OptionInfos[id - 1];
38}
39
40OptTable::OptTable() : Options(new Option*[numOptions]) {
41}
42
43OptTable::~OptTable() {
44  for (unsigned i=0; i<numOptions; ++i)
45    delete Options[i];
46  delete[] Options;
47}
48
49unsigned OptTable::getNumOptions() const {
50  return numOptions;
51}
52
53const char *OptTable::getOptionName(options::ID id) const {
54  return getInfo(id).Name;
55}
56
57const Option *OptTable::getOption(options::ID id) const {
58  if (id == 0)
59    return 0;
60
61  assert((unsigned) (id - 1) < numOptions && "Invalid ID.");
62
63  Option *&Entry = Options[id - 1];
64  if (!Entry)
65    Entry = constructOption(id);
66
67  return Entry;
68}
69
70Option *OptTable::constructOption(options::ID id) const {
71  Info &info = getInfo(id);
72  const OptionGroup *Group =
73    cast_or_null<OptionGroup>(getOption((options::ID) info.GroupID));
74  const Option *Alias = getOption((options::ID) info.AliasID);
75
76  Option *Opt = 0;
77  switch (info.Kind) {
78  default:
79    assert(0 && "Invalid option kind.");
80  case Option::GroupClass:
81    Opt = new OptionGroup(info.Name, Group); break;
82  case Option::FlagClass:
83    Opt = new FlagOption(info.Name, Group, Alias); break;
84  case Option::JoinedClass:
85    Opt = new JoinedOption(info.Name, Group, Alias); break;
86  case Option::SeparateClass:
87    Opt = new SeparateOption(info.Name, Group, Alias); break;
88  case Option::CommaJoinedClass:
89    Opt = new CommaJoinedOption(info.Name, Group, Alias); break;
90  case Option::MultiArgClass:
91    Opt = new MultiArgOption(info.Name, Group, Alias, info.Param); break;
92  case Option::JoinedOrSeparateClass:
93    Opt = new JoinedOrSeparateOption(info.Name, Group, Alias); break;
94  case Option::JoinedAndSeparateClass:
95    Opt = new JoinedAndSeparateOption(info.Name, Group, Alias); break;
96  }
97
98  for (const char *s = info.Flags; *s; ++s) {
99    switch (*s) {
100    default: assert(0 && "Invalid option flag.");
101    case 'l': Opt->setLinkerInput(true); break;
102    case 'i': Opt->setNoOptAsInput(true); break;
103    case 'J': Opt->setForceJoinedRender(true); break;
104    case 'S': Opt->setForceSeparateRender(true); break;
105    case 'U': Opt->setUnsupported(true); break;
106    }
107  }
108
109  return Opt;
110}
111