blob: 070c12e154f0729b1deb19029676c163cda97cc9 [file] [log] [blame]
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +00001//===--- 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[] = {
Daniel Dunbar30b055f2009-03-04 21:53:04 +000029 // The InputOption info
30 { Option::InputClass, "<input>", 0, 0, "", 0 },
31 // The UnknownOption info
32 { Option::UnknownClass, "<unknown>", 0, 0, "", 0 },
33
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000034#define OPTION(ID, KIND, NAME, GROUP, ALIAS, FLAGS, PARAM) \
35 { Option::KIND##Class, NAME, GROUP, ALIAS, FLAGS, PARAM },
36#include "clang/Driver/Options.def"
37};
38static const unsigned numOptions = sizeof(OptionInfos) / sizeof(OptionInfos[0]);
39
40static Info &getInfo(unsigned id) {
41 assert(id > 0 && id - 1 < numOptions && "Invalid Option ID.");
42 return OptionInfos[id - 1];
43}
44
45OptTable::OptTable() : Options(new Option*[numOptions]) {
46}
47
48OptTable::~OptTable() {
49 for (unsigned i=0; i<numOptions; ++i)
50 delete Options[i];
51 delete[] Options;
52}
53
54unsigned OptTable::getNumOptions() const {
55 return numOptions;
56}
57
58const char *OptTable::getOptionName(options::ID id) const {
59 return getInfo(id).Name;
60}
61
62const Option *OptTable::getOption(options::ID id) const {
Daniel Dunbar30b055f2009-03-04 21:53:04 +000063 if (id == NotOption)
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000064 return 0;
65
66 assert((unsigned) (id - 1) < numOptions && "Invalid ID.");
67
68 Option *&Entry = Options[id - 1];
69 if (!Entry)
70 Entry = constructOption(id);
71
72 return Entry;
73}
74
75Option *OptTable::constructOption(options::ID id) const {
76 Info &info = getInfo(id);
77 const OptionGroup *Group =
78 cast_or_null<OptionGroup>(getOption((options::ID) info.GroupID));
79 const Option *Alias = getOption((options::ID) info.AliasID);
80
81 Option *Opt = 0;
82 switch (info.Kind) {
Daniel Dunbar30b055f2009-03-04 21:53:04 +000083 case Option::InputClass:
84 Opt = new InputOption(); break;
85 case Option::UnknownClass:
86 Opt = new UnknownOption(); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000087 case Option::GroupClass:
Daniel Dunbar30b055f2009-03-04 21:53:04 +000088 Opt = new OptionGroup(id, info.Name, Group); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000089 case Option::FlagClass:
Daniel Dunbar30b055f2009-03-04 21:53:04 +000090 Opt = new FlagOption(id, info.Name, Group, Alias); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000091 case Option::JoinedClass:
Daniel Dunbar30b055f2009-03-04 21:53:04 +000092 Opt = new JoinedOption(id, info.Name, Group, Alias); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000093 case Option::SeparateClass:
Daniel Dunbar30b055f2009-03-04 21:53:04 +000094 Opt = new SeparateOption(id, info.Name, Group, Alias); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000095 case Option::CommaJoinedClass:
Daniel Dunbar30b055f2009-03-04 21:53:04 +000096 Opt = new CommaJoinedOption(id, info.Name, Group, Alias); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000097 case Option::MultiArgClass:
Daniel Dunbar30b055f2009-03-04 21:53:04 +000098 Opt = new MultiArgOption(id, info.Name, Group, Alias, info.Param); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000099 case Option::JoinedOrSeparateClass:
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000100 Opt = new JoinedOrSeparateOption(id, info.Name, Group, Alias); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000101 case Option::JoinedAndSeparateClass:
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000102 Opt = new JoinedAndSeparateOption(id, info.Name, Group, Alias); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000103 }
104
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000105 for (const char *s = info.Flags; *s; ++s) {
106 switch (*s) {
Daniel Dunbar0f9098e2009-03-04 21:05:23 +0000107 default: assert(0 && "Invalid option flag.");
108 case 'l': Opt->setLinkerInput(true); break;
109 case 'i': Opt->setNoOptAsInput(true); break;
110 case 'J': Opt->setForceJoinedRender(true); break;
111 case 'S': Opt->setForceSeparateRender(true); break;
112 case 'U': Opt->setUnsupported(true); break;
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000113 }
114 }
115
116 return Opt;
117}