[clang] Add test for CWG190 "Layout-compatible POD-struct types" (#121668)
[llvm-project.git] / llvm / lib / Option / Option.cpp
blob738f75bb41e68cd975650bc6479c8e6f842776bf
1 //===- Option.cpp - Abstract Driver Options -------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Option/Option.h"
10 #include "llvm/ADT/StringRef.h"
11 #include "llvm/ADT/Twine.h"
12 #include "llvm/Config/llvm-config.h"
13 #include "llvm/Option/Arg.h"
14 #include "llvm/Option/ArgList.h"
15 #include "llvm/Option/OptTable.h"
16 #include "llvm/Support/Compiler.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include <cassert>
22 using namespace llvm;
23 using namespace llvm::opt;
25 Option::Option(const OptTable::Info *info, const OptTable *owner)
26 : Info(info), Owner(owner) {
27 // Multi-level aliases are not supported. This just simplifies option
28 // tracking, it is not an inherent limitation.
29 assert((!Info || !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
30 "Multi-level aliases are not supported.");
32 if (Info && getAliasArgs()) {
33 assert(getAlias().isValid() && "Only alias options can have alias args.");
34 assert(getKind() == FlagClass && "Only Flag aliases can have alias args.");
35 assert(getAlias().getKind() != FlagClass &&
36 "Cannot provide alias args to a flag option.");
40 void Option::print(raw_ostream &O, bool AddNewLine) const {
41 O << "<";
42 switch (getKind()) {
43 #define P(N) case N: O << #N; break
44 P(GroupClass);
45 P(InputClass);
46 P(UnknownClass);
47 P(FlagClass);
48 P(JoinedClass);
49 P(ValuesClass);
50 P(SeparateClass);
51 P(CommaJoinedClass);
52 P(MultiArgClass);
53 P(JoinedOrSeparateClass);
54 P(JoinedAndSeparateClass);
55 P(RemainingArgsClass);
56 P(RemainingArgsJoinedClass);
57 #undef P
60 if (!Info->hasNoPrefix()) {
61 O << " Prefixes:[";
62 for (size_t I = 0, N = Info->getNumPrefixes(Owner->getPrefixesTable());
63 I != N; ++I)
64 O << '"'
65 << Info->getPrefix(Owner->getStrTable(), Owner->getPrefixesTable(), I)
66 << (I == N - 1 ? "\"" : "\", ");
67 O << ']';
70 O << " Name:\"" << getName() << '"';
72 const Option Group = getGroup();
73 if (Group.isValid()) {
74 O << " Group:";
75 Group.print(O, /*AddNewLine=*/false);
78 const Option Alias = getAlias();
79 if (Alias.isValid()) {
80 O << " Alias:";
81 Alias.print(O, /*AddNewLine=*/false);
84 if (getKind() == MultiArgClass)
85 O << " NumArgs:" << getNumArgs();
87 O << ">";
88 if (AddNewLine)
89 O << "\n";
92 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
93 LLVM_DUMP_METHOD void Option::dump() const { print(dbgs()); }
94 #endif
96 bool Option::matches(OptSpecifier Opt) const {
97 // Aliases are never considered in matching, look through them.
98 const Option Alias = getAlias();
99 if (Alias.isValid())
100 return Alias.matches(Opt);
102 // Check exact match.
103 if (getID() == Opt.getID())
104 return true;
106 const Option Group = getGroup();
107 if (Group.isValid())
108 return Group.matches(Opt);
109 return false;
112 std::unique_ptr<Arg> Option::acceptInternal(const ArgList &Args,
113 StringRef Spelling,
114 unsigned &Index) const {
115 const size_t SpellingSize = Spelling.size();
116 const size_t ArgStringSize = StringRef(Args.getArgString(Index)).size();
117 switch (getKind()) {
118 case FlagClass: {
119 if (SpellingSize != ArgStringSize)
120 return nullptr;
121 return std::make_unique<Arg>(*this, Spelling, Index++);
123 case JoinedClass: {
124 const char *Value = Args.getArgString(Index) + SpellingSize;
125 return std::make_unique<Arg>(*this, Spelling, Index++, Value);
127 case CommaJoinedClass: {
128 // Always matches.
129 const char *Str = Args.getArgString(Index) + SpellingSize;
130 auto A = std::make_unique<Arg>(*this, Spelling, Index++);
132 // Parse out the comma separated values.
133 const char *Prev = Str;
134 for (;; ++Str) {
135 char c = *Str;
137 if (!c || c == ',') {
138 if (Prev != Str) {
139 char *Value = new char[Str - Prev + 1];
140 memcpy(Value, Prev, Str - Prev);
141 Value[Str - Prev] = '\0';
142 A->getValues().push_back(Value);
145 if (!c)
146 break;
148 Prev = Str + 1;
151 A->setOwnsValues(true);
153 return A;
155 case SeparateClass:
156 // Matches iff this is an exact match.
157 if (SpellingSize != ArgStringSize)
158 return nullptr;
160 Index += 2;
161 if (Index > Args.getNumInputArgStrings() ||
162 Args.getArgString(Index - 1) == nullptr)
163 return nullptr;
165 return std::make_unique<Arg>(*this, Spelling, Index - 2,
166 Args.getArgString(Index - 1));
167 case MultiArgClass: {
168 // Matches iff this is an exact match.
169 if (SpellingSize != ArgStringSize)
170 return nullptr;
172 Index += 1 + getNumArgs();
173 if (Index > Args.getNumInputArgStrings())
174 return nullptr;
176 auto A = std::make_unique<Arg>(*this, Spelling, Index - 1 - getNumArgs(),
177 Args.getArgString(Index - getNumArgs()));
178 for (unsigned i = 1; i != getNumArgs(); ++i)
179 A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
180 return A;
182 case JoinedOrSeparateClass: {
183 // If this is not an exact match, it is a joined arg.
184 if (SpellingSize != ArgStringSize) {
185 const char *Value = Args.getArgString(Index) + SpellingSize;
186 return std::make_unique<Arg>(*this, Spelling, Index++, Value);
189 // Otherwise it must be separate.
190 Index += 2;
191 if (Index > Args.getNumInputArgStrings() ||
192 Args.getArgString(Index - 1) == nullptr)
193 return nullptr;
195 return std::make_unique<Arg>(*this, Spelling, Index - 2,
196 Args.getArgString(Index - 1));
198 case JoinedAndSeparateClass:
199 // Always matches.
200 Index += 2;
201 if (Index > Args.getNumInputArgStrings() ||
202 Args.getArgString(Index - 1) == nullptr)
203 return nullptr;
205 return std::make_unique<Arg>(*this, Spelling, Index - 2,
206 Args.getArgString(Index - 2) + SpellingSize,
207 Args.getArgString(Index - 1));
208 case RemainingArgsClass: {
209 // Matches iff this is an exact match.
210 if (SpellingSize != ArgStringSize)
211 return nullptr;
212 auto A = std::make_unique<Arg>(*this, Spelling, Index++);
213 while (Index < Args.getNumInputArgStrings() &&
214 Args.getArgString(Index) != nullptr)
215 A->getValues().push_back(Args.getArgString(Index++));
216 return A;
218 case RemainingArgsJoinedClass: {
219 auto A = std::make_unique<Arg>(*this, Spelling, Index);
220 if (SpellingSize != ArgStringSize) {
221 // An inexact match means there is a joined arg.
222 A->getValues().push_back(Args.getArgString(Index) + SpellingSize);
224 Index++;
225 while (Index < Args.getNumInputArgStrings() &&
226 Args.getArgString(Index) != nullptr)
227 A->getValues().push_back(Args.getArgString(Index++));
228 return A;
231 default:
232 llvm_unreachable("Invalid option kind!");
236 std::unique_ptr<Arg> Option::accept(const ArgList &Args, StringRef CurArg,
237 bool GroupedShortOption,
238 unsigned &Index) const {
239 auto A(GroupedShortOption && getKind() == FlagClass
240 ? std::make_unique<Arg>(*this, CurArg, Index)
241 : acceptInternal(Args, CurArg, Index));
242 if (!A)
243 return nullptr;
245 const Option &UnaliasedOption = getUnaliasedOption();
246 if (getID() == UnaliasedOption.getID())
247 return A;
249 // "A" is an alias for a different flag. For most clients it's more convenient
250 // if this function returns unaliased Args, so create an unaliased arg for
251 // returning.
253 // This creates a completely new Arg object for the unaliased Arg because
254 // the alias and the unaliased arg can have different Kinds and different
255 // Values (due to AliasArgs<>).
257 // Get the spelling from the unaliased option.
258 StringRef UnaliasedSpelling = Args.MakeArgString(
259 Twine(UnaliasedOption.getPrefix()) + Twine(UnaliasedOption.getName()));
261 // It's a bit weird that aliased and unaliased arg share one index, but
262 // the index is mostly use as a memory optimization in render().
263 // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling
264 // of the aliased arg always, while A->getSpelling() returns either the
265 // unaliased or the aliased arg, depending on which Arg object it's called on.
266 auto UnaliasedA =
267 std::make_unique<Arg>(UnaliasedOption, UnaliasedSpelling, A->getIndex());
268 Arg *RawA = A.get();
269 UnaliasedA->setAlias(std::move(A));
271 if (getKind() != FlagClass) {
272 // Values are usually owned by the ArgList. The exception are
273 // CommaJoined flags, where the Arg owns the values. For aliased flags,
274 // make the unaliased Arg the owner of the values.
275 // FIXME: There aren't many uses of CommaJoined -- try removing
276 // CommaJoined in favor of just calling StringRef::split(',') instead.
277 UnaliasedA->getValues() = RawA->getValues();
278 UnaliasedA->setOwnsValues(RawA->getOwnsValues());
279 RawA->setOwnsValues(false);
280 return UnaliasedA;
283 // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg.
284 if (const char *Val = getAliasArgs()) {
285 while (*Val != '\0') {
286 UnaliasedA->getValues().push_back(Val);
288 // Move past the '\0' to the next argument.
289 Val += strlen(Val) + 1;
292 if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs())
293 // A Flag alias for a Joined option must provide an argument.
294 UnaliasedA->getValues().push_back("");
295 return UnaliasedA;