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