1 //===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===// 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 #ifndef CLANG_DRIVER_OPTION_H_ 11 #define CLANG_DRIVER_OPTION_H_ 12 13 #include "clang/Driver/OptTable.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/Support/ErrorHandling.h" 16 #include "clang/Basic/LLVM.h" 17 18 namespace clang { 19 namespace driver { 20 class Arg; 21 class ArgList; 22 23 namespace options { 24 enum DriverFlag { 25 DriverOption = (1 << 0), 26 HelpHidden = (1 << 1), 27 LinkerInput = (1 << 2), 28 NoArgumentUnused = (1 << 3), 29 NoForward = (1 << 4), 30 RenderAsInput = (1 << 5), 31 RenderJoined = (1 << 6), 32 RenderSeparate = (1 << 7), 33 Unsupported = (1 << 8), 34 CC1Option = (1 << 9) 35 }; 36 } 37 38 /// Option - Abstract representation for a single form of driver 39 /// argument. 40 /// 41 /// An Option class represents a form of option that the driver 42 /// takes, for example how many arguments the option has and how 43 /// they can be provided. Individual option instances store 44 /// additional information about what group the option is a member 45 /// of (if any), if the option is an alias, and a number of 46 /// flags. At runtime the driver parses the command line into 47 /// concrete Arg instances, each of which corresponds to a 48 /// particular Option instance. 49 class Option { 50 public: 51 enum OptionClass { 52 GroupClass = 0, 53 InputClass, 54 UnknownClass, 55 FlagClass, 56 JoinedClass, 57 SeparateClass, 58 CommaJoinedClass, 59 MultiArgClass, 60 JoinedOrSeparateClass, 61 JoinedAndSeparateClass 62 }; 63 64 enum RenderStyleKind { 65 RenderCommaJoinedStyle, 66 RenderJoinedStyle, 67 RenderSeparateStyle, 68 RenderValuesStyle 69 }; 70 71 private: 72 const OptTable::Info *Info; 73 74 /// The option ID. 75 OptSpecifier ID; 76 77 /// Group this option is a member of, if any. 78 const Option *Group; 79 80 /// Option that this is an alias for, if any. 81 const Option *Alias; 82 83 public: 84 Option(const OptTable::Info *Info, OptSpecifier ID, 85 const Option *Group, const Option *Alias); 86 ~Option(); 87 88 unsigned getID() const { return ID.getID(); } 89 OptionClass getKind() const { return OptionClass(Info->Kind); } 90 StringRef getName() const { return Info->Name; } 91 const Option *getGroup() const { return Group; } 92 const Option *getAlias() const { return Alias; } 93 94 unsigned getNumArgs() const { return Info->Param; } 95 96 bool isUnsupported() const { return Info->Flags & options::Unsupported; } 97 98 bool isLinkerInput() const { return Info->Flags & options::LinkerInput; } 99 100 bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;} 101 102 RenderStyleKind getRenderStyle() const { 103 if (Info->Flags & options::RenderJoined) 104 return RenderJoinedStyle; 105 if (Info->Flags & options::RenderSeparate) 106 return RenderSeparateStyle; 107 switch (getKind()) { 108 case GroupClass: 109 case InputClass: 110 case UnknownClass: 111 return RenderValuesStyle; 112 case JoinedClass: 113 case JoinedAndSeparateClass: 114 return RenderJoinedStyle; 115 case CommaJoinedClass: 116 return RenderCommaJoinedStyle; 117 case FlagClass: 118 case SeparateClass: 119 case MultiArgClass: 120 case JoinedOrSeparateClass: 121 return RenderSeparateStyle; 122 } 123 llvm_unreachable("Unexpected kind!"); 124 } 125 126 bool isDriverOption() const { return Info->Flags & options::DriverOption; } 127 128 bool hasNoArgumentUnused() const { 129 return Info->Flags & options::NoArgumentUnused; 130 } 131 132 bool hasNoForward() const { return Info->Flags & options::NoForward; } 133 134 bool isCC1Option() const { return Info->Flags & options::CC1Option; } 135 136 bool hasForwardToGCC() const { 137 return !hasNoForward() && !isDriverOption() && !isLinkerInput(); 138 } 139 140 /// getUnaliasedOption - Return the final option this option 141 /// aliases (itself, if the option has no alias). 142 const Option *getUnaliasedOption() const { 143 if (Alias) return Alias->getUnaliasedOption(); 144 return this; 145 } 146 147 /// getRenderName - Return the name to use when rendering this 148 /// option. 149 StringRef getRenderName() const { 150 return getUnaliasedOption()->getName(); 151 } 152 153 /// matches - Predicate for whether this option is part of the 154 /// given option (which may be a group). 155 /// 156 /// Note that matches against options which are an alias should never be 157 /// done -- aliases do not participate in matching and so such a query will 158 /// always be false. 159 bool matches(OptSpecifier ID) const; 160 161 /// accept - Potentially accept the current argument, returning a 162 /// new Arg instance, or 0 if the option does not accept this 163 /// argument (or the argument is missing values). 164 /// 165 /// If the option accepts the current argument, accept() sets 166 /// Index to the position where argument parsing should resume 167 /// (even if the argument is missing values). 168 Arg *accept(const ArgList &Args, unsigned &Index) const; 169 170 void dump() const; 171 }; 172 173 } // end namespace driver 174 } // end namespace clang 175 176 #endif 177