|
1 # 24314638 LLVM CommandLine subsystem is busted |
|
2 # 24314687 static initialization of optimization passes doesn't work as |
|
3 # intended |
|
4 # 3.9.X for upstream. |
|
5 --- include/llvm/Support/raw_ostream.h 2015-12-16 14:59:06.000000000 -0800 |
|
6 +++ include/llvm/Support/raw_ostream.h 2016-05-19 17:27:46.046422643 -0700 |
|
7 @@ -35,7 +35,7 @@ |
|
8 /// output to a stream. It does not support seeking, reopening, rewinding, line |
|
9 /// buffered disciplines etc. It is a simple buffer that outputs |
|
10 /// a chunk at a time. |
|
11 -class raw_ostream { |
|
12 +class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) raw_ostream { |
|
13 private: |
|
14 void operator=(const raw_ostream &) = delete; |
|
15 raw_ostream(const raw_ostream &) = delete; |
|
16 ### |
|
17 --- lib/Support/raw_ostream.cpp 2016-01-11 15:33:03.000000000 -0800 |
|
18 +++ lib/Support/raw_ostream.cpp 2016-05-25 20:32:16.532306707 -0700 |
|
19 @@ -20,7 +20,9 @@ |
|
20 #include "llvm/Support/ErrorHandling.h" |
|
21 #include "llvm/Support/FileSystem.h" |
|
22 #include "llvm/Support/Format.h" |
|
23 +#include "llvm/Support/ManagedStatic.h" |
|
24 #include "llvm/Support/MathExtras.h" |
|
25 +#include "llvm/Support/Mutex.h" |
|
26 #include "llvm/Support/Process.h" |
|
27 #include "llvm/Support/Program.h" |
|
28 #include <cctype> |
|
29 @@ -496,7 +498,7 @@ |
|
30 // Handle "-" as stdout. Note that when we do this, we consider ourself |
|
31 // the owner of stdout. This means that we can do things like close the |
|
32 // file descriptor when we're done and set the "binary" flag globally. |
|
33 - if (Filename == "-") { |
|
34 + if (Filename == StringRef("-")) { |
|
35 EC = std::error_code(); |
|
36 // If user requested binary then put stdout into binary mode if |
|
37 // possible. |
|
38 @@ -515,38 +517,61 @@ |
|
39 |
|
40 raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC, |
|
41 sys::fs::OpenFlags Flags) |
|
42 - : raw_fd_ostream(getFD(Filename, EC, Flags), true) {} |
|
43 + : raw_pwrite_stream(true), FD(-1), ShouldClose(false), |
|
44 + Error(false), pos(static_cast<uint64_t>(-1)), SupportsSeeking(false) { |
|
45 + this->FD = getFD(Filename, EC, Flags); |
|
46 + if (this->FD < 0 ) { |
|
47 + ShouldClose = false; |
|
48 + return; |
|
49 + } |
|
50 + |
|
51 + // Get the starting position. |
|
52 + off_t loc = ::lseek(this->FD, 0, SEEK_CUR); |
|
53 +#ifdef LLVM_ON_WIN32 |
|
54 + // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes. |
|
55 + sys::fs::file_status Status; |
|
56 + std::error_code EC = status(FD, Status); |
|
57 + SupportsSeeking = !EC && Status.type() == sys::fs::file_type::regular_file; |
|
58 +#else |
|
59 + SupportsSeeking = loc != static_cast<off_t>(-1); |
|
60 +#endif |
|
61 + if (!SupportsSeeking) |
|
62 + pos = 0ULL; |
|
63 + else |
|
64 + pos = static_cast<uint64_t>(loc); |
|
65 +} |
|
66 |
|
67 /// FD is the file descriptor that this writes to. If ShouldClose is true, this |
|
68 /// closes the file when the stream is destroyed. |
|
69 raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered) |
|
70 : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose), |
|
71 - Error(false) { |
|
72 - if (FD < 0 ) { |
|
73 + Error(false), pos(static_cast<uint64_t>(-1)), SupportsSeeking(false) { |
|
74 + if (this->FD < 0 ) { |
|
75 ShouldClose = false; |
|
76 return; |
|
77 } |
|
78 |
|
79 // Get the starting position. |
|
80 - off_t loc = ::lseek(FD, 0, SEEK_CUR); |
|
81 + off_t loc = ::lseek(this->FD, 0, SEEK_CUR); |
|
82 #ifdef LLVM_ON_WIN32 |
|
83 // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes. |
|
84 sys::fs::file_status Status; |
|
85 std::error_code EC = status(FD, Status); |
|
86 SupportsSeeking = !EC && Status.type() == sys::fs::file_type::regular_file; |
|
87 #else |
|
88 - SupportsSeeking = loc != (off_t)-1; |
|
89 + SupportsSeeking = loc != static_cast<off_t>(-1); |
|
90 #endif |
|
91 if (!SupportsSeeking) |
|
92 - pos = 0; |
|
93 + pos = 0ULL; |
|
94 else |
|
95 pos = static_cast<uint64_t>(loc); |
|
96 } |
|
97 |
|
98 raw_fd_ostream::~raw_fd_ostream() { |
|
99 - if (FD >= 0) { |
|
100 + if (this->FD >= 0) { |
|
101 flush(); |
|
102 - if (ShouldClose && sys::Process::SafelyCloseFileDescriptor(FD)) |
|
103 + |
|
104 + if (ShouldClose && sys::Process::SafelyCloseFileDescriptor(this->FD)) |
|
105 error_detected(); |
|
106 } |
|
107 |
|
108 @@ -585,7 +610,7 @@ |
|
109 if (ChunkSize > 32767 && ShouldWriteInChunks) |
|
110 ChunkSize = 32767; |
|
111 |
|
112 - ssize_t ret = ::write(FD, Ptr, ChunkSize); |
|
113 + ssize_t ret = ::write(this->FD, Ptr, ChunkSize); |
|
114 |
|
115 if (ret < 0) { |
|
116 // If it's a recoverable error, swallow it and retry the write. |
|
117 @@ -617,11 +642,14 @@ |
|
118 } |
|
119 |
|
120 void raw_fd_ostream::close() { |
|
121 - assert(ShouldClose); |
|
122 + if (FD == -1) { |
|
123 + ShouldClose = false; |
|
124 + return; |
|
125 + } |
|
126 + |
|
127 ShouldClose = false; |
|
128 flush(); |
|
129 - if (sys::Process::SafelyCloseFileDescriptor(FD)) |
|
130 - error_detected(); |
|
131 + (void) sys::Process::SafelyCloseFileDescriptor(FD); |
|
132 FD = -1; |
|
133 } |
|
134 |
|
135 @@ -715,30 +743,64 @@ |
|
136 // outs(), errs(), nulls() |
|
137 //===----------------------------------------------------------------------===// |
|
138 |
|
139 +static raw_fd_ostream *SOUT = nullptr; |
|
140 +static llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SOutMutex; |
|
141 + |
|
142 +static raw_fd_ostream *SERR = nullptr; |
|
143 +static llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SErrMutex; |
|
144 + |
|
145 +static raw_null_ostream *SNULL = nullptr; |
|
146 +static llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SNullMutex; |
|
147 + |
|
148 /// outs() - This returns a reference to a raw_ostream for standard output. |
|
149 /// Use it like: outs() << "foo" << "bar"; |
|
150 +__attribute__((noinline)) |
|
151 raw_ostream &llvm::outs() { |
|
152 // Set buffer settings to model stdout behavior. |
|
153 // Delete the file descriptor when the program exits, forcing error |
|
154 // detection. If you don't want this behavior, don't use outs(). |
|
155 - std::error_code EC; |
|
156 - static raw_fd_ostream S("-", EC, sys::fs::F_None); |
|
157 - assert(!EC); |
|
158 - return S; |
|
159 + // This makes absolutely no sense whatsoever. getFD returns STDOUT_FILENO |
|
160 + // anyway. |
|
161 + |
|
162 + if (!SOUT) { |
|
163 + llvm::sys::SmartScopedLock<true> Lock(*SOutMutex); |
|
164 + if (!SOUT) { |
|
165 + SOUT = new raw_fd_ostream(STDOUT_FILENO, false, false); |
|
166 + assert(SOUT); |
|
167 + } |
|
168 + } |
|
169 + |
|
170 + return *SOUT; |
|
171 } |
|
172 |
|
173 /// errs() - This returns a reference to a raw_ostream for standard error. |
|
174 /// Use it like: errs() << "foo" << "bar"; |
|
175 +__attribute__((noinline)) |
|
176 raw_ostream &llvm::errs() { |
|
177 // Set standard error to be unbuffered by default. |
|
178 - static raw_fd_ostream S(STDERR_FILENO, false, true); |
|
179 - return S; |
|
180 + if (!SERR) { |
|
181 + llvm::sys::SmartScopedLock<true> Lock(*SErrMutex); |
|
182 + if (!SERR) { |
|
183 + SERR = new raw_fd_ostream(STDERR_FILENO, false, true); |
|
184 + assert(SERR); |
|
185 + } |
|
186 + } |
|
187 + |
|
188 + return *SERR; |
|
189 } |
|
190 |
|
191 /// nulls() - This returns a reference to a raw_ostream which discards output. |
|
192 +__attribute__((noinline)) |
|
193 raw_ostream &llvm::nulls() { |
|
194 - static raw_null_ostream S; |
|
195 - return S; |
|
196 + if (!SNULL) { |
|
197 + llvm::sys::SmartScopedLock<true> Lock(*SNullMutex); |
|
198 + if (!SNULL) { |
|
199 + SNULL = new raw_null_ostream(); |
|
200 + assert(SNULL); |
|
201 + } |
|
202 + } |
|
203 + |
|
204 + return *SNULL; |
|
205 } |
|
206 |
|
207 |
|
208 ### |
|
209 --- include/llvm/Support/CommandLine.h 2015-11-17 10:00:52.000000000 -0900 |
|
210 +++ include/llvm/Support/CommandLine.h 2016-07-05 20:30:35.333194355 -0800 |
|
211 @@ -25,11 +25,13 @@ |
|
212 #include "llvm/ADT/StringMap.h" |
|
213 #include "llvm/ADT/Twine.h" |
|
214 #include "llvm/Support/Compiler.h" |
|
215 +#include "llvm/Support/raw_ostream.h" |
|
216 #include <cassert> |
|
217 #include <climits> |
|
218 #include <cstdarg> |
|
219 #include <utility> |
|
220 #include <vector> |
|
221 +#include <type_traits> |
|
222 |
|
223 namespace llvm { |
|
224 |
|
225 @@ -111,7 +113,9 @@ |
|
226 // zero reserved for the unspecified value |
|
227 ValueOptional = 0x01, // The value can appear... or not |
|
228 ValueRequired = 0x02, // The value is required to appear! |
|
229 - ValueDisallowed = 0x03 // A value may not be specified (for flags) |
|
230 + ValueDisallowed = 0x03, // A value may not be specified (for flags) |
|
231 + ValuePositionalNoArgs = 0x04, // Positional Argument, no additional args |
|
232 + ValuePositionalWithArgs = 0x05 // Positional Argument, with additional args |
|
233 }; |
|
234 |
|
235 enum OptionHidden { // Control whether -help shows this option |
|
236 @@ -149,6 +153,43 @@ |
|
237 }; |
|
238 |
|
239 //===----------------------------------------------------------------------===// |
|
240 +// Generic Filename Locations |
|
241 +// |
|
242 +struct GenericFilenameLocation { |
|
243 + GenericFilenameLocation() : Value("") { } |
|
244 + GenericFilenameLocation(const std::string &S) : Value(S) { } |
|
245 + GenericFilenameLocation(std::string &&S) |
|
246 + : Value(std::move(S)) { } |
|
247 + |
|
248 + void operator=(const std::string &S) { |
|
249 + if (!S.empty()) |
|
250 + Value = S; |
|
251 + } |
|
252 + |
|
253 + void operator=(std::string &&S) { |
|
254 + if (!S.empty()) |
|
255 + Value = std::move(S); |
|
256 + } |
|
257 + |
|
258 + std::string Value; |
|
259 +}; |
|
260 + |
|
261 +struct GenericFilenameLocations { |
|
262 + GenericFilenameLocations() : Value() { } |
|
263 + GenericFilenameLocations(const std::string &S) |
|
264 + : Value() { |
|
265 + Value.push_back(S); |
|
266 + } |
|
267 + |
|
268 + void operator=(const std::string &S) { |
|
269 + if (!S.empty()) |
|
270 + Value.push_back(S); |
|
271 + } |
|
272 + |
|
273 + std::vector<std::string> Value; |
|
274 +}; |
|
275 + |
|
276 +//===----------------------------------------------------------------------===// |
|
277 // Option Category class |
|
278 // |
|
279 class OptionCategory { |
|
280 @@ -176,6 +217,16 @@ |
|
281 class alias; |
|
282 class Option { |
|
283 friend class alias; |
|
284 + friend class OptionRegistry; |
|
285 + |
|
286 +protected: |
|
287 + /// RegisteredOptionList - This is the list of the command line options |
|
288 + /// that have statically constructed themselves. |
|
289 + static Option *RegisteredOptionList; |
|
290 + |
|
291 + /// NumRegisteredOptions - The number of Options registered with the |
|
292 + /// RegisteredOptionList. |
|
293 + static unsigned NumRegisteredOptions; |
|
294 |
|
295 // handleOccurrences - Overriden by subclasses to handle the value passed into |
|
296 // an argument. Should return true if there was an error processing the |
|
297 @@ -191,51 +242,65 @@ |
|
298 // Out of line virtual function to provide home for the class. |
|
299 virtual void anchor(); |
|
300 |
|
301 - int NumOccurrences; // The number of times specified |
|
302 + // The number of times specified |
|
303 + int NumOccurrences; |
|
304 + |
|
305 // Occurrences, HiddenFlag, and Formatting are all enum types but to avoid |
|
306 // problems with signed enums in bitfields. |
|
307 - unsigned Occurrences : 3; // enum NumOccurrencesFlag |
|
308 + unsigned Occurrences; // enum NumOccurrencesFlag |
|
309 + |
|
310 + // This Option's position index in the RegisteredOptionList. |
|
311 + // -1 means this option hasn't been registered. |
|
312 + int OptionIndex; |
|
313 + |
|
314 // not using the enum type for 'Value' because zero is an implementation |
|
315 // detail representing the non-value |
|
316 - unsigned Value : 2; |
|
317 - unsigned HiddenFlag : 2; // enum OptionHidden |
|
318 - unsigned Formatting : 2; // enum FormattingFlags |
|
319 - unsigned Misc : 3; |
|
320 + unsigned Value; |
|
321 + |
|
322 + unsigned HiddenFlag; // enum OptionHidden |
|
323 + unsigned Formatting; // enum FormattingFlags |
|
324 + unsigned Misc; |
|
325 unsigned Position; // Position of last occurrence of the option |
|
326 unsigned AdditionalVals; // Greater than 0 for multi-valued option. |
|
327 + Option *NextRegistered; |
|
328 |
|
329 public: |
|
330 - StringRef ArgStr; // The argument string itself (ex: "help", "o") |
|
331 - StringRef HelpStr; // The descriptive text message for -help |
|
332 - StringRef ValueStr; // String describing what the value of this option is |
|
333 + const char *ArgStr; // The argument string itself (ex: "help", "o") |
|
334 + const char *HelpStr; // The descriptive text message for -help |
|
335 + const char *ValueStr; // String describing what the value of this option is |
|
336 OptionCategory *Category; // The Category this option belongs to |
|
337 bool FullyInitialized; // Has addArguemnt been called? |
|
338 |
|
339 inline enum NumOccurrencesFlag getNumOccurrencesFlag() const { |
|
340 - return (enum NumOccurrencesFlag)Occurrences; |
|
341 + return static_cast<enum NumOccurrencesFlag>(Occurrences); |
|
342 } |
|
343 + |
|
344 inline enum ValueExpected getValueExpectedFlag() const { |
|
345 - return Value ? ((enum ValueExpected)Value) : getValueExpectedFlagDefault(); |
|
346 + return Value ? |
|
347 + static_cast<enum ValueExpected>(Value) : getValueExpectedFlagDefault(); |
|
348 } |
|
349 + |
|
350 inline enum OptionHidden getOptionHiddenFlag() const { |
|
351 - return (enum OptionHidden)HiddenFlag; |
|
352 + return static_cast<enum OptionHidden>(HiddenFlag); |
|
353 } |
|
354 + |
|
355 inline enum FormattingFlags getFormattingFlag() const { |
|
356 - return (enum FormattingFlags)Formatting; |
|
357 + return static_cast<enum FormattingFlags>(Formatting); |
|
358 } |
|
359 + |
|
360 inline unsigned getMiscFlags() const { return Misc; } |
|
361 inline unsigned getPosition() const { return Position; } |
|
362 inline unsigned getNumAdditionalVals() const { return AdditionalVals; } |
|
363 |
|
364 // hasArgStr - Return true if the argstr != "" |
|
365 - bool hasArgStr() const { return !ArgStr.empty(); } |
|
366 + bool hasArgStr() const { return ArgStr && *ArgStr != '\0'; } |
|
367 |
|
368 //-------------------------------------------------------------------------=== |
|
369 // Accessor functions set by OptionModifiers |
|
370 // |
|
371 - void setArgStr(StringRef S); |
|
372 - void setDescription(StringRef S) { HelpStr = S; } |
|
373 - void setValueStr(StringRef S) { ValueStr = S; } |
|
374 + void setArgStr(const char *S); |
|
375 + void setDescription(const char *S) { HelpStr = S; } |
|
376 + void setValueStr(const char *S) { ValueStr = S; } |
|
377 void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { Occurrences = Val; } |
|
378 void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; } |
|
379 void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; } |
|
380 @@ -245,16 +310,121 @@ |
|
381 void setCategory(OptionCategory &C) { Category = &C; } |
|
382 |
|
383 protected: |
|
384 + Option() : NumOccurrences(0), |
|
385 + Occurrences(0), |
|
386 + OptionIndex(-1), |
|
387 + Value(0U), |
|
388 + HiddenFlag(0U), |
|
389 + Formatting(0U), |
|
390 + Misc(0U), |
|
391 + Position(0U), |
|
392 + AdditionalVals(0U), |
|
393 + NextRegistered(nullptr), |
|
394 + ArgStr(""), |
|
395 + HelpStr(""), |
|
396 + ValueStr(""), |
|
397 + Category(nullptr), |
|
398 + FullyInitialized(false) { } |
|
399 + |
|
400 explicit Option(enum NumOccurrencesFlag OccurrencesFlag, |
|
401 enum OptionHidden Hidden) |
|
402 - : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), |
|
403 - HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), Position(0), |
|
404 - AdditionalVals(0), ArgStr(""), HelpStr(""), ValueStr(""), |
|
405 - Category(&GeneralCategory), FullyInitialized(false) {} |
|
406 + : NumOccurrences(0), |
|
407 + Occurrences(OccurrencesFlag), |
|
408 + OptionIndex(-1), |
|
409 + Value(0U), |
|
410 + HiddenFlag(Hidden), |
|
411 + Formatting(NormalFormatting), |
|
412 + Misc(0U), |
|
413 + Position(0U), |
|
414 + AdditionalVals(0U), |
|
415 + NextRegistered(nullptr), |
|
416 + ArgStr(""), |
|
417 + HelpStr(""), |
|
418 + ValueStr(""), |
|
419 + Category(&GeneralCategory), |
|
420 + FullyInitialized(false) { } |
|
421 |
|
422 inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } |
|
423 |
|
424 public: |
|
425 + Option(const Option &RHS) |
|
426 + : NumOccurrences(RHS.NumOccurrences), |
|
427 + Occurrences(RHS.Occurrences), |
|
428 + OptionIndex(RHS.OptionIndex), |
|
429 + Value(RHS.Value), |
|
430 + HiddenFlag(RHS.HiddenFlag), |
|
431 + Formatting(RHS.Formatting), |
|
432 + Misc(RHS.Misc), |
|
433 + Position(RHS.Position), |
|
434 + AdditionalVals(RHS.AdditionalVals), |
|
435 + NextRegistered(RHS.NextRegistered), |
|
436 + ArgStr(RHS.ArgStr), |
|
437 + HelpStr(RHS.HelpStr), |
|
438 + ValueStr(RHS.ValueStr), |
|
439 + Category(RHS.Category), |
|
440 + FullyInitialized(RHS.FullyInitialized) { } |
|
441 + |
|
442 + Option(Option &&RHS) |
|
443 + : NumOccurrences(std::move(RHS.NumOccurrences)), |
|
444 + Occurrences(std::move(RHS.Occurrences)), |
|
445 + OptionIndex(std::move(RHS.OptionIndex)), |
|
446 + Value(std::move(RHS.Value)), |
|
447 + HiddenFlag(std::move(RHS.HiddenFlag)), |
|
448 + Formatting(std::move(RHS.Formatting)), |
|
449 + Misc(std::move(RHS.Misc)), |
|
450 + Position(std::move(RHS.Position)), |
|
451 + AdditionalVals(std::move(RHS.AdditionalVals)), |
|
452 + NextRegistered(std::move(RHS.NextRegistered)), |
|
453 + ArgStr(std::move(RHS.ArgStr)), |
|
454 + HelpStr(std::move(RHS.HelpStr)), |
|
455 + ValueStr(std::move(RHS.ValueStr)), |
|
456 + Category(std::move(RHS.Category)), |
|
457 + FullyInitialized(std::move(RHS.FullyInitialized)) { } |
|
458 + |
|
459 + Option &operator=(const Option &RHS) { |
|
460 + if (this != &RHS) { |
|
461 + NumOccurrences = RHS.NumOccurrences; |
|
462 + Occurrences = RHS.Occurrences; |
|
463 + OptionIndex = RHS.OptionIndex; |
|
464 + Value = RHS.Value; |
|
465 + HiddenFlag = RHS.HiddenFlag; |
|
466 + Formatting = RHS.Formatting; |
|
467 + Misc = RHS.Misc; |
|
468 + Position = RHS.Position; |
|
469 + AdditionalVals = RHS.AdditionalVals; |
|
470 + NextRegistered = RHS.NextRegistered; |
|
471 + ArgStr = RHS.ArgStr; |
|
472 + HelpStr = RHS.HelpStr; |
|
473 + ValueStr = RHS.ValueStr; |
|
474 + Category = RHS.Category; |
|
475 + FullyInitialized = RHS.FullyInitialized; |
|
476 + } |
|
477 + |
|
478 + return *this; |
|
479 + } |
|
480 + |
|
481 + const Option &operator=(Option &&RHS) { |
|
482 + if (this != &RHS) { |
|
483 + NumOccurrences = std::move(RHS.NumOccurrences); |
|
484 + Occurrences = std::move(RHS.Occurrences); |
|
485 + OptionIndex = RHS.OptionIndex; |
|
486 + Value = std::move(RHS.Value); |
|
487 + HiddenFlag = std::move(RHS.HiddenFlag); |
|
488 + Formatting = std::move(RHS.Formatting); |
|
489 + Misc = std::move(RHS.Misc); |
|
490 + Position = std::move(RHS.Position); |
|
491 + AdditionalVals = std::move(RHS.AdditionalVals); |
|
492 + NextRegistered = std::move(RHS.NextRegistered); |
|
493 + ArgStr = std::move(RHS.ArgStr); |
|
494 + HelpStr = std::move(RHS.HelpStr); |
|
495 + ValueStr = std::move(RHS.ValueStr); |
|
496 + Category = std::move(RHS.Category); |
|
497 + FullyInitialized = std::move(RHS.FullyInitialized); |
|
498 + } |
|
499 + |
|
500 + return *this; |
|
501 + } |
|
502 + |
|
503 // addArgument - Register this argument with the commandline system. |
|
504 // |
|
505 void addArgument(); |
|
506 @@ -265,6 +435,32 @@ |
|
507 /// For testing purposes only. |
|
508 void removeArgument(); |
|
509 |
|
510 + static void registerOption(Option *O) { |
|
511 + assert(O && "Invalid argument!"); |
|
512 + |
|
513 + O->NextRegistered = Option::RegisteredOptionList; |
|
514 + Option::RegisteredOptionList = O; |
|
515 + O->OptionIndex = Option::NumRegisteredOptions; |
|
516 + ++Option::NumRegisteredOptions; |
|
517 + O->FullyInitialized = true; |
|
518 + } |
|
519 + |
|
520 + static Option *getRegisteredOptionList() { |
|
521 + return Option::RegisteredOptionList; |
|
522 + } |
|
523 + |
|
524 + static unsigned getNumRegisteredOptions() { |
|
525 + return Option::NumRegisteredOptions; |
|
526 + } |
|
527 + |
|
528 + virtual Option *getNextRegisteredOption() const { |
|
529 + if ((OptionIndex == -1) || |
|
530 + (OptionIndex >= static_cast<int>(Option::NumRegisteredOptions))) |
|
531 + return nullptr; |
|
532 + |
|
533 + return NextRegistered; |
|
534 + } |
|
535 + |
|
536 // Return the width of the option tag for printing... |
|
537 virtual size_t getOptionWidth() const = 0; |
|
538 |
|
539 @@ -275,13 +471,17 @@ |
|
540 |
|
541 virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0; |
|
542 |
|
543 - virtual void getExtraOptionNames(SmallVectorImpl<StringRef> &) {} |
|
544 + virtual void getExtraOptionNames(std::vector<const char*> &V) { } |
|
545 |
|
546 // addOccurrence - Wrapper around handleOccurrence that enforces Flags. |
|
547 // |
|
548 virtual bool addOccurrence(unsigned pos, StringRef ArgName, StringRef Value, |
|
549 bool MultiArg = false); |
|
550 |
|
551 + // addOccurrence - Increment the NumOccurrences counter. |
|
552 + // |
|
553 + virtual void addOccurrence(); |
|
554 + |
|
555 // Prints option name followed by message. Always returns true. |
|
556 bool error(const Twine &Message, StringRef ArgName = StringRef()); |
|
557 |
|
558 @@ -298,6 +498,7 @@ |
|
559 // desc - Modifier to set the description shown in the -help output... |
|
560 struct desc { |
|
561 const char *Desc; |
|
562 + desc() : Desc("") { } |
|
563 desc(const char *Str) : Desc(Str) {} |
|
564 void apply(Option &O) const { O.setDescription(Desc); } |
|
565 }; |
|
566 @@ -306,6 +507,7 @@ |
|
567 // output... |
|
568 struct value_desc { |
|
569 const char *Desc; |
|
570 + value_desc() : Desc("") { } |
|
571 value_desc(const char *Str) : Desc(Str) {} |
|
572 void apply(Option &O) const { O.setValueStr(Desc); } |
|
573 }; |
|
574 @@ -314,29 +516,37 @@ |
|
575 // the default constructor for the argument type does not give you what you |
|
576 // want. This is only valid on "opt" arguments, not on "list" arguments. |
|
577 // |
|
578 -template <class Ty> struct initializer { |
|
579 +template<typename Ty> struct initializer { |
|
580 const Ty &Init; |
|
581 initializer(const Ty &Val) : Init(Val) {} |
|
582 + initializer(const initializer &RHS) : Init(RHS.Init) { } |
|
583 + initializer(initializer &&RHS) : Init(RHS.Init) { } |
|
584 |
|
585 - template <class Opt> void apply(Opt &O) const { O.setInitialValue(Init); } |
|
586 + template <typename Opt> void apply(Opt &O) const { O.setInitialValue(Init); } |
|
587 }; |
|
588 |
|
589 -template <class Ty> initializer<Ty> init(const Ty &Val) { |
|
590 - return initializer<Ty>(Val); |
|
591 +template <typename Ty> |
|
592 +initializer<Ty> init(const Ty &Val) { |
|
593 + llvm::cl::initializer<Ty> I(Val); |
|
594 + return I; |
|
595 } |
|
596 |
|
597 // location - Allow the user to specify which external variable they want to |
|
598 // store the results of the command line argument processing into, if they don't |
|
599 // want to store it in the option itself. |
|
600 // |
|
601 -template <class Ty> struct LocationClass { |
|
602 +template <typename Ty> struct LocationClass { |
|
603 Ty &Loc; |
|
604 + |
|
605 LocationClass(Ty &L) : Loc(L) {} |
|
606 + LocationClass(const LocationClass &RHS) : Loc(RHS.Loc) { } |
|
607 + LocationClass(LocationClass &&RHS) : Loc(RHS.Loc) { } |
|
608 |
|
609 - template <class Opt> void apply(Opt &O) const { O.setLocation(O, Loc); } |
|
610 + template <typename Opt> |
|
611 + void apply(Opt &O) const { O.setLocation(O, Loc); } |
|
612 }; |
|
613 |
|
614 -template <class Ty> LocationClass<Ty> location(Ty &L) { |
|
615 +template <typename Ty> LocationClass<Ty> location(Ty &L) { |
|
616 return LocationClass<Ty>(L); |
|
617 } |
|
618 |
|
619 @@ -344,43 +554,62 @@ |
|
620 // to. |
|
621 struct cat { |
|
622 OptionCategory &Category; |
|
623 - cat(OptionCategory &c) : Category(c) {} |
|
624 |
|
625 - template <class Opt> void apply(Opt &O) const { O.setCategory(Category); } |
|
626 + cat(OptionCategory &C) : Category(C) { } |
|
627 + cat(const cat &RHS) : Category(RHS.Category) { } |
|
628 + virtual ~cat() { } |
|
629 + |
|
630 + template<typename Opt> |
|
631 + void apply(Opt &O) const { O.setCategory(Category); } |
|
632 }; |
|
633 |
|
634 //===----------------------------------------------------------------------===// |
|
635 // OptionValue class |
|
636 |
|
637 // Support value comparison outside the template. |
|
638 -struct GenericOptionValue { |
|
639 +class GenericOptionValue { |
|
640 +public: |
|
641 virtual bool compare(const GenericOptionValue &V) const = 0; |
|
642 |
|
643 protected: |
|
644 - ~GenericOptionValue() = default; |
|
645 - GenericOptionValue() = default; |
|
646 - GenericOptionValue(const GenericOptionValue&) = default; |
|
647 - GenericOptionValue &operator=(const GenericOptionValue &) = default; |
|
648 + virtual ~GenericOptionValue() { } |
|
649 + GenericOptionValue() { } |
|
650 + GenericOptionValue(const GenericOptionValue &RHS) { } |
|
651 + GenericOptionValue(GenericOptionValue &&RHS) { } |
|
652 + GenericOptionValue &operator=(const GenericOptionValue &RHS) { |
|
653 + return *this; |
|
654 + } |
|
655 + |
|
656 + const GenericOptionValue &operator=(GenericOptionValue &&RHS) { |
|
657 + return *this; |
|
658 + } |
|
659 |
|
660 private: |
|
661 virtual void anchor(); |
|
662 }; |
|
663 |
|
664 -template <class DataType> struct OptionValue; |
|
665 +template<typename DataType, bool> class OptionValue; |
|
666 |
|
667 // The default value safely does nothing. Option value printing is only |
|
668 // best-effort. |
|
669 -template <class DataType, bool isClass> |
|
670 -struct OptionValueBase : public GenericOptionValue { |
|
671 +template<typename DataType, bool isClass> |
|
672 +class OptionValueBase : public GenericOptionValue { |
|
673 +public: |
|
674 // Temporary storage for argument passing. |
|
675 - typedef OptionValue<DataType> WrapperType; |
|
676 + typedef OptionValue<DataType, false> WrapperType; |
|
677 |
|
678 bool hasValue() const { return false; } |
|
679 |
|
680 - const DataType &getValue() const { llvm_unreachable("no default value"); } |
|
681 + const DataType &getValue() const { |
|
682 + llvm::errs() << __PRETTY_FUNCTION__ << ": no default value!\n"; |
|
683 + abort(); |
|
684 + } |
|
685 + |
|
686 + void setValue(const DataType &V) { } |
|
687 |
|
688 // Some options may take their value from a different data type. |
|
689 - template <class DT> void setValue(const DT & /*V*/) {} |
|
690 + template<typename DT> |
|
691 + void setValue(const DT &V) { } |
|
692 |
|
693 bool compare(const DataType & /*V*/) const { return false; } |
|
694 |
|
695 @@ -389,21 +618,55 @@ |
|
696 } |
|
697 |
|
698 protected: |
|
699 - ~OptionValueBase() = default; |
|
700 + virtual ~OptionValueBase() { } |
|
701 + |
|
702 +public: |
|
703 + OptionValueBase() : GenericOptionValue() { } |
|
704 }; |
|
705 |
|
706 // Simple copy of the option value. |
|
707 -template <class DataType> class OptionValueCopy : public GenericOptionValue { |
|
708 +template<typename DataType> |
|
709 +class OptionValueCopy : public GenericOptionValue { |
|
710 +protected: |
|
711 DataType Value; |
|
712 bool Valid; |
|
713 |
|
714 -protected: |
|
715 - ~OptionValueCopy() = default; |
|
716 - OptionValueCopy(const OptionValueCopy&) = default; |
|
717 - OptionValueCopy &operator=(const OptionValueCopy&) = default; |
|
718 - |
|
719 public: |
|
720 - OptionValueCopy() : Valid(false) {} |
|
721 + OptionValueCopy<DataType>() |
|
722 + : GenericOptionValue(), Value(), Valid(false) { } |
|
723 + |
|
724 + OptionValueCopy<DataType>(const OptionValueCopy<DataType> &RHS) |
|
725 + : GenericOptionValue(RHS), Value(RHS.Value), Valid(RHS.Valid) { } |
|
726 + |
|
727 + OptionValueCopy<DataType>& |
|
728 + operator=(const OptionValueCopy<DataType> &RHS) { |
|
729 + if (this != &RHS) { |
|
730 + GenericOptionValue::operator=(RHS); |
|
731 + Value = RHS.Value; |
|
732 + Valid = RHS.Valid; |
|
733 + } |
|
734 + |
|
735 + return *this; |
|
736 + } |
|
737 + |
|
738 + const OptionValueCopy<DataType>& |
|
739 + operator=(OptionValueCopy<DataType> &&RHS) { |
|
740 + if (this != &RHS) { |
|
741 + GenericOptionValue::operator=(RHS); |
|
742 + Value = std::move(RHS.Value); |
|
743 + Valid = std::move(RHS.Valid); |
|
744 + } |
|
745 + |
|
746 + return *this; |
|
747 + } |
|
748 + |
|
749 + OptionValueCopy<DataType> &operator=(const DataType& V) { |
|
750 + Value = V; |
|
751 + Valid = true; |
|
752 + return *this; |
|
753 + } |
|
754 + |
|
755 + ~OptionValueCopy<DataType>() { } |
|
756 |
|
757 bool hasValue() const { return Valid; } |
|
758 |
|
759 @@ -417,6 +680,12 @@ |
|
760 Value = V; |
|
761 } |
|
762 |
|
763 + template<typename DT> |
|
764 + void setValue(const DT &V) { |
|
765 + Valid = true; |
|
766 + Value = V; |
|
767 + } |
|
768 + |
|
769 bool compare(const DataType &V) const { return Valid && (Value != V); } |
|
770 |
|
771 bool compare(const GenericOptionValue &V) const override { |
|
772 @@ -429,117 +698,178 @@ |
|
773 }; |
|
774 |
|
775 // Non-class option values. |
|
776 -template <class DataType> |
|
777 -struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> { |
|
778 +template<typename DataType> |
|
779 +class OptionValueBase<DataType, false> : public OptionValueCopy<DataType> { |
|
780 +public: |
|
781 typedef DataType WrapperType; |
|
782 |
|
783 protected: |
|
784 - ~OptionValueBase() = default; |
|
785 - OptionValueBase() = default; |
|
786 - OptionValueBase(const OptionValueBase&) = default; |
|
787 - OptionValueBase &operator=(const OptionValueBase&) = default; |
|
788 + virtual ~OptionValueBase<DataType, false>() { } |
|
789 + |
|
790 + OptionValueBase<DataType, false>() |
|
791 + : OptionValueCopy<DataType>() { } |
|
792 + |
|
793 + OptionValueBase<DataType, false>( |
|
794 + const OptionValueBase<DataType, false> &RHS) |
|
795 + : OptionValueCopy<DataType>(RHS) { } |
|
796 + |
|
797 + OptionValueBase<DataType, false>& |
|
798 + operator=(const OptionValueBase<DataType, false> &RHS) { |
|
799 + if (this != &RHS) |
|
800 + OptionValueCopy<DataType>::operator=(RHS); |
|
801 + |
|
802 + return *this; |
|
803 + } |
|
804 + |
|
805 + const OptionValueBase<DataType, false>& |
|
806 + operator=(OptionValueBase<DataType, false> &&RHS) { |
|
807 + if (this != &RHS) |
|
808 + OptionValueCopy<DataType>::operator=(RHS); |
|
809 + |
|
810 + return *this; |
|
811 + } |
|
812 + |
|
813 + void setValue(const DataType& V) { |
|
814 + OptionValueCopy<DataType>::setValue(V); |
|
815 + } |
|
816 + |
|
817 + template<typename DT> |
|
818 + void setValue(const DT &V) { |
|
819 + OptionValueCopy<DataType>::setValue(V); |
|
820 + } |
|
821 }; |
|
822 |
|
823 // Top-level option class. |
|
824 -template <class DataType> |
|
825 -struct OptionValue final |
|
826 - : OptionValueBase<DataType, std::is_class<DataType>::value> { |
|
827 - OptionValue() = default; |
|
828 +template<typename DataType, bool IsClass = std::is_class<DataType>::value> |
|
829 +class OptionValue final : |
|
830 + public OptionValueBase<DataType, std::is_class<DataType>::value> { |
|
831 +public: |
|
832 + OptionValue<DataType, IsClass>() |
|
833 + : OptionValueBase<DataType, IsClass>() { } |
|
834 + |
|
835 + OptionValue<DataType, IsClass>(const OptionValue<DataType, IsClass> &RHS) |
|
836 + : OptionValueBase<DataType, IsClass>(RHS) { } |
|
837 + |
|
838 + OptionValue<DataType, IsClass>& |
|
839 + operator=(const OptionValue<DataType, IsClass> &RHS) { |
|
840 + if (this != &RHS) { |
|
841 + OptionValueBase<DataType, IsClass>::operator=(RHS); |
|
842 + } |
|
843 + |
|
844 + return *this; |
|
845 + } |
|
846 + |
|
847 + virtual ~OptionValue<DataType, IsClass>() { } |
|
848 + |
|
849 + OptionValue<DataType, IsClass>(const DataType &V) |
|
850 + : OptionValueBase<DataType, IsClass>() { |
|
851 + OptionValueBase<DataType, IsClass>::setValue(V); |
|
852 + } |
|
853 + |
|
854 + void setValue(const DataType &V) { |
|
855 + OptionValueBase<DataType, IsClass>::setValue(V); |
|
856 + } |
|
857 + |
|
858 + template<typename DT> |
|
859 + void setValue(const DT &V) { |
|
860 + OptionValueBase<DataType, IsClass>::setValue(V); |
|
861 + } |
|
862 |
|
863 - OptionValue(const DataType &V) { this->setValue(V); } |
|
864 // Some options may take their value from a different data type. |
|
865 - template <class DT> OptionValue<DataType> &operator=(const DT &V) { |
|
866 - this->setValue(V); |
|
867 + template<typename DT> |
|
868 + OptionValue<DataType, IsClass> &operator=(const DT &V) { |
|
869 + // this->setValue(V); |
|
870 + OptionValueBase<DataType, IsClass>::setValue(V); |
|
871 return *this; |
|
872 } |
|
873 }; |
|
874 |
|
875 // Other safe-to-copy-by-value common option types. |
|
876 enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE }; |
|
877 + |
|
878 template <> |
|
879 -struct OptionValue<cl::boolOrDefault> final |
|
880 - : OptionValueCopy<cl::boolOrDefault> { |
|
881 +class OptionValue<cl::boolOrDefault> final |
|
882 + : public OptionValueCopy<cl::boolOrDefault> { |
|
883 +public: |
|
884 typedef cl::boolOrDefault WrapperType; |
|
885 |
|
886 - OptionValue() {} |
|
887 + OptionValue<cl::boolOrDefault>() |
|
888 + : OptionValueCopy<cl::boolOrDefault>() { } |
|
889 + |
|
890 + OptionValue<cl::boolOrDefault>(const OptionValue<cl::boolOrDefault> &RHS) |
|
891 + : OptionValueCopy<cl::boolOrDefault>(RHS) { } |
|
892 + |
|
893 + OptionValue<cl::boolOrDefault>(const cl::boolOrDefault &V) |
|
894 + : OptionValueCopy<cl::boolOrDefault>() { |
|
895 + this->setValue(V); |
|
896 + } |
|
897 |
|
898 - OptionValue(const cl::boolOrDefault &V) { this->setValue(V); } |
|
899 OptionValue<cl::boolOrDefault> &operator=(const cl::boolOrDefault &V) { |
|
900 setValue(V); |
|
901 return *this; |
|
902 } |
|
903 |
|
904 + OptionValue<cl::boolOrDefault>& |
|
905 + operator=(const OptionValue<cl::boolOrDefault> &RHS) { |
|
906 + if (this != &RHS) { |
|
907 + OptionValueCopy<cl::boolOrDefault>::operator=(RHS); |
|
908 + this->setValue(RHS.getValue()); |
|
909 + } |
|
910 + |
|
911 + return *this; |
|
912 + } |
|
913 + |
|
914 + virtual ~OptionValue<cl::boolOrDefault>() { } |
|
915 + |
|
916 private: |
|
917 void anchor() override; |
|
918 }; |
|
919 |
|
920 template <> |
|
921 -struct OptionValue<std::string> final : OptionValueCopy<std::string> { |
|
922 +class OptionValue<std::string> final : public OptionValueCopy<std::string> { |
|
923 +public: |
|
924 typedef StringRef WrapperType; |
|
925 |
|
926 - OptionValue() {} |
|
927 + OptionValue<std::string>() : OptionValueCopy<std::string>() { } |
|
928 + |
|
929 + OptionValue<std::string>(const OptionValue<std::string> &RHS) |
|
930 + : OptionValueCopy<std::string>(RHS) { } |
|
931 + |
|
932 + OptionValue<std::string>(const std::string &V) { |
|
933 + this->setValue(V); |
|
934 + } |
|
935 + |
|
936 + OptionValue<std::string>(std::string &&V) { |
|
937 + this->setValue(V); |
|
938 + } |
|
939 |
|
940 - OptionValue(const std::string &V) { this->setValue(V); } |
|
941 OptionValue<std::string> &operator=(const std::string &V) { |
|
942 + OptionValueCopy<std::string>::operator=(V); |
|
943 setValue(V); |
|
944 return *this; |
|
945 } |
|
946 |
|
947 -private: |
|
948 - void anchor() override; |
|
949 -}; |
|
950 - |
|
951 -//===----------------------------------------------------------------------===// |
|
952 -// Enum valued command line option |
|
953 -// |
|
954 -#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC |
|
955 -#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC |
|
956 -#define clEnumValEnd (reinterpret_cast<void *>(0)) |
|
957 - |
|
958 -// values - For custom data types, allow specifying a group of values together |
|
959 -// as the values that go into the mapping that the option handler uses. Note |
|
960 -// that the values list must always have a 0 at the end of the list to indicate |
|
961 -// that the list has ended. |
|
962 -// |
|
963 -template <class DataType> class ValuesClass { |
|
964 - // Use a vector instead of a map, because the lists should be short, |
|
965 - // the overhead is less, and most importantly, it keeps them in the order |
|
966 - // inserted so we can print our option out nicely. |
|
967 - SmallVector<std::pair<const char *, std::pair<int, const char *>>, 4> Values; |
|
968 - void processValues(va_list Vals); |
|
969 - |
|
970 -public: |
|
971 - ValuesClass(const char *EnumName, DataType Val, const char *Desc, |
|
972 - va_list ValueArgs) { |
|
973 - // Insert the first value, which is required. |
|
974 - Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc))); |
|
975 - |
|
976 - // Process the varargs portion of the values... |
|
977 - while (const char *enumName = va_arg(ValueArgs, const char *)) { |
|
978 - DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int)); |
|
979 - const char *EnumDesc = va_arg(ValueArgs, const char *); |
|
980 - Values.push_back(std::make_pair(enumName, // Add value to value map |
|
981 - std::make_pair(EnumVal, EnumDesc))); |
|
982 - } |
|
983 + const OptionValue<std::string> &operator=(std::string &&V) { |
|
984 + OptionValueCopy<std::string>::operator=(V); |
|
985 + setValue(V); |
|
986 + return *this; |
|
987 } |
|
988 |
|
989 - template <class Opt> void apply(Opt &O) const { |
|
990 - for (size_t i = 0, e = Values.size(); i != e; ++i) |
|
991 - O.getParser().addLiteralOption(Values[i].first, Values[i].second.first, |
|
992 - Values[i].second.second); |
|
993 + OptionValue<std::string> &operator=(const OptionValue<std::string> &RHS) { |
|
994 + if (this != &RHS) { |
|
995 + OptionValueCopy<std::string>::operator=(RHS); |
|
996 + setValue(RHS.getValue()); |
|
997 } |
|
998 -}; |
|
999 |
|
1000 -template <class DataType> |
|
1001 -ValuesClass<DataType> LLVM_END_WITH_NULL |
|
1002 -values(const char *Arg, DataType Val, const char *Desc, ...) { |
|
1003 - va_list ValueArgs; |
|
1004 - va_start(ValueArgs, Desc); |
|
1005 - ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs); |
|
1006 - va_end(ValueArgs); |
|
1007 - return Vals; |
|
1008 + return *this; |
|
1009 } |
|
1010 |
|
1011 + virtual ~OptionValue<std::string>() { } |
|
1012 + |
|
1013 +private: |
|
1014 + void anchor() override; |
|
1015 +}; |
|
1016 + |
|
1017 //===----------------------------------------------------------------------===// |
|
1018 // parser class - Parameterizable parser for different data types. By default, |
|
1019 // known data types (string, int, bool) have specialized parsers, that do what |
|
1020 @@ -556,20 +886,73 @@ |
|
1021 protected: |
|
1022 class GenericOptionInfo { |
|
1023 public: |
|
1024 + GenericOptionInfo() : Name(""), HelpStr("") { } |
|
1025 + |
|
1026 GenericOptionInfo(const char *name, const char *helpStr) |
|
1027 : Name(name), HelpStr(helpStr) {} |
|
1028 + |
|
1029 + GenericOptionInfo(const GenericOptionInfo &RHS) |
|
1030 + : Name(RHS.Name), HelpStr(RHS.HelpStr) { } |
|
1031 + |
|
1032 + GenericOptionInfo(GenericOptionInfo &&RHS) |
|
1033 + : Name(RHS.Name), HelpStr(RHS.HelpStr) { } |
|
1034 + |
|
1035 + virtual ~GenericOptionInfo() { } |
|
1036 + |
|
1037 + GenericOptionInfo &operator=(const GenericOptionInfo &RHS) { |
|
1038 + if (this != &RHS) { |
|
1039 + Name = RHS.Name; |
|
1040 + HelpStr = RHS.HelpStr; |
|
1041 + } |
|
1042 + |
|
1043 + return *this; |
|
1044 + } |
|
1045 + |
|
1046 + const GenericOptionInfo &operator=(GenericOptionInfo &&RHS) { |
|
1047 + if (this != &RHS) { |
|
1048 + Name = std::move(RHS.Name); |
|
1049 + HelpStr = std::move(RHS.HelpStr); |
|
1050 + } |
|
1051 + |
|
1052 + return *this; |
|
1053 + } |
|
1054 + |
|
1055 const char *Name; |
|
1056 const char *HelpStr; |
|
1057 }; |
|
1058 |
|
1059 + static Option *DefaultInvalidOption; |
|
1060 + |
|
1061 public: |
|
1062 - generic_parser_base(Option &O) : Owner(O) {} |
|
1063 + generic_parser_base() |
|
1064 + : Owner(generic_parser_base::DefaultInvalidOption) { } |
|
1065 + |
|
1066 + generic_parser_base(Option &O) : Owner(&O) { } |
|
1067 + |
|
1068 + generic_parser_base(const generic_parser_base &RHS) |
|
1069 + : Owner(RHS.Owner) { } |
|
1070 + |
|
1071 + generic_parser_base(generic_parser_base &&RHS) |
|
1072 + : Owner(RHS.Owner) { } |
|
1073 + |
|
1074 + virtual ~generic_parser_base() { } |
|
1075 + |
|
1076 + generic_parser_base &operator=(const generic_parser_base &RHS) { |
|
1077 + if (this != &RHS) |
|
1078 + Owner = RHS.Owner; |
|
1079 + |
|
1080 + return *this; |
|
1081 + } |
|
1082 |
|
1083 - virtual ~generic_parser_base() {} // Base class should have virtual-dtor |
|
1084 + const generic_parser_base &operator=(generic_parser_base &&RHS) { |
|
1085 + if (this != &RHS) |
|
1086 + Owner = std::move(RHS.Owner); |
|
1087 + |
|
1088 + return *this; |
|
1089 + } |
|
1090 |
|
1091 // getNumOptions - Virtual function implemented by generic subclass to |
|
1092 // indicate how many entries are in Values. |
|
1093 - // |
|
1094 virtual unsigned getNumOptions() const = 0; |
|
1095 |
|
1096 // getOption - Return option name N. |
|
1097 @@ -597,19 +980,27 @@ |
|
1098 // Template definition ensures that the option and default have the same |
|
1099 // DataType (via the same AnyOptionValue). |
|
1100 template <class AnyOptionValue> |
|
1101 - void printOptionDiff(const Option &O, const AnyOptionValue &V, |
|
1102 + void printOptionDiff(const Option &O, |
|
1103 + const AnyOptionValue &V, |
|
1104 const AnyOptionValue &Default, |
|
1105 size_t GlobalWidth) const { |
|
1106 printGenericOptionDiff(O, V, Default, GlobalWidth); |
|
1107 } |
|
1108 |
|
1109 - void initialize() {} |
|
1110 + virtual bool isValid() const { |
|
1111 + return Owner != DefaultInvalidOption; |
|
1112 + } |
|
1113 + |
|
1114 + virtual void initialize() { } |
|
1115 + virtual void initialize(Option *O) { Owner = O; } |
|
1116 + virtual void initialize(Option &O) { Owner = &O; } |
|
1117 |
|
1118 - void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) { |
|
1119 + virtual void |
|
1120 + getExtraOptionNames(std::vector<const char*> &OptionNames) { |
|
1121 // If there has been no argstr specified, that means that we need to add an |
|
1122 // argument for every possible option. This ensures that our options are |
|
1123 // vectored to us. |
|
1124 - if (!Owner.hasArgStr()) |
|
1125 + if (!Owner->hasArgStr()) |
|
1126 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) |
|
1127 OptionNames.push_back(getOption(i)); |
|
1128 } |
|
1129 @@ -626,7 +1017,7 @@ |
|
1130 // |
|
1131 // If this is the case, we cannot allow a value. |
|
1132 // |
|
1133 - if (Owner.hasArgStr()) |
|
1134 + if (Owner->hasArgStr()) |
|
1135 return ValueRequired; |
|
1136 else |
|
1137 return ValueDisallowed; |
|
1138 @@ -638,7 +1029,7 @@ |
|
1139 unsigned findOption(const char *Name); |
|
1140 |
|
1141 protected: |
|
1142 - Option &Owner; |
|
1143 + Option *Owner; |
|
1144 }; |
|
1145 |
|
1146 // Default parser implementation - This implementation depends on having a |
|
1147 @@ -647,24 +1038,109 @@ |
|
1148 // command line option for -help. Because this is a simple mapping parser, the |
|
1149 // data type can be any unsupported type. |
|
1150 // |
|
1151 -template <class DataType> class parser : public generic_parser_base { |
|
1152 +template<typename DataType> |
|
1153 +class parser : public generic_parser_base { |
|
1154 protected: |
|
1155 class OptionInfo : public GenericOptionInfo { |
|
1156 public: |
|
1157 - OptionInfo(const char *name, DataType v, const char *helpStr) |
|
1158 - : GenericOptionInfo(name, helpStr), V(v) {} |
|
1159 + OptionInfo() : V() { } |
|
1160 + |
|
1161 + OptionInfo(const char *Name, DataType DT, const char *HelpStr) |
|
1162 + : GenericOptionInfo(Name, HelpStr), V(DT) { } |
|
1163 + |
|
1164 + OptionInfo(const OptionInfo &RHS) |
|
1165 + : GenericOptionInfo(RHS), V(RHS.V) { } |
|
1166 + |
|
1167 + OptionInfo(OptionInfo &&RHS) |
|
1168 + : GenericOptionInfo(RHS), V(RHS.V) { } |
|
1169 + |
|
1170 + virtual ~OptionInfo() { } |
|
1171 + |
|
1172 + OptionInfo &operator=(const OptionInfo &RHS) { |
|
1173 + if (this != &RHS) { |
|
1174 + GenericOptionInfo::operator=(RHS); |
|
1175 + V = RHS.V; |
|
1176 + } |
|
1177 + |
|
1178 + return *this; |
|
1179 + } |
|
1180 + |
|
1181 + const OptionInfo &operator=(OptionInfo &&RHS) { |
|
1182 + if (this != &RHS) { |
|
1183 + GenericOptionInfo::operator=(RHS); |
|
1184 + V = std::move(RHS.V); |
|
1185 + } |
|
1186 + |
|
1187 + return *this; |
|
1188 + } |
|
1189 + |
|
1190 + OptionInfo &operator=(const OptionValue<DataType> &RHS) { |
|
1191 + V = RHS; |
|
1192 + return *this; |
|
1193 + } |
|
1194 + |
|
1195 + const OptionInfo &operator=(OptionValue<DataType> &&RHS) { |
|
1196 + V = std::move(RHS); |
|
1197 + return *this; |
|
1198 + } |
|
1199 + |
|
1200 OptionValue<DataType> V; |
|
1201 }; |
|
1202 - SmallVector<OptionInfo, 8> Values; |
|
1203 + |
|
1204 + std::vector<OptionInfo> Values; |
|
1205 |
|
1206 public: |
|
1207 - parser(Option &O) : generic_parser_base(O) {} |
|
1208 + parser<DataType>() |
|
1209 + : generic_parser_base(), Values() { } |
|
1210 + |
|
1211 + parser<DataType>(Option &O) |
|
1212 + : generic_parser_base(O), Values() { } |
|
1213 + |
|
1214 + parser<DataType>(const parser<DataType> &RHS) |
|
1215 + : generic_parser_base(RHS), Values(RHS.Values) { } |
|
1216 + |
|
1217 + parser<DataType>(parser<DataType> &&RHS) |
|
1218 + : generic_parser_base(RHS), Values(RHS.Values) { } |
|
1219 + |
|
1220 + virtual ~parser<DataType>() { } |
|
1221 + |
|
1222 + parser<DataType> &operator=(const parser<DataType> &RHS) { |
|
1223 + if (this != &RHS) { |
|
1224 + generic_parser_base::operator=(RHS); |
|
1225 + Values = RHS.Values; |
|
1226 + } |
|
1227 + |
|
1228 + return *this; |
|
1229 + } |
|
1230 + |
|
1231 + const parser<DataType> &operator=(parser<DataType> &&RHS) { |
|
1232 + if (this != &RHS) { |
|
1233 + generic_parser_base::operator=(RHS); |
|
1234 + Values = std::move(RHS.Values); |
|
1235 + } |
|
1236 + |
|
1237 + return *this; |
|
1238 + } |
|
1239 + |
|
1240 + // Why is this needed. |
|
1241 typedef DataType parser_data_type; |
|
1242 |
|
1243 // Implement virtual functions needed by generic_parser_base |
|
1244 - unsigned getNumOptions() const override { return unsigned(Values.size()); } |
|
1245 - const char *getOption(unsigned N) const override { return Values[N].Name; } |
|
1246 - const char *getDescription(unsigned N) const override { |
|
1247 + virtual unsigned getNumOptions() const override { |
|
1248 + return unsigned(Values.size()); |
|
1249 + } |
|
1250 + |
|
1251 + virtual const char *getOption(unsigned N) const override { |
|
1252 + if (N >= Values.size()) |
|
1253 + return 0UL; |
|
1254 + |
|
1255 + return Values[N].Name; |
|
1256 + } |
|
1257 + |
|
1258 + virtual const char *getDescription(unsigned N) const override { |
|
1259 + if (N >= Values.size()) |
|
1260 + return 0UL; |
|
1261 + |
|
1262 return Values[N].HelpStr; |
|
1263 } |
|
1264 |
|
1265 @@ -676,7 +1152,7 @@ |
|
1266 // parse - Return true on error. |
|
1267 bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) { |
|
1268 StringRef ArgVal; |
|
1269 - if (Owner.hasArgStr()) |
|
1270 + if (Owner->hasArgStr()) |
|
1271 ArgVal = Arg; |
|
1272 else |
|
1273 ArgVal = ArgName; |
|
1274 @@ -690,38 +1166,128 @@ |
|
1275 return O.error("Cannot find option named '" + ArgVal + "'!"); |
|
1276 } |
|
1277 |
|
1278 - /// addLiteralOption - Add an entry to the mapping table. |
|
1279 - /// |
|
1280 - template <class DT> |
|
1281 - void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) { |
|
1282 - assert(findOption(Name) == Values.size() && "Option already exists!"); |
|
1283 - OptionInfo X(Name, static_cast<DataType>(V), HelpStr); |
|
1284 - Values.push_back(X); |
|
1285 - AddLiteralOption(Owner, Name); |
|
1286 + /// addLiteralOption - Add an entry to the mapping table. |
|
1287 + /// |
|
1288 + template <typename DT> |
|
1289 + void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) { |
|
1290 + assert(findOption(Name) == Values.size() && "Option already exists!"); |
|
1291 + OptionInfo X(Name, static_cast<DataType>(V), HelpStr); |
|
1292 + Values.push_back(X); |
|
1293 + AddLiteralOption(*Owner, Name); |
|
1294 + } |
|
1295 + |
|
1296 + void addLiteralOption(const char *Name, const DataType &V, |
|
1297 + const char *HelpStr) { |
|
1298 + assert(findOption(Name) == Values.size() && "Option already exists!"); |
|
1299 + OptionInfo X(Name, V, HelpStr); |
|
1300 + Values.push_back(X); |
|
1301 + } |
|
1302 + |
|
1303 + /// removeLiteralOption - Remove the specified option. |
|
1304 + /// |
|
1305 + void removeLiteralOption(const char *Name) { |
|
1306 + unsigned N = findOption(Name); |
|
1307 + assert(N != Values.size() && "Option not found!"); |
|
1308 + Values.erase(Values.begin() + N); |
|
1309 + } |
|
1310 +}; |
|
1311 + |
|
1312 + |
|
1313 +//===----------------------------------------------------------------------===// |
|
1314 +// Enum valued command line option |
|
1315 +// |
|
1316 +#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC |
|
1317 +#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC |
|
1318 +#define clEnumValEnd (reinterpret_cast<void *>(0)) |
|
1319 + |
|
1320 +// values - For custom data types, allow specifying a group of values together |
|
1321 +// as the values that go into the mapping that the option handler uses. Note |
|
1322 +// that the values list must always have a 0 at the end of the list to indicate |
|
1323 +// that the list has ended. |
|
1324 +// |
|
1325 +template<typename DataType> |
|
1326 +class ValuesClass { |
|
1327 + // Use a vector instead of a map, because the lists should be short, |
|
1328 + // the overhead is less, and most importantly, it keeps them in the order |
|
1329 + // inserted so we can print our option out nicely. |
|
1330 + std::vector<std::pair<const char*, std::pair<int, const char*> > > Values; |
|
1331 + void processValues(va_list Vals); |
|
1332 + |
|
1333 +public: |
|
1334 + ValuesClass<DataType>(const char *EnumName, DataType Val, const char *Desc, |
|
1335 + va_list ValueArgs) |
|
1336 + : Values() { |
|
1337 + // Insert the first value, which is required. |
|
1338 + Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc))); |
|
1339 + |
|
1340 + // Process the varargs portion of the values... |
|
1341 + while (const char *enumName = va_arg(ValueArgs, const char *)) { |
|
1342 + DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int)); |
|
1343 + const char *EnumDesc = va_arg(ValueArgs, const char *); |
|
1344 + |
|
1345 + Values.push_back(std::make_pair(enumName, // Add value to value map |
|
1346 + std::make_pair(EnumVal, EnumDesc))); |
|
1347 + } |
|
1348 + } |
|
1349 + |
|
1350 + ValuesClass<DataType>(const ValuesClass<DataType> &RHS) |
|
1351 + : Values(RHS.Values) { } |
|
1352 + |
|
1353 + ValuesClass<DataType>(ValuesClass<DataType> &&RHS) |
|
1354 + : Values(RHS.Values) { } |
|
1355 + |
|
1356 + ValuesClass<DataType> &operator=(const ValuesClass<DataType> &RHS) { |
|
1357 + if (this != &RHS) |
|
1358 + Values.operator=(RHS.Values); |
|
1359 + |
|
1360 + return *this; |
|
1361 + } |
|
1362 + |
|
1363 + const ValuesClass &operator=(ValuesClass<DataType> &&RHS) { |
|
1364 + if (this != &RHS) |
|
1365 + Values = std::move(RHS.Values); |
|
1366 + |
|
1367 + return *this; |
|
1368 } |
|
1369 |
|
1370 - /// removeLiteralOption - Remove the specified option. |
|
1371 - /// |
|
1372 - void removeLiteralOption(const char *Name) { |
|
1373 - unsigned N = findOption(Name); |
|
1374 - assert(N != Values.size() && "Option not found!"); |
|
1375 - Values.erase(Values.begin() + N); |
|
1376 + ~ValuesClass() { } |
|
1377 + |
|
1378 + template<typename Opt> |
|
1379 + void apply(Opt &O) const { |
|
1380 + for (size_t i = 0, e = Values.size(); i != e; ++i) { |
|
1381 + O.getParser().addLiteralOption(Values[i].first, Values[i].second.first, |
|
1382 + Values[i].second.second); |
|
1383 + } |
|
1384 } |
|
1385 }; |
|
1386 |
|
1387 +template<typename DataType> |
|
1388 +ValuesClass<DataType> LLVM_END_WITH_NULL |
|
1389 +values(const char *Arg, DataType Val, const char *Desc, ...) { |
|
1390 + va_list ValueArgs; |
|
1391 + va_start(ValueArgs, Desc); |
|
1392 + ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs); |
|
1393 + va_end(ValueArgs); |
|
1394 + return Vals; |
|
1395 +} |
|
1396 + |
|
1397 +//===----------------------------------------------------------------------===// |
|
1398 + |
|
1399 //-------------------------------------------------- |
|
1400 // basic_parser - Super class of parsers to provide boilerplate code |
|
1401 // |
|
1402 class basic_parser_impl { // non-template implementation of basic_parser<t> |
|
1403 public: |
|
1404 + basic_parser_impl() { } |
|
1405 basic_parser_impl(Option &) {} |
|
1406 |
|
1407 + virtual ~basic_parser_impl() { } |
|
1408 |
|
1409 enum ValueExpected getValueExpectedFlagDefault() const { |
|
1410 return ValueRequired; |
|
1411 } |
|
1412 |
|
1413 - void getExtraOptionNames(SmallVectorImpl<StringRef> &) {} |
|
1414 + virtual void getExtraOptionNames(std::vector<const char*> &V) { } |
|
1415 |
|
1416 void initialize() {} |
|
1417 |
|
1418 @@ -744,7 +1310,6 @@ |
|
1419 virtual void anchor(); |
|
1420 |
|
1421 protected: |
|
1422 - ~basic_parser_impl() = default; |
|
1423 // A helper for basic_parser::printOptionDiff. |
|
1424 void printOptionName(const Option &O, size_t GlobalWidth) const; |
|
1425 }; |
|
1426 @@ -752,23 +1317,87 @@ |
|
1427 // basic_parser - The real basic parser is just a template wrapper that provides |
|
1428 // a typedef for the provided data type. |
|
1429 // |
|
1430 -template <class DataType> class basic_parser : public basic_parser_impl { |
|
1431 +template<typename DataType> |
|
1432 +class basic_parser : public basic_parser_impl { |
|
1433 public: |
|
1434 - basic_parser(Option &O) : basic_parser_impl(O) {} |
|
1435 + basic_parser<DataType>() : basic_parser_impl(), Values() { } |
|
1436 + basic_parser<DataType>(Option &O) : basic_parser_impl(O), Values() { } |
|
1437 + virtual ~basic_parser<DataType>() { } |
|
1438 + |
|
1439 + virtual unsigned getNumOptions() const { |
|
1440 + return static_cast<unsigned>(Values.size()); |
|
1441 + } |
|
1442 + |
|
1443 + virtual const char *getOption(unsigned I) { |
|
1444 + assert(I < static_cast<unsigned>(Values.size()) && |
|
1445 + "Index is out-of-range!"); |
|
1446 + return Values[I].Name; |
|
1447 + } |
|
1448 + |
|
1449 + virtual const char *getDescription(unsigned I) { |
|
1450 + assert(I < static_cast<unsigned>(Values.size()) && |
|
1451 + "Index is out-of-range!"); |
|
1452 + return Values[I].Help; |
|
1453 + } |
|
1454 + |
|
1455 typedef DataType parser_data_type; |
|
1456 typedef OptionValue<DataType> OptVal; |
|
1457 |
|
1458 protected: |
|
1459 - // Workaround Clang PR22793 |
|
1460 - ~basic_parser() {} |
|
1461 + template<typename SameDataType> |
|
1462 + class OptionInfo { |
|
1463 + public: |
|
1464 + OptionInfo<SameDataType>() |
|
1465 + : Name(""), Help(""), V() { } |
|
1466 + |
|
1467 + OptionInfo<SameDataType>(const char *NameStr, SameDataType DT, |
|
1468 + const char *HelpStr) |
|
1469 + : Name(NameStr), Help(HelpStr), V(DT) { } |
|
1470 + |
|
1471 + OptionInfo<SameDataType>(const OptionInfo<SameDataType> &RHS) |
|
1472 + : Name(RHS.Name), Help(RHS.Help), V(RHS.V) { } |
|
1473 + |
|
1474 + OptionInfo<SameDataType>& |
|
1475 + operator=(const OptionInfo<SameDataType> &RHS) { |
|
1476 + if (this != &RHS) { |
|
1477 + Name = RHS.Name; |
|
1478 + Help = RHS.Help; |
|
1479 + V = RHS.V; |
|
1480 + } |
|
1481 + |
|
1482 + return *this; |
|
1483 + } |
|
1484 + |
|
1485 + const OptionInfo<SameDataType>& |
|
1486 + operator=(OptionInfo<SameDataType> &&RHS) { |
|
1487 + if (this != &RHS) { |
|
1488 + Name = std::move(RHS.Name); |
|
1489 + Help = std::move(RHS.Help); |
|
1490 + V = std::move(RHS.V); |
|
1491 + } |
|
1492 + |
|
1493 + return *this; |
|
1494 + } |
|
1495 + |
|
1496 + ~OptionInfo() { } |
|
1497 + |
|
1498 + const char *Name; |
|
1499 + const char *Help; |
|
1500 + OptionValue<SameDataType> V; |
|
1501 + }; |
|
1502 + |
|
1503 + std::vector<OptionInfo<DataType> > Values; |
|
1504 }; |
|
1505 |
|
1506 //-------------------------------------------------- |
|
1507 // parser<bool> |
|
1508 // |
|
1509 -template <> class parser<bool> final : public basic_parser<bool> { |
|
1510 +template<> |
|
1511 +class parser<bool> final : public basic_parser<bool> { |
|
1512 public: |
|
1513 - parser(Option &O) : basic_parser(O) {} |
|
1514 + parser<bool>() : basic_parser<bool>() { } |
|
1515 + parser<bool>(Option &O) : basic_parser<bool>(O) { } |
|
1516 + virtual ~parser<bool>() { } |
|
1517 |
|
1518 // parse - Return true on error. |
|
1519 bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val); |
|
1520 @@ -782,21 +1411,25 @@ |
|
1521 // getValueName - Do not print =<value> at all. |
|
1522 const char *getValueName() const override { return nullptr; } |
|
1523 |
|
1524 - void printOptionDiff(const Option &O, bool V, OptVal Default, |
|
1525 + void printOptionDiff(const Option &O, const bool &V, |
|
1526 + const llvm::cl::OptionValue<bool> &Default, |
|
1527 size_t GlobalWidth) const; |
|
1528 |
|
1529 // An out-of-line virtual method to provide a 'home' for this class. |
|
1530 - void anchor() override; |
|
1531 + virtual void anchor() override; |
|
1532 }; |
|
1533 |
|
1534 -extern template class basic_parser<bool>; |
|
1535 +// extern template class basic_parser<bool>; |
|
1536 |
|
1537 //-------------------------------------------------- |
|
1538 // parser<boolOrDefault> |
|
1539 template <> |
|
1540 class parser<boolOrDefault> final : public basic_parser<boolOrDefault> { |
|
1541 public: |
|
1542 - parser(Option &O) : basic_parser(O) {} |
|
1543 + |
|
1544 + parser<boolOrDefault>() : basic_parser<boolOrDefault>() { } |
|
1545 + parser<boolOrDefault>(Option &O) : basic_parser<boolOrDefault>(O) { } |
|
1546 + virtual ~parser<boolOrDefault>() { } |
|
1547 |
|
1548 // parse - Return true on error. |
|
1549 bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val); |
|
1550 @@ -808,21 +1441,25 @@ |
|
1551 // getValueName - Do not print =<value> at all. |
|
1552 const char *getValueName() const override { return nullptr; } |
|
1553 |
|
1554 - void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default, |
|
1555 + void printOptionDiff(const Option &O, const boolOrDefault &V, |
|
1556 + const llvm::cl::OptionValue<boolOrDefault> &Default, |
|
1557 size_t GlobalWidth) const; |
|
1558 |
|
1559 // An out-of-line virtual method to provide a 'home' for this class. |
|
1560 - void anchor() override; |
|
1561 + virtual void anchor() override; |
|
1562 }; |
|
1563 |
|
1564 -extern template class basic_parser<boolOrDefault>; |
|
1565 +// extern template class basic_parser<boolOrDefault>; |
|
1566 |
|
1567 //-------------------------------------------------- |
|
1568 // parser<int> |
|
1569 // |
|
1570 -template <> class parser<int> final : public basic_parser<int> { |
|
1571 +template<> |
|
1572 +class parser<int> final : public basic_parser<int> { |
|
1573 public: |
|
1574 - parser(Option &O) : basic_parser(O) {} |
|
1575 + parser<int>() : basic_parser<int>() { } |
|
1576 + parser<int>(Option &O) : basic_parser<int>(O) { } |
|
1577 + virtual ~parser<int>() { } |
|
1578 |
|
1579 // parse - Return true on error. |
|
1580 bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val); |
|
1581 @@ -830,21 +1467,29 @@ |
|
1582 // getValueName - Overload in subclass to provide a better default value. |
|
1583 const char *getValueName() const override { return "int"; } |
|
1584 |
|
1585 - void printOptionDiff(const Option &O, int V, OptVal Default, |
|
1586 + void addLiteralOption(const char *Name, int V, const char *HelpStr) { |
|
1587 + OptionInfo<int> OI(Name, V, HelpStr); |
|
1588 + Values.push_back(OI); |
|
1589 + } |
|
1590 + |
|
1591 + void printOptionDiff(const Option &O, const int &V, |
|
1592 + const llvm::cl::OptionValue<int> &Default, |
|
1593 size_t GlobalWidth) const; |
|
1594 |
|
1595 // An out-of-line virtual method to provide a 'home' for this class. |
|
1596 - void anchor() override; |
|
1597 + virtual void anchor() override; |
|
1598 }; |
|
1599 |
|
1600 -extern template class basic_parser<int>; |
|
1601 +// extern template class basic_parser<int>; |
|
1602 |
|
1603 //-------------------------------------------------- |
|
1604 // parser<unsigned> |
|
1605 // |
|
1606 template <> class parser<unsigned> final : public basic_parser<unsigned> { |
|
1607 public: |
|
1608 - parser(Option &O) : basic_parser(O) {} |
|
1609 + parser<unsigned>() : basic_parser<unsigned>() { } |
|
1610 + parser<unsigned>(Option &O) : basic_parser<unsigned>(O) { } |
|
1611 + virtual ~parser<unsigned>() { } |
|
1612 |
|
1613 // parse - Return true on error. |
|
1614 bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val); |
|
1615 @@ -852,14 +1497,20 @@ |
|
1616 // getValueName - Overload in subclass to provide a better default value. |
|
1617 const char *getValueName() const override { return "uint"; } |
|
1618 |
|
1619 - void printOptionDiff(const Option &O, unsigned V, OptVal Default, |
|
1620 + void addLiteralOption(const char *Name, unsigned V, const char *HelpStr) { |
|
1621 + OptionInfo<unsigned> OI(Name, V, HelpStr); |
|
1622 + Values.push_back(OI); |
|
1623 + } |
|
1624 + |
|
1625 + void printOptionDiff(const Option &O, const unsigned &V, |
|
1626 + const llvm::cl::OptionValue<unsigned> &Default, |
|
1627 size_t GlobalWidth) const; |
|
1628 |
|
1629 // An out-of-line virtual method to provide a 'home' for this class. |
|
1630 - void anchor() override; |
|
1631 + virtual void anchor() override; |
|
1632 }; |
|
1633 |
|
1634 -extern template class basic_parser<unsigned>; |
|
1635 +// extern template class basic_parser<unsigned>; |
|
1636 |
|
1637 //-------------------------------------------------- |
|
1638 // parser<unsigned long long> |
|
1639 @@ -868,7 +1519,10 @@ |
|
1640 class parser<unsigned long long> final |
|
1641 : public basic_parser<unsigned long long> { |
|
1642 public: |
|
1643 - parser(Option &O) : basic_parser(O) {} |
|
1644 + parser<unsigned long long>() : basic_parser<unsigned long long>() { } |
|
1645 + parser<unsigned long long>(Option &O) |
|
1646 + : basic_parser<unsigned long long>(O) { } |
|
1647 + virtual ~parser<unsigned long long>() { } |
|
1648 |
|
1649 // parse - Return true on error. |
|
1650 bool parse(Option &O, StringRef ArgName, StringRef Arg, |
|
1651 @@ -877,21 +1531,31 @@ |
|
1652 // getValueName - Overload in subclass to provide a better default value. |
|
1653 const char *getValueName() const override { return "uint"; } |
|
1654 |
|
1655 - void printOptionDiff(const Option &O, unsigned long long V, OptVal Default, |
|
1656 + void addLiteralOption(const char *Name, unsigned long long V, |
|
1657 + const char *HelpStr) { |
|
1658 + OptionInfo<unsigned long long> OI(Name, V, HelpStr); |
|
1659 + Values.push_back(OI); |
|
1660 + } |
|
1661 + |
|
1662 + void printOptionDiff(const Option &O, const unsigned long long &V, |
|
1663 + const llvm::cl::OptionValue<unsigned long long> &Default, |
|
1664 size_t GlobalWidth) const; |
|
1665 |
|
1666 // An out-of-line virtual method to provide a 'home' for this class. |
|
1667 void anchor() override; |
|
1668 }; |
|
1669 |
|
1670 -extern template class basic_parser<unsigned long long>; |
|
1671 +// extern template class basic_parser<unsigned long long>; |
|
1672 |
|
1673 //-------------------------------------------------- |
|
1674 // parser<double> |
|
1675 // |
|
1676 -template <> class parser<double> final : public basic_parser<double> { |
|
1677 +template<> |
|
1678 +class parser<double> final : public basic_parser<double> { |
|
1679 public: |
|
1680 - parser(Option &O) : basic_parser(O) {} |
|
1681 + parser<double>() : basic_parser<double>() { } |
|
1682 + parser<double>(Option &O) : basic_parser<double>(O) { } |
|
1683 + virtual ~parser<double>() { } |
|
1684 |
|
1685 // parse - Return true on error. |
|
1686 bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val); |
|
1687 @@ -899,21 +1563,31 @@ |
|
1688 // getValueName - Overload in subclass to provide a better default value. |
|
1689 const char *getValueName() const override { return "number"; } |
|
1690 |
|
1691 - void printOptionDiff(const Option &O, double V, OptVal Default, |
|
1692 + void addLiteralOption(const char *Name, double V, |
|
1693 + const char *HelpStr) { |
|
1694 + OptionInfo<double> OI(Name, V, HelpStr); |
|
1695 + Values.push_back(OI); |
|
1696 + } |
|
1697 + |
|
1698 + void printOptionDiff(const Option &O, const double &V, |
|
1699 + const llvm::cl::OptionValue<double> &Default, |
|
1700 size_t GlobalWidth) const; |
|
1701 |
|
1702 // An out-of-line virtual method to provide a 'home' for this class. |
|
1703 - void anchor() override; |
|
1704 + virtual void anchor() override; |
|
1705 }; |
|
1706 |
|
1707 -extern template class basic_parser<double>; |
|
1708 +// extern template class basic_parser<double>; |
|
1709 |
|
1710 //-------------------------------------------------- |
|
1711 // parser<float> |
|
1712 // |
|
1713 -template <> class parser<float> final : public basic_parser<float> { |
|
1714 +template<> |
|
1715 +class parser<float> final : public basic_parser<float> { |
|
1716 public: |
|
1717 - parser(Option &O) : basic_parser(O) {} |
|
1718 + parser<float>() : basic_parser<float>() { } |
|
1719 + parser<float>(Option &O) : basic_parser<float>(O) { } |
|
1720 + virtual ~parser<float>() { } |
|
1721 |
|
1722 // parse - Return true on error. |
|
1723 bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val); |
|
1724 @@ -921,21 +1595,31 @@ |
|
1725 // getValueName - Overload in subclass to provide a better default value. |
|
1726 const char *getValueName() const override { return "number"; } |
|
1727 |
|
1728 - void printOptionDiff(const Option &O, float V, OptVal Default, |
|
1729 + void addLiteralOption(const char *Name, float V, |
|
1730 + const char *HelpStr) { |
|
1731 + OptionInfo<float> OI(Name, V, HelpStr); |
|
1732 + Values.push_back(OI); |
|
1733 + } |
|
1734 + |
|
1735 + void printOptionDiff(const Option &O, const float &V, |
|
1736 + const llvm::cl::OptionValue<float> &Default, |
|
1737 size_t GlobalWidth) const; |
|
1738 |
|
1739 // An out-of-line virtual method to provide a 'home' for this class. |
|
1740 - void anchor() override; |
|
1741 + virtual void anchor() override; |
|
1742 }; |
|
1743 |
|
1744 -extern template class basic_parser<float>; |
|
1745 +// extern template class basic_parser<float>; |
|
1746 |
|
1747 //-------------------------------------------------- |
|
1748 // parser<std::string> |
|
1749 // |
|
1750 -template <> class parser<std::string> final : public basic_parser<std::string> { |
|
1751 +template<> |
|
1752 +class parser<std::string> final : public basic_parser<std::string> { |
|
1753 public: |
|
1754 - parser(Option &O) : basic_parser(O) {} |
|
1755 + parser<std::string>() : basic_parser<std::string>() { } |
|
1756 + parser<std::string>(Option &O) : basic_parser<std::string>(O) {} |
|
1757 + virtual ~parser<std::string>() { } |
|
1758 |
|
1759 // parse - Return true on error. |
|
1760 bool parse(Option &, StringRef, StringRef Arg, std::string &Value) { |
|
1761 @@ -946,21 +1630,31 @@ |
|
1762 // getValueName - Overload in subclass to provide a better default value. |
|
1763 const char *getValueName() const override { return "string"; } |
|
1764 |
|
1765 - void printOptionDiff(const Option &O, StringRef V, OptVal Default, |
|
1766 + void addLiteralOption(const char *Name, const std::string &V, |
|
1767 + const char *HelpStr) { |
|
1768 + OptionInfo<std::string> OI(Name, V, HelpStr); |
|
1769 + Values.push_back(OI); |
|
1770 + } |
|
1771 + |
|
1772 + void printOptionDiff(const Option &O, const std::string &V, |
|
1773 + const llvm::cl::OptionValue<std::string> &Default, |
|
1774 size_t GlobalWidth) const; |
|
1775 |
|
1776 // An out-of-line virtual method to provide a 'home' for this class. |
|
1777 - void anchor() override; |
|
1778 + virtual void anchor() override; |
|
1779 }; |
|
1780 |
|
1781 -extern template class basic_parser<std::string>; |
|
1782 +// extern template class basic_parser<std::string>; |
|
1783 |
|
1784 //-------------------------------------------------- |
|
1785 // parser<char> |
|
1786 // |
|
1787 -template <> class parser<char> final : public basic_parser<char> { |
|
1788 +template<> |
|
1789 +class parser<char> final : public basic_parser<char> { |
|
1790 public: |
|
1791 + parser<char>() : basic_parser<char>() { } |
|
1792 parser(Option &O) : basic_parser(O) {} |
|
1793 + virtual ~parser<char>() { } |
|
1794 |
|
1795 // parse - Return true on error. |
|
1796 bool parse(Option &, StringRef, StringRef Arg, char &Value) { |
|
1797 @@ -971,14 +1665,20 @@ |
|
1798 // getValueName - Overload in subclass to provide a better default value. |
|
1799 const char *getValueName() const override { return "char"; } |
|
1800 |
|
1801 - void printOptionDiff(const Option &O, char V, OptVal Default, |
|
1802 + void addLiteralOption(const char *Name, char V, const char *HelpStr) { |
|
1803 + OptionInfo<char> OI(Name, V, HelpStr); |
|
1804 + Values.push_back(OI); |
|
1805 + } |
|
1806 + |
|
1807 + void printOptionDiff(const Option &O, const char &V, |
|
1808 + const llvm::cl::OptionValue<char> &Default, |
|
1809 size_t GlobalWidth) const; |
|
1810 |
|
1811 // An out-of-line virtual method to provide a 'home' for this class. |
|
1812 - void anchor() override; |
|
1813 + virtual void anchor() override; |
|
1814 }; |
|
1815 |
|
1816 -extern template class basic_parser<char>; |
|
1817 +// extern template class basic_parser<char>; |
|
1818 |
|
1819 //-------------------------------------------------- |
|
1820 // PrintOptionDiff |
|
1821 @@ -987,16 +1687,18 @@ |
|
1822 // parser to handle all the template nastiness. |
|
1823 |
|
1824 // This overloaded function is selected by the generic parser. |
|
1825 -template <class ParserClass, class DT> |
|
1826 -void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V, |
|
1827 - const OptionValue<DT> &Default, size_t GlobalWidth) { |
|
1828 +template<typename ParserClass, typename DT> |
|
1829 +void printOptionDiff(const Option &O, const generic_parser_base &P, |
|
1830 + const DT &V, const OptionValue<DT> &Default, |
|
1831 + size_t GlobalWidth) { |
|
1832 OptionValue<DT> OV = V; |
|
1833 P.printOptionDiff(O, OV, Default, GlobalWidth); |
|
1834 } |
|
1835 |
|
1836 // This is instantiated for basic parsers when the parsed value has a different |
|
1837 // type than the option value. e.g. HelpPrinter. |
|
1838 -template <class ParserDT, class ValDT> struct OptionDiffPrinter { |
|
1839 +template<typename ParserDT, typename ValDT> |
|
1840 +struct OptionDiffPrinter { |
|
1841 void print(const Option &O, const parser<ParserDT> &P, const ValDT & /*V*/, |
|
1842 const OptionValue<ValDT> & /*Default*/, size_t GlobalWidth) { |
|
1843 P.printOptionNoValue(O, GlobalWidth); |
|
1844 @@ -1005,7 +1707,8 @@ |
|
1845 |
|
1846 // This is instantiated for basic parsers when the parsed value has the same |
|
1847 // type as the option value. |
|
1848 -template <class DT> struct OptionDiffPrinter<DT, DT> { |
|
1849 +template<typename DT> |
|
1850 +struct OptionDiffPrinter<DT, DT> { |
|
1851 void print(const Option &O, const parser<DT> &P, const DT &V, |
|
1852 const OptionValue<DT> &Default, size_t GlobalWidth) { |
|
1853 P.printOptionDiff(O, V, Default, GlobalWidth); |
|
1854 @@ -1014,11 +1717,11 @@ |
|
1855 |
|
1856 // This overloaded function is selected by the basic parser, which may parse a |
|
1857 // different type than the option type. |
|
1858 -template <class ParserClass, class ValDT> |
|
1859 -void printOptionDiff( |
|
1860 - const Option &O, |
|
1861 +template<typename ParserClass, typename ValDT> |
|
1862 +void printOptionDiff(const Option &O, |
|
1863 const basic_parser<typename ParserClass::parser_data_type> &P, |
|
1864 - const ValDT &V, const OptionValue<ValDT> &Default, size_t GlobalWidth) { |
|
1865 + const ValDT &V, const OptionValue<ValDT> &Default, |
|
1866 + size_t GlobalWidth) { |
|
1867 |
|
1868 OptionDiffPrinter<typename ParserClass::parser_data_type, ValDT> printer; |
|
1869 printer.print(O, static_cast<const ParserClass &>(P), V, Default, |
|
1870 @@ -1031,53 +1734,70 @@ |
|
1871 // not correctly respond to the apply method). Because the syntax to use this |
|
1872 // is a pain, we have the 'apply' method below to handle the nastiness... |
|
1873 // |
|
1874 -template <class Mod> struct applicator { |
|
1875 - template <class Opt> static void opt(const Mod &M, Opt &O) { M.apply(O); } |
|
1876 +template<typename Mod> |
|
1877 +struct applicator { |
|
1878 + template<typename Opt> |
|
1879 + static void opt(const Mod &M, Opt &O) { M.apply(O); } |
|
1880 }; |
|
1881 |
|
1882 // Handle const char* as a special case... |
|
1883 -template <unsigned n> struct applicator<char[n]> { |
|
1884 - template <class Opt> static void opt(const char *Str, Opt &O) { |
|
1885 +template<unsigned N> |
|
1886 +struct applicator<char[N]> { |
|
1887 + template <typename Opt> static void opt(const char *Str, Opt &O) { |
|
1888 O.setArgStr(Str); |
|
1889 } |
|
1890 }; |
|
1891 -template <unsigned n> struct applicator<const char[n]> { |
|
1892 + |
|
1893 +template<unsigned N> |
|
1894 +struct applicator<const char[N]> { |
|
1895 template <class Opt> static void opt(const char *Str, Opt &O) { |
|
1896 O.setArgStr(Str); |
|
1897 } |
|
1898 }; |
|
1899 -template <> struct applicator<const char *> { |
|
1900 + |
|
1901 +template<> |
|
1902 +struct applicator<const char *> { |
|
1903 template <class Opt> static void opt(const char *Str, Opt &O) { |
|
1904 O.setArgStr(Str); |
|
1905 } |
|
1906 }; |
|
1907 |
|
1908 -template <> struct applicator<NumOccurrencesFlag> { |
|
1909 +template<> |
|
1910 +struct applicator<NumOccurrencesFlag> { |
|
1911 static void opt(NumOccurrencesFlag N, Option &O) { |
|
1912 O.setNumOccurrencesFlag(N); |
|
1913 } |
|
1914 }; |
|
1915 -template <> struct applicator<ValueExpected> { |
|
1916 + |
|
1917 +template<> |
|
1918 +struct applicator<ValueExpected> { |
|
1919 static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); } |
|
1920 }; |
|
1921 -template <> struct applicator<OptionHidden> { |
|
1922 + |
|
1923 +template<> |
|
1924 +struct applicator<OptionHidden> { |
|
1925 static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); } |
|
1926 }; |
|
1927 -template <> struct applicator<FormattingFlags> { |
|
1928 + |
|
1929 +template<> |
|
1930 +struct applicator<FormattingFlags> { |
|
1931 static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); } |
|
1932 }; |
|
1933 -template <> struct applicator<MiscFlags> { |
|
1934 + |
|
1935 +template<> |
|
1936 +struct applicator<MiscFlags> { |
|
1937 static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); } |
|
1938 }; |
|
1939 |
|
1940 // apply method - Apply modifiers to an option in a type safe way. |
|
1941 -template <class Opt, class Mod, class... Mods> |
|
1942 +template<typename Opt, typename Mod, typename... Mods> |
|
1943 void apply(Opt *O, const Mod &M, const Mods &... Ms) { |
|
1944 applicator<Mod>::opt(M, *O); |
|
1945 apply(O, Ms...); |
|
1946 } |
|
1947 |
|
1948 -template <class Opt, class Mod> void apply(Opt *O, const Mod &M) { |
|
1949 +template<typename Opt, typename Mod> |
|
1950 +void apply(Opt *O, const Mod &M) { |
|
1951 applicator<Mod>::opt(M, *O); |
|
1952 } |
|
1953 |
|
1954 @@ -1088,39 +1808,101 @@ |
|
1955 // assumes the user will specify a variable to store the data into with the |
|
1956 // cl::location(x) modifier. |
|
1957 // |
|
1958 -template <class DataType, bool ExternalStorage, bool isClass> |
|
1959 -class opt_storage { |
|
1960 +template<typename DataType, bool ExternalStorage, bool isClass> |
|
1961 +class LLVM_ALIGNAS(8) opt_storage { |
|
1962 +private: |
|
1963 DataType *Location; // Where to store the object... |
|
1964 OptionValue<DataType> Default; |
|
1965 |
|
1966 +protected: |
|
1967 void check_location() const { |
|
1968 assert(Location && "cl::location(...) not specified for a command " |
|
1969 "line option with external storage, " |
|
1970 "or cl::init specified before cl::location()!!"); |
|
1971 + if (!Location) { |
|
1972 + llvm::errs() << __PRETTY_FUNCTION__ |
|
1973 + << ": cl::location(...) not specified for a command " |
|
1974 + << "line option with external storage, " |
|
1975 + << "or cl::init specified before cl::location()!!\n"; |
|
1976 + abort(); |
|
1977 + } |
|
1978 } |
|
1979 |
|
1980 public: |
|
1981 - opt_storage() : Location(nullptr) {} |
|
1982 + opt_storage<DataType, ExternalStorage, isClass>() |
|
1983 + : Location(nullptr), Default() { } |
|
1984 + |
|
1985 + opt_storage<DataType, ExternalStorage, isClass>( |
|
1986 + const opt_storage<DataType, ExternalStorage, isClass> &RHS) |
|
1987 + : Location(RHS.Location), Default(RHS.Default) { } |
|
1988 + |
|
1989 + opt_storage<DataType, ExternalStorage, isClass>( |
|
1990 + opt_storage<DataType, ExternalStorage, isClass> &&RHS) |
|
1991 + : Location(RHS.Location), Default(RHS.Default) { } |
|
1992 + |
|
1993 + virtual ~opt_storage<DataType, ExternalStorage, isClass>() { } |
|
1994 + |
|
1995 + opt_storage<DataType, ExternalStorage, isClass>& |
|
1996 + operator=(const opt_storage<DataType, ExternalStorage, isClass> &RHS) { |
|
1997 + if (this != &RHS) { |
|
1998 + Location = RHS.Location; |
|
1999 + Default = RHS.Default; |
|
2000 + } |
|
2001 + |
|
2002 + return *this; |
|
2003 + } |
|
2004 + |
|
2005 + const opt_storage<DataType, ExternalStorage, isClass>& |
|
2006 + operator=(opt_storage<DataType, ExternalStorage, isClass> &&RHS) { |
|
2007 + if (this != &RHS) { |
|
2008 + Location = std::move(RHS.Location); |
|
2009 + Default = std::move(RHS.Default); |
|
2010 + } |
|
2011 + |
|
2012 + return *this; |
|
2013 + } |
|
2014 |
|
2015 bool setLocation(Option &O, DataType &L) { |
|
2016 if (Location) |
|
2017 return O.error("cl::location(x) specified more than once!"); |
|
2018 + |
|
2019 Location = &L; |
|
2020 Default = L; |
|
2021 return false; |
|
2022 } |
|
2023 |
|
2024 - template <class T> void setValue(const T &V, bool initial = false) { |
|
2025 + void setValue(const DataType &V, bool initial = false) { |
|
2026 check_location(); |
|
2027 - *Location = V; |
|
2028 - if (initial) |
|
2029 + |
|
2030 + DataType *DT = |
|
2031 + reinterpret_cast<DataType*>( |
|
2032 + const_cast<void*>(reinterpret_cast<const void*>(&V))); |
|
2033 + Location = DT; |
|
2034 + |
|
2035 + if (initial) { |
|
2036 + Default = V; |
|
2037 + } |
|
2038 + } |
|
2039 + |
|
2040 + template<typename T> |
|
2041 + void setValue(const T &V, bool initial = false) { |
|
2042 + check_location(); |
|
2043 + |
|
2044 + DataType *DT = |
|
2045 + reinterpret_cast<DataType*>( |
|
2046 + const_cast<void*>(reinterpret_cast<const void*>(&V))); |
|
2047 + Location = DT; |
|
2048 + |
|
2049 + if (initial) { |
|
2050 Default = V; |
|
2051 + } |
|
2052 } |
|
2053 |
|
2054 DataType &getValue() { |
|
2055 check_location(); |
|
2056 return *Location; |
|
2057 } |
|
2058 + |
|
2059 const DataType &getValue() const { |
|
2060 check_location(); |
|
2061 return *Location; |
|
2062 @@ -1134,14 +1916,66 @@ |
|
2063 // Define how to hold a class type object, such as a string. Since we can |
|
2064 // inherit from a class, we do so. This makes us exactly compatible with the |
|
2065 // object in all cases that it is used. |
|
2066 -// |
|
2067 -template <class DataType> |
|
2068 -class opt_storage<DataType, false, true> : public DataType { |
|
2069 +template<typename DataType> |
|
2070 +class LLVM_ALIGNAS(8) opt_storage<DataType, false, true> : public DataType { |
|
2071 public: |
|
2072 + DataType *Location; |
|
2073 OptionValue<DataType> Default; |
|
2074 |
|
2075 - template <class T> void setValue(const T &V, bool initial = false) { |
|
2076 + opt_storage<DataType, false, true>() |
|
2077 + : DataType(), Location(nullptr), Default() { } |
|
2078 + |
|
2079 + opt_storage<DataType, false, true>( |
|
2080 + const opt_storage<DataType, false, true> &RHS) |
|
2081 + : DataType(RHS), Location(RHS.Location), Default(RHS.Default) { } |
|
2082 + |
|
2083 + opt_storage<DataType, false, true>(opt_storage<DataType, false, true> &&RHS) |
|
2084 + : DataType(RHS), Location(RHS.Location), Default(RHS.Default) { } |
|
2085 + |
|
2086 + virtual ~opt_storage<DataType, false, true>() { } |
|
2087 + |
|
2088 + opt_storage<DataType, false, true> |
|
2089 + &operator=(const opt_storage<DataType, false, true> &RHS) { |
|
2090 + if (this != &RHS) { |
|
2091 + DataType::operator=(RHS); |
|
2092 + Location = RHS.Location; |
|
2093 + Default = RHS.Default; |
|
2094 + } |
|
2095 + |
|
2096 + return *this; |
|
2097 + } |
|
2098 + |
|
2099 + const opt_storage<DataType, false, true> |
|
2100 + &operator=(opt_storage<DataType, false, true> &&RHS) { |
|
2101 + if (this != &RHS) { |
|
2102 + DataType::operator=(RHS); |
|
2103 + Location = std::move(RHS.Location); |
|
2104 + Default = std::move(RHS.Default); |
|
2105 + } |
|
2106 + |
|
2107 + return *this; |
|
2108 + } |
|
2109 + |
|
2110 + bool setLocation(Option &O, DataType &L) { |
|
2111 + if (Location) |
|
2112 + return O.error("cl::location(x) specified more than once!"); |
|
2113 + |
|
2114 + Location = &L; |
|
2115 + Default = L; |
|
2116 + return false; |
|
2117 + } |
|
2118 + |
|
2119 + void setValue(const DataType &V, bool initial = false) { |
|
2120 DataType::operator=(V); |
|
2121 + |
|
2122 + if (initial) |
|
2123 + Default = V; |
|
2124 + } |
|
2125 + |
|
2126 + template<typename T> |
|
2127 + void setValue(const T &V, bool initial = false) { |
|
2128 + DataType::operator=(V); |
|
2129 + |
|
2130 if (initial) |
|
2131 Default = V; |
|
2132 } |
|
2133 @@ -1155,27 +1989,68 @@ |
|
2134 // Define a partial specialization to handle things we cannot inherit from. In |
|
2135 // this case, we store an instance through containment, and overload operators |
|
2136 // to get at the value. |
|
2137 -// |
|
2138 -template <class DataType> class opt_storage<DataType, false, false> { |
|
2139 +template<typename DataType> |
|
2140 +class LLVM_ALIGNAS(8) opt_storage<DataType, false, false> { |
|
2141 public: |
|
2142 DataType Value; |
|
2143 OptionValue<DataType> Default; |
|
2144 |
|
2145 // Make sure we initialize the value with the default constructor for the |
|
2146 // type. |
|
2147 - opt_storage() : Value(DataType()), Default(DataType()) {} |
|
2148 + opt_storage<DataType, false, false>() : Value(), Default() { } |
|
2149 + |
|
2150 + opt_storage<DataType, false, false>( |
|
2151 + const opt_storage<DataType, false, false> &RHS) |
|
2152 + : Value(RHS.Value), Default(RHS.Default) { } |
|
2153 + |
|
2154 + opt_storage<DataType, false, false>(opt_storage<DataType, false, false> &&RHS) |
|
2155 + : Value(std::move(RHS.Value)), Default(std::move(RHS.Default)) { } |
|
2156 + |
|
2157 + opt_storage<DataType, false, false> |
|
2158 + &operator=(const opt_storage<DataType, false, false> &RHS) { |
|
2159 + if (this != &RHS) { |
|
2160 + Value = RHS.Value; |
|
2161 + Default = RHS.Default; |
|
2162 + } |
|
2163 + |
|
2164 + return *this; |
|
2165 + } |
|
2166 + |
|
2167 + const opt_storage<DataType, false, false> |
|
2168 + &operator=(opt_storage<DataType, false, false> &&RHS) { |
|
2169 + if (this != &RHS) { |
|
2170 + Value = std::move(RHS.Value); |
|
2171 + Default = std::move(RHS.Default); |
|
2172 + } |
|
2173 + |
|
2174 + return *this; |
|
2175 + } |
|
2176 |
|
2177 - template <class T> void setValue(const T &V, bool initial = false) { |
|
2178 + bool setLocation(Option &O, DataType &L) { |
|
2179 + Value = L; |
|
2180 + Default = Value; |
|
2181 + return false; |
|
2182 + } |
|
2183 + |
|
2184 + void setValue(const DataType &V, bool initial = false) { |
|
2185 + Value = V; |
|
2186 + if (initial) |
|
2187 + Default = V; |
|
2188 + } |
|
2189 + |
|
2190 + template<typename T> |
|
2191 + void setValue(const T &V, bool initial = false) { |
|
2192 Value = V; |
|
2193 if (initial) |
|
2194 Default = V; |
|
2195 } |
|
2196 + |
|
2197 DataType &getValue() { return Value; } |
|
2198 DataType getValue() const { return Value; } |
|
2199 |
|
2200 const OptionValue<DataType> &getDefault() const { return Default; } |
|
2201 |
|
2202 - operator DataType() const { return getValue(); } |
|
2203 + operator DataType() const { return Value; } |
|
2204 |
|
2205 // If the datatype is a pointer, support -> on it. |
|
2206 DataType operator->() const { return Value; } |
|
2207 @@ -1184,19 +2059,57 @@ |
|
2208 //===----------------------------------------------------------------------===// |
|
2209 // opt - A scalar command line option. |
|
2210 // |
|
2211 -template <class DataType, bool ExternalStorage = false, |
|
2212 - class ParserClass = parser<DataType>> |
|
2213 -class opt : public Option, |
|
2214 - public opt_storage<DataType, ExternalStorage, |
|
2215 - std::is_class<DataType>::value> { |
|
2216 +template<typename DataType, bool ExternalStorage = false, |
|
2217 + typename ParserClass = parser<DataType> > |
|
2218 +class LLVM_ALIGNAS(8) opt : public Option, |
|
2219 + public opt_storage<DataType, ExternalStorage, |
|
2220 + std::is_class<DataType>::value> { |
|
2221 ParserClass Parser; |
|
2222 |
|
2223 - bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2224 +public: |
|
2225 + opt<DataType, ExternalStorage, ParserClass>() |
|
2226 + : Option(), opt_storage<DataType, ExternalStorage, |
|
2227 + std::is_class<DataType>::value>(), Parser(*this) { } |
|
2228 + |
|
2229 + opt<DataType, ExternalStorage, ParserClass>( |
|
2230 + const opt<DataType, ExternalStorage, ParserClass> &RHS) : Option(RHS), |
|
2231 + opt_storage<DataType, ExternalStorage, |
|
2232 + std::is_class<DataType>::value>(RHS), Parser(RHS.Parser) { } |
|
2233 + |
|
2234 + opt<DataType, ExternalStorage, ParserClass>& |
|
2235 + operator=(const opt<DataType, ExternalStorage, ParserClass> &RHS) { |
|
2236 + if (this != &RHS) { |
|
2237 + Option::operator=(RHS); |
|
2238 + opt_storage<DataType, ExternalStorage, |
|
2239 + std::is_class<DataType>::value>::operator=(RHS); |
|
2240 + Parser = RHS.Parser; |
|
2241 + } |
|
2242 + |
|
2243 + return *this; |
|
2244 + } |
|
2245 + |
|
2246 + const opt<DataType, ExternalStorage, ParserClass>& |
|
2247 + operator=(opt<DataType, ExternalStorage, ParserClass> &&RHS) { |
|
2248 + if (this != &RHS) { |
|
2249 + Option::operator=(RHS); |
|
2250 + opt_storage<DataType, ExternalStorage, |
|
2251 + std::is_class<DataType>::value>::operator=(RHS); |
|
2252 + Parser = std::move(RHS.Parser); |
|
2253 + } |
|
2254 + |
|
2255 + return *this; |
|
2256 + } |
|
2257 + |
|
2258 + virtual ~opt<DataType, ExternalStorage, ParserClass>() { } |
|
2259 + |
|
2260 +protected: |
|
2261 + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2262 StringRef Arg) override { |
|
2263 typename ParserClass::parser_data_type Val = |
|
2264 typename ParserClass::parser_data_type(); |
|
2265 if (Parser.parse(*this, ArgName, Arg, Val)) |
|
2266 return true; // Parse error! |
|
2267 + |
|
2268 this->setValue(Val); |
|
2269 this->setPosition(pos); |
|
2270 return false; |
|
2271 @@ -1205,7 +2118,9 @@ |
|
2272 enum ValueExpected getValueExpectedFlagDefault() const override { |
|
2273 return Parser.getValueExpectedFlagDefault(); |
|
2274 } |
|
2275 - void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { |
|
2276 + |
|
2277 + virtual void |
|
2278 + getExtraOptionNames(std::vector<const char*> &OptionNames) override { |
|
2279 return Parser.getExtraOptionNames(OptionNames); |
|
2280 } |
|
2281 |
|
2282 @@ -1213,6 +2128,7 @@ |
|
2283 size_t getOptionWidth() const override { |
|
2284 return Parser.getOptionWidth(*this); |
|
2285 } |
|
2286 + |
|
2287 void printOptionInfo(size_t GlobalWidth) const override { |
|
2288 Parser.printOptionInfo(*this, GlobalWidth); |
|
2289 } |
|
2290 @@ -1229,34 +2145,44 @@ |
|
2291 Parser.initialize(); |
|
2292 } |
|
2293 |
|
2294 - // Command line options should not be copyable |
|
2295 - opt(const opt &) = delete; |
|
2296 - opt &operator=(const opt &) = delete; |
|
2297 - |
|
2298 public: |
|
2299 // setInitialValue - Used by the cl::init modifier... |
|
2300 void setInitialValue(const DataType &V) { this->setValue(V, true); } |
|
2301 |
|
2302 + bool setLocation(Option &O, DataType &L) { |
|
2303 + bool R = opt_storage<DataType, ExternalStorage, |
|
2304 + std::is_class<DataType>::value>::setLocation(O, L); |
|
2305 + return R; |
|
2306 + } |
|
2307 + |
|
2308 + void addArgument() { |
|
2309 + assert(!NextRegistered && "argument multiply registered!"); |
|
2310 + Option::registerOption(this); |
|
2311 + } |
|
2312 + |
|
2313 ParserClass &getParser() { return Parser; } |
|
2314 |
|
2315 - template <class T> DataType &operator=(const T &Val) { |
|
2316 + template<typename T> DataType &operator=(const T &Val) { |
|
2317 this->setValue(Val); |
|
2318 return this->getValue(); |
|
2319 } |
|
2320 |
|
2321 - template <class... Mods> |
|
2322 + template <typename... Mods> |
|
2323 explicit opt(const Mods &... Ms) |
|
2324 - : Option(Optional, NotHidden), Parser(*this) { |
|
2325 + : Option(Optional, NotHidden), |
|
2326 + opt_storage<DataType, ExternalStorage, std::is_class<DataType>::value>(), |
|
2327 + Parser(*this) { |
|
2328 apply(this, Ms...); |
|
2329 done(); |
|
2330 } |
|
2331 }; |
|
2332 |
|
2333 -extern template class opt<unsigned>; |
|
2334 -extern template class opt<int>; |
|
2335 -extern template class opt<std::string>; |
|
2336 -extern template class opt<char>; |
|
2337 -extern template class opt<bool>; |
|
2338 +// extern template class opt<unsigned>; |
|
2339 +// extern template class opt<int>; |
|
2340 +// extern template class opt<std::string>; |
|
2341 +// extern template class opt<char>; |
|
2342 +// extern template class opt<bool>; |
|
2343 +// extern template class opt<unsigned long long>; |
|
2344 |
|
2345 //===----------------------------------------------------------------------===// |
|
2346 // list_storage class |
|
2347 @@ -1265,22 +2191,72 @@ |
|
2348 // assumes the user will specify a variable to store the data into with the |
|
2349 // cl::location(x) modifier. |
|
2350 // |
|
2351 -template <class DataType, class StorageClass> class list_storage { |
|
2352 +template<typename DataType, typename StorageClass> |
|
2353 +class list_storage { |
|
2354 +private: |
|
2355 StorageClass *Location; // Where to store the object... |
|
2356 |
|
2357 public: |
|
2358 - list_storage() : Location(0) {} |
|
2359 + list_storage<DataType, StorageClass>() : Location(nullptr) { } |
|
2360 + |
|
2361 + list_storage<DataType, StorageClass>( |
|
2362 + const list_storage<DataType, StorageClass> &RHS) |
|
2363 + : Location(RHS.Location) { } |
|
2364 + |
|
2365 + list_storage<DataType, StorageClass>( |
|
2366 + list_storage<DataType, StorageClass> &&RHS) |
|
2367 + : Location(RHS.Location) { } |
|
2368 + |
|
2369 + virtual ~list_storage<DataType, StorageClass>() { } |
|
2370 + |
|
2371 + list_storage<DataType, StorageClass>& |
|
2372 + operator=(const list_storage<DataType, StorageClass> &RHS) { |
|
2373 + if (this != &RHS) |
|
2374 + Location = RHS.Location; |
|
2375 + |
|
2376 + return *this; |
|
2377 + } |
|
2378 + |
|
2379 + const list_storage<DataType, StorageClass>& |
|
2380 + operator=(list_storage<DataType, StorageClass> &&RHS) { |
|
2381 + if (this != &RHS) |
|
2382 + Location = std::move(RHS.Location); |
|
2383 + |
|
2384 + return *this; |
|
2385 + } |
|
2386 |
|
2387 bool setLocation(Option &O, StorageClass &L) { |
|
2388 if (Location) |
|
2389 return O.error("cl::location(x) specified more than once!"); |
|
2390 + |
|
2391 Location = &L; |
|
2392 return false; |
|
2393 } |
|
2394 |
|
2395 - template <class T> void addValue(const T &V) { |
|
2396 + void addValue(const DataType &V) { |
|
2397 + assert(Location != 0 && "cl::location(...) not specified for a command " |
|
2398 + "line option with external storage!"); |
|
2399 + if (!Location) { |
|
2400 + llvm::errs() << __PRETTY_FUNCTION__ |
|
2401 + << ": cl::location(...) not specified for a command " |
|
2402 + << "line option with external storage!\n"; |
|
2403 + abort(); |
|
2404 + } |
|
2405 + |
|
2406 + Location->push_back(V); |
|
2407 + } |
|
2408 + |
|
2409 + template <typename T> |
|
2410 + void addValue(const T &V) { |
|
2411 assert(Location != 0 && "cl::location(...) not specified for a command " |
|
2412 "line option with external storage!"); |
|
2413 + if (!Location) { |
|
2414 + llvm::errs() << __PRETTY_FUNCTION__ |
|
2415 + << ": cl::location(...) not specified for a command " |
|
2416 + << "line option with external storage!\n"; |
|
2417 + abort(); |
|
2418 + } |
|
2419 + |
|
2420 Location->push_back(V); |
|
2421 } |
|
2422 }; |
|
2423 @@ -1293,10 +2269,24 @@ |
|
2424 // |
|
2425 // FIXME: Reduce this API to a more narrow subset of std::vector |
|
2426 // |
|
2427 -template <class DataType> class list_storage<DataType, bool> { |
|
2428 +template <typename DataType> |
|
2429 +class list_storage<DataType, bool> { |
|
2430 std::vector<DataType> Storage; |
|
2431 |
|
2432 public: |
|
2433 + list_storage<DataType, bool>() : Storage() { } |
|
2434 + list_storage<DataType, bool>(const list_storage<DataType, bool> &RHS) |
|
2435 + : Storage(RHS.Storage) { } |
|
2436 + virtual ~list_storage<DataType, bool>() { } |
|
2437 + |
|
2438 + list_storage<DataType, bool> |
|
2439 + &operator=(const list_storage<DataType, bool> &RHS) { |
|
2440 + if (this != &RHS) |
|
2441 + Storage = RHS.Storage; |
|
2442 + |
|
2443 + return *this; |
|
2444 + } |
|
2445 + |
|
2446 typedef typename std::vector<DataType>::iterator iterator; |
|
2447 |
|
2448 iterator begin() { return Storage.begin(); } |
|
2449 @@ -1332,6 +2322,7 @@ |
|
2450 iterator insert(const_iterator pos, const DataType &value) { |
|
2451 return Storage.insert(pos, value); |
|
2452 } |
|
2453 + |
|
2454 iterator insert(const_iterator pos, DataType &&value) { |
|
2455 return Storage.insert(pos, value); |
|
2456 } |
|
2457 @@ -1339,6 +2330,7 @@ |
|
2458 iterator insert(iterator pos, const DataType &value) { |
|
2459 return Storage.insert(pos, value); |
|
2460 } |
|
2461 + |
|
2462 iterator insert(iterator pos, DataType &&value) { |
|
2463 return Storage.insert(pos, value); |
|
2464 } |
|
2465 @@ -1351,48 +2343,68 @@ |
|
2466 std::vector<DataType> *operator&() { return &Storage; } |
|
2467 const std::vector<DataType> *operator&() const { return &Storage; } |
|
2468 |
|
2469 - template <class T> void addValue(const T &V) { Storage.push_back(V); } |
|
2470 + template<typename T> |
|
2471 + void addValue(const T &V) { |
|
2472 + T LV(V); |
|
2473 + Storage.push_back(LV); |
|
2474 + } |
|
2475 + |
|
2476 + void addValue(const DataType &V) { |
|
2477 + DataType LV(V); |
|
2478 + Storage.push_back(LV); |
|
2479 + } |
|
2480 + |
|
2481 + const std::vector<DataType> &getStorage() const { |
|
2482 + return Storage; |
|
2483 + } |
|
2484 }; |
|
2485 |
|
2486 //===----------------------------------------------------------------------===// |
|
2487 // list - A list of command line options. |
|
2488 // |
|
2489 -template <class DataType, class StorageClass = bool, |
|
2490 - class ParserClass = parser<DataType>> |
|
2491 +template<typename DataType, typename StorageClass = bool, |
|
2492 + typename ParserClass = parser<DataType> > |
|
2493 class list : public Option, public list_storage<DataType, StorageClass> { |
|
2494 + friend class Option; |
|
2495 std::vector<unsigned> Positions; |
|
2496 ParserClass Parser; |
|
2497 |
|
2498 - enum ValueExpected getValueExpectedFlagDefault() const override { |
|
2499 +protected: |
|
2500 + virtual enum ValueExpected getValueExpectedFlagDefault() const override { |
|
2501 return Parser.getValueExpectedFlagDefault(); |
|
2502 } |
|
2503 - void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { |
|
2504 + |
|
2505 + virtual void |
|
2506 + getExtraOptionNames(std::vector<const char*> &OptionNames) override { |
|
2507 return Parser.getExtraOptionNames(OptionNames); |
|
2508 } |
|
2509 |
|
2510 - bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2511 + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2512 StringRef Arg) override { |
|
2513 typename ParserClass::parser_data_type Val = |
|
2514 typename ParserClass::parser_data_type(); |
|
2515 if (Parser.parse(*this, ArgName, Arg, Val)) |
|
2516 return true; // Parse Error! |
|
2517 - list_storage<DataType, StorageClass>::addValue(Val); |
|
2518 + |
|
2519 + // list_storage<DataType, StorageClass>::addValue(Val); |
|
2520 + this->addValue(Val); |
|
2521 setPosition(pos); |
|
2522 Positions.push_back(pos); |
|
2523 return false; |
|
2524 } |
|
2525 |
|
2526 // Forward printing stuff to the parser... |
|
2527 - size_t getOptionWidth() const override { |
|
2528 + virtual size_t getOptionWidth() const override { |
|
2529 return Parser.getOptionWidth(*this); |
|
2530 } |
|
2531 - void printOptionInfo(size_t GlobalWidth) const override { |
|
2532 + |
|
2533 + virtual void printOptionInfo(size_t GlobalWidth) const override { |
|
2534 Parser.printOptionInfo(*this, GlobalWidth); |
|
2535 } |
|
2536 |
|
2537 // Unimplemented: list options don't currently store their default value. |
|
2538 - void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { |
|
2539 - } |
|
2540 + virtual void |
|
2541 + printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { } |
|
2542 |
|
2543 void done() { |
|
2544 addArgument(); |
|
2545 @@ -1400,22 +2412,46 @@ |
|
2546 } |
|
2547 |
|
2548 // Command line options should not be copyable |
|
2549 - list(const list &) = delete; |
|
2550 - list &operator=(const list &) = delete; |
|
2551 + list<DataType, StorageClass, ParserClass>( |
|
2552 + const list<DataType, StorageClass, ParserClass>&) = delete; |
|
2553 + list<DataType, StorageClass, ParserClass>& |
|
2554 + operator=(const list<DataType, StorageClass, ParserClass>&) = delete; |
|
2555 |
|
2556 public: |
|
2557 + list<DataType, StorageClass, ParserClass>() |
|
2558 + : Option(), list_storage<DataType, StorageClass>(), |
|
2559 + Positions(), Parser(ParserClass()) { } |
|
2560 + |
|
2561 + list<DataType, StorageClass, ParserClass>(const Option &O) |
|
2562 + : Option(O), list_storage<DataType, StorageClass>(), |
|
2563 + Positions(), Parser(ParserClass()) { } |
|
2564 + |
|
2565 + list<DataType, StorageClass, ParserClass>(Option *O) |
|
2566 + : Option(*O), list_storage<DataType, StorageClass>(), |
|
2567 + Positions(), Parser(ParserClass()) { } |
|
2568 + |
|
2569 + ~list<DataType, StorageClass, ParserClass>() { } |
|
2570 + |
|
2571 ParserClass &getParser() { return Parser; } |
|
2572 |
|
2573 + void addArgument() { |
|
2574 + assert(!NextRegistered && "argument multiply registered!"); |
|
2575 + Option::registerOption(this); |
|
2576 + } |
|
2577 + |
|
2578 unsigned getPosition(unsigned optnum) const { |
|
2579 assert(optnum < this->size() && "Invalid option index"); |
|
2580 return Positions[optnum]; |
|
2581 } |
|
2582 |
|
2583 - void setNumAdditionalVals(unsigned n) { Option::setNumAdditionalVals(n); } |
|
2584 + void setNumAdditionalVals(unsigned N) { |
|
2585 + Option::setNumAdditionalVals(N); |
|
2586 + } |
|
2587 |
|
2588 - template <class... Mods> |
|
2589 - explicit list(const Mods &... Ms) |
|
2590 - : Option(ZeroOrMore, NotHidden), Parser(*this) { |
|
2591 + template <typename... Mods> |
|
2592 + explicit list<DataType, StorageClass, ParserClass>(const Mods &... Ms) |
|
2593 + : Option(ZeroOrMore, NotHidden), list_storage<DataType, StorageClass>(), |
|
2594 + Positions(), Parser(*this) { |
|
2595 apply(this, Ms...); |
|
2596 done(); |
|
2597 } |
|
2598 @@ -1424,7 +2460,9 @@ |
|
2599 // multi_val - Modifier to set the number of additional values. |
|
2600 struct multi_val { |
|
2601 unsigned AdditionalVals; |
|
2602 + multi_val() : AdditionalVals(0U) { } |
|
2603 explicit multi_val(unsigned N) : AdditionalVals(N) {} |
|
2604 + ~multi_val() { } |
|
2605 |
|
2606 template <typename D, typename S, typename P> |
|
2607 void apply(list<D, S, P> &L) const { |
|
2608 @@ -1439,10 +2477,11 @@ |
|
2609 // assumes the user will specify a variable to store the data into with the |
|
2610 // cl::location(x) modifier. |
|
2611 // |
|
2612 -template <class DataType, class StorageClass> class bits_storage { |
|
2613 +template<typename DataType, typename StorageClass> |
|
2614 +class bits_storage { |
|
2615 unsigned *Location; // Where to store the bits... |
|
2616 |
|
2617 - template <class T> static unsigned Bit(const T &V) { |
|
2618 + template<typename T> static unsigned Bit(const T &V) { |
|
2619 unsigned BitPos = reinterpret_cast<unsigned>(V); |
|
2620 assert(BitPos < sizeof(unsigned) * CHAR_BIT && |
|
2621 "enum exceeds width of bit vector!"); |
|
2622 @@ -1475,41 +2514,59 @@ |
|
2623 // Define how to hold bits. Since we can inherit from a class, we do so. |
|
2624 // This makes us exactly compatible with the bits in all cases that it is used. |
|
2625 // |
|
2626 -template <class DataType> class bits_storage<DataType, bool> { |
|
2627 +template<typename DataType> |
|
2628 +class bits_storage<DataType, bool> { |
|
2629 unsigned Bits; // Where to store the bits... |
|
2630 |
|
2631 - template <class T> static unsigned Bit(const T &V) { |
|
2632 - unsigned BitPos = (unsigned)V; |
|
2633 + template<typename T> static unsigned Bit(const T &V) { |
|
2634 + unsigned BitPos = static_cast<unsigned>(V); |
|
2635 assert(BitPos < sizeof(unsigned) * CHAR_BIT && |
|
2636 "enum exceeds width of bit vector!"); |
|
2637 return 1 << BitPos; |
|
2638 } |
|
2639 |
|
2640 public: |
|
2641 - template <class T> void addValue(const T &V) { Bits |= Bit(V); } |
|
2642 + void addValue(const DataType &V) { |
|
2643 + Bits |= Bit(V); |
|
2644 + } |
|
2645 + |
|
2646 + template<typename T> |
|
2647 + void addValue(const T &V) { |
|
2648 + Bits |= Bit(V); |
|
2649 + } |
|
2650 |
|
2651 unsigned getBits() { return Bits; } |
|
2652 |
|
2653 - template <class T> bool isSet(const T &V) { return (Bits & Bit(V)) != 0; } |
|
2654 + bool isSet(const DataType &V) { |
|
2655 + return (Bits & Bit(V)) != 0; |
|
2656 + } |
|
2657 + |
|
2658 + template<typename T> |
|
2659 + bool isSet(const T &V) { |
|
2660 + return (Bits & Bit(V)) != 0; |
|
2661 + } |
|
2662 }; |
|
2663 |
|
2664 //===----------------------------------------------------------------------===// |
|
2665 // bits - A bit vector of command options. |
|
2666 // |
|
2667 -template <class DataType, class Storage = bool, |
|
2668 - class ParserClass = parser<DataType>> |
|
2669 +template<typename DataType, typename Storage = bool, |
|
2670 + typename ParserClass = parser<DataType> > |
|
2671 class bits : public Option, public bits_storage<DataType, Storage> { |
|
2672 std::vector<unsigned> Positions; |
|
2673 ParserClass Parser; |
|
2674 |
|
2675 - enum ValueExpected getValueExpectedFlagDefault() const override { |
|
2676 +protected: |
|
2677 + virtual enum ValueExpected getValueExpectedFlagDefault() const override { |
|
2678 return Parser.getValueExpectedFlagDefault(); |
|
2679 } |
|
2680 - void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { |
|
2681 + |
|
2682 + virtual void |
|
2683 + getExtraOptionNames(std::vector<const char*> &OptionNames) override { |
|
2684 return Parser.getExtraOptionNames(OptionNames); |
|
2685 } |
|
2686 |
|
2687 - bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2688 + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2689 StringRef Arg) override { |
|
2690 typename ParserClass::parser_data_type Val = |
|
2691 typename ParserClass::parser_data_type(); |
|
2692 @@ -1525,6 +2582,7 @@ |
|
2693 size_t getOptionWidth() const override { |
|
2694 return Parser.getOptionWidth(*this); |
|
2695 } |
|
2696 + |
|
2697 void printOptionInfo(size_t GlobalWidth) const override { |
|
2698 Parser.printOptionInfo(*this, GlobalWidth); |
|
2699 } |
|
2700 @@ -1538,11 +2596,20 @@ |
|
2701 Parser.initialize(); |
|
2702 } |
|
2703 |
|
2704 +private: |
|
2705 // Command line options should not be copyable |
|
2706 - bits(const bits &) = delete; |
|
2707 - bits &operator=(const bits &) = delete; |
|
2708 + bits<DataType, Storage, ParserClass>( |
|
2709 + const bits<DataType, Storage, ParserClass>&) = delete; |
|
2710 + bits<DataType, Storage, ParserClass> |
|
2711 + &operator=(const bits<DataType, Storage, ParserClass>&) = delete; |
|
2712 |
|
2713 public: |
|
2714 + bits<DataType, Storage, ParserClass>() |
|
2715 + : Option(ZeroOrMore, NotHidden), bits_storage<DataType, Storage>(), |
|
2716 + Positions(), Parser() { } |
|
2717 + |
|
2718 + ~bits() { } |
|
2719 + |
|
2720 ParserClass &getParser() { return Parser; } |
|
2721 |
|
2722 unsigned getPosition(unsigned optnum) const { |
|
2723 @@ -1550,9 +2617,10 @@ |
|
2724 return Positions[optnum]; |
|
2725 } |
|
2726 |
|
2727 - template <class... Mods> |
|
2728 - explicit bits(const Mods &... Ms) |
|
2729 - : Option(ZeroOrMore, NotHidden), Parser(*this) { |
|
2730 + template<typename... Mods> |
|
2731 + explicit bits<DataType, Storage, ParserClass>(const Mods &... Ms) |
|
2732 + : Option(ZeroOrMore, NotHidden), bits_storage<DataType, Storage>(), |
|
2733 + Positions(), Parser(*this) { |
|
2734 apply(this, Ms...); |
|
2735 done(); |
|
2736 } |
|
2737 @@ -1568,19 +2636,21 @@ |
|
2738 StringRef Arg) override { |
|
2739 return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg); |
|
2740 } |
|
2741 - bool addOccurrence(unsigned pos, StringRef /*ArgName*/, StringRef Value, |
|
2742 - bool MultiArg = false) override { |
|
2743 + |
|
2744 + virtual bool addOccurrence(unsigned pos, StringRef /*ArgName*/, |
|
2745 + StringRef Value, bool MultiArg = false) override { |
|
2746 return AliasFor->addOccurrence(pos, AliasFor->ArgStr, Value, MultiArg); |
|
2747 } |
|
2748 + |
|
2749 // Handle printing stuff... |
|
2750 size_t getOptionWidth() const override; |
|
2751 void printOptionInfo(size_t GlobalWidth) const override; |
|
2752 |
|
2753 // Aliases do not need to print their values. |
|
2754 - void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { |
|
2755 - } |
|
2756 + virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) |
|
2757 + const override { } |
|
2758 |
|
2759 - ValueExpected getValueExpectedFlagDefault() const override { |
|
2760 + virtual ValueExpected getValueExpectedFlagDefault() const override { |
|
2761 return AliasFor->getValueExpectedFlag(); |
|
2762 } |
|
2763 |
|
2764 @@ -1597,13 +2667,15 @@ |
|
2765 alias &operator=(const alias &) = delete; |
|
2766 |
|
2767 public: |
|
2768 + alias() : Option(Optional, Hidden), AliasFor(nullptr) { } |
|
2769 + |
|
2770 void setAliasFor(Option &O) { |
|
2771 if (AliasFor) |
|
2772 error("cl::alias must only have one cl::aliasopt(...) specified!"); |
|
2773 AliasFor = &O; |
|
2774 } |
|
2775 |
|
2776 - template <class... Mods> |
|
2777 + template<typename... Mods> |
|
2778 explicit alias(const Mods &... Ms) |
|
2779 : Option(Optional, Hidden), AliasFor(nullptr) { |
|
2780 apply(this, Ms...); |
|
2781 @@ -1615,6 +2687,7 @@ |
|
2782 struct aliasopt { |
|
2783 Option &Opt; |
|
2784 explicit aliasopt(Option &O) : Opt(O) {} |
|
2785 + |
|
2786 void apply(alias &A) const { A.setAliasFor(Opt); } |
|
2787 }; |
|
2788 |
|
2789 @@ -1624,6 +2697,7 @@ |
|
2790 // exit is called. |
|
2791 struct extrahelp { |
|
2792 const char *morehelp; |
|
2793 + |
|
2794 explicit extrahelp(const char *help); |
|
2795 }; |
|
2796 |
|
2797 @@ -1688,7 +2762,7 @@ |
|
2798 /// lines and end of the response file to be marked with a nullptr string. |
|
2799 /// \param [out] NewArgv All parsed strings are appended to NewArgv. |
|
2800 void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, |
|
2801 - SmallVectorImpl<const char *> &NewArgv, |
|
2802 + std::vector<const char*> &NewArgv, |
|
2803 bool MarkEOLs = false); |
|
2804 |
|
2805 /// \brief Tokenizes a Windows command line which may contain quotes and escaped |
|
2806 @@ -1703,13 +2777,13 @@ |
|
2807 /// lines and end of the response file to be marked with a nullptr string. |
|
2808 /// \param [out] NewArgv All parsed strings are appended to NewArgv. |
|
2809 void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, |
|
2810 - SmallVectorImpl<const char *> &NewArgv, |
|
2811 + std::vector<const char*> &NewArgv, |
|
2812 bool MarkEOLs = false); |
|
2813 |
|
2814 /// \brief String tokenization function type. Should be compatible with either |
|
2815 /// Windows or Unix command line tokenizers. |
|
2816 typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver, |
|
2817 - SmallVectorImpl<const char *> &NewArgv, |
|
2818 + std::vector<const char*> &NewArgv, |
|
2819 bool MarkEOLs); |
|
2820 |
|
2821 /// \brief Expand response files on a command line recursively using the given |
|
2822 @@ -1720,16 +2794,6 @@ |
|
2823 /// remaining arguments only until the next end of line, when in a response |
|
2824 /// file. |
|
2825 /// |
|
2826 -/// \param [in] Saver Delegates back to the caller for saving parsed strings. |
|
2827 -/// \param [in] Tokenizer Tokenization strategy. Typically Unix or Windows. |
|
2828 -/// \param [in,out] Argv Command line into which to expand response files. |
|
2829 -/// \param [in] MarkEOLs Mark end of lines and the end of the response file |
|
2830 -/// with nullptrs in the Argv vector. |
|
2831 -/// \return true if all @files were expanded successfully or there were none. |
|
2832 -bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, |
|
2833 - SmallVectorImpl<const char *> &Argv, |
|
2834 - bool MarkEOLs = false); |
|
2835 - |
|
2836 /// \brief Mark all options not part of this category as cl::ReallyHidden. |
|
2837 /// |
|
2838 /// \param Category the category of options to keep displaying |
|
2839 @@ -1748,6 +2812,13 @@ |
|
2840 /// option category to display in the -help output. |
|
2841 void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories); |
|
2842 |
|
2843 +/// \brief Expand response files on a command line recursively using |
|
2844 +/// the given StringSaver and tokenization strategy. |
|
2845 +/// |
|
2846 +bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, |
|
2847 + std::vector<const char *> &Argv, |
|
2848 + bool MarkEOLs = false); |
|
2849 + |
|
2850 } // End namespace cl |
|
2851 |
|
2852 } // End namespace llvm |
|
2853 ### |
|
2854 --- lib/Support/CommandLine.cpp 2015-12-28 06:46:15.000000000 -0900 |
|
2855 +++ lib/Support/CommandLine.cpp 2016-07-06 13:40:52.605682650 -0800 |
|
2856 @@ -34,18 +34,23 @@ |
|
2857 #include "llvm/Support/Path.h" |
|
2858 #include "llvm/Support/StringSaver.h" |
|
2859 #include "llvm/Support/raw_ostream.h" |
|
2860 -#include <cstdlib> |
|
2861 -#include <map> |
|
2862 using namespace llvm; |
|
2863 using namespace cl; |
|
2864 |
|
2865 +#include <cstdlib> |
|
2866 +#include <string> |
|
2867 +#include <map> |
|
2868 + |
|
2869 #define DEBUG_TYPE "commandline" |
|
2870 |
|
2871 +#include <iostream> |
|
2872 + |
|
2873 //===----------------------------------------------------------------------===// |
|
2874 // Template instantiations and anchors. |
|
2875 // |
|
2876 namespace llvm { |
|
2877 namespace cl { |
|
2878 +typedef std::map<std::string, Option*> StdStringMap; |
|
2879 template class basic_parser<bool>; |
|
2880 template class basic_parser<boolOrDefault>; |
|
2881 template class basic_parser<int>; |
|
2882 @@ -82,133 +87,197 @@ |
|
2883 |
|
2884 //===----------------------------------------------------------------------===// |
|
2885 |
|
2886 +namespace llvm { |
|
2887 + namespace cl { |
|
2888 + Option *generic_parser_base::DefaultInvalidOption = |
|
2889 + reinterpret_cast<Option*>(reinterpret_cast<void*>( |
|
2890 + static_cast<uintptr_t>(0xdeadbeef))); |
|
2891 + } // namespace cl |
|
2892 +} // namedspace llvm |
|
2893 + |
|
2894 +//===----------------------------------------------------------------------===// |
|
2895 + |
|
2896 namespace { |
|
2897 |
|
2898 class CommandLineParser { |
|
2899 public: |
|
2900 // Globals for name and overview of program. Program name is not a string to |
|
2901 // avoid static ctor/dtor issues. |
|
2902 - std::string ProgramName; |
|
2903 - const char *ProgramOverview; |
|
2904 + static std::string ProgramName; |
|
2905 + static const char *ProgramOverview; |
|
2906 |
|
2907 // This collects additional help to be printed. |
|
2908 - std::vector<const char *> MoreHelp; |
|
2909 + static std::vector<const char *> MoreHelp; |
|
2910 |
|
2911 - SmallVector<Option *, 4> PositionalOpts; |
|
2912 - SmallVector<Option *, 4> SinkOpts; |
|
2913 - StringMap<Option *> OptionsMap; |
|
2914 + std::vector<Option*> PositionalOpts; |
|
2915 + std::vector<Option*> SinkOpts; |
|
2916 + llvm::cl::StdStringMap OptionsMap; |
|
2917 + StringMap<Option*> ReturnOptionsMap; |
|
2918 |
|
2919 Option *ConsumeAfterOpt; // The ConsumeAfter option if it exists. |
|
2920 |
|
2921 // This collects the different option categories that have been registered. |
|
2922 SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories; |
|
2923 |
|
2924 - CommandLineParser() : ProgramOverview(nullptr), ConsumeAfterOpt(nullptr) {} |
|
2925 + // Check out the positional arguments to collect information about them. |
|
2926 + unsigned NumPositionalRequired; |
|
2927 |
|
2928 - void ParseCommandLineOptions(int argc, const char *const *argv, |
|
2929 - const char *Overview); |
|
2930 + // Determine whether or not there are an unlimited number of positionals |
|
2931 + bool HasUnlimitedPositionals; |
|
2932 |
|
2933 - void addLiteralOption(Option &Opt, const char *Name) { |
|
2934 - if (!Opt.hasArgStr()) { |
|
2935 - if (!OptionsMap.insert(std::make_pair(Name, &Opt)).second) { |
|
2936 - errs() << ProgramName << ": CommandLine Error: Option '" << Name |
|
2937 - << "' registered more than once!\n"; |
|
2938 - report_fatal_error("inconsistency in registered CommandLine options"); |
|
2939 - } |
|
2940 - } |
|
2941 - } |
|
2942 + CommandLineParser() |
|
2943 + : PositionalOpts(), SinkOpts(), OptionsMap(), ReturnOptionsMap(), |
|
2944 + ConsumeAfterOpt(0UL), RegisteredOptionCategories(), |
|
2945 + NumPositionalRequired(0U), HasUnlimitedPositionals(false) { } |
|
2946 |
|
2947 - void addOption(Option *O) { |
|
2948 - bool HadErrors = false; |
|
2949 - if (O->hasArgStr()) { |
|
2950 - // Add argument to the argument map! |
|
2951 - if (!OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) { |
|
2952 - errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr |
|
2953 - << "' registered more than once!\n"; |
|
2954 - HadErrors = true; |
|
2955 - } |
|
2956 - } |
|
2957 + ~CommandLineParser() { } |
|
2958 |
|
2959 - // Remember information about positional options. |
|
2960 - if (O->getFormattingFlag() == cl::Positional) |
|
2961 - PositionalOpts.push_back(O); |
|
2962 - else if (O->getMiscFlags() & cl::Sink) // Remember sink options |
|
2963 - SinkOpts.push_back(O); |
|
2964 - else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) { |
|
2965 - if (ConsumeAfterOpt) { |
|
2966 - O->error("Cannot specify more than one option with cl::ConsumeAfter!"); |
|
2967 - HadErrors = true; |
|
2968 - } |
|
2969 - ConsumeAfterOpt = O; |
|
2970 - } |
|
2971 + static void GetOptionInfo(std::vector<Option *> &PO, |
|
2972 + std::vector<Option *> &SO, |
|
2973 + llvm::cl::StdStringMap &OM); |
|
2974 + |
|
2975 + static bool ExpandResponseFile(const char *FName, |
|
2976 + StringSaver &Saver, |
|
2977 + TokenizerCallback Tokenizer, |
|
2978 + std::vector<const char *> &NewArgv, |
|
2979 + bool MarkEOLs = false); |
|
2980 + |
|
2981 + void __attribute__((noinline)) |
|
2982 + ParseCommandLineOptions(int Argc, const char *const *Argv, |
|
2983 + const char *Overview); |
|
2984 + |
|
2985 + void __attribute__((noinline)) |
|
2986 + addLiteralOption(Option &Opt, const char *Name); |
|
2987 + |
|
2988 + void __attribute__((noinline)) addOption(Option *O); |
|
2989 + |
|
2990 + void __attribute__((noinline)) removeOption(Option *O); |
|
2991 + |
|
2992 + bool __attribute__((noinline)) hasOptions(); |
|
2993 + |
|
2994 + void __attribute__((noinline)) updateArgStr(Option *O, StringRef NewName); |
|
2995 + |
|
2996 + void __attribute__((noinline)) PrintOptionValues(); |
|
2997 |
|
2998 - // Fail hard if there were errors. These are strictly unrecoverable and |
|
2999 - // indicate serious issues such as conflicting option names or an |
|
3000 - // incorrectly |
|
3001 - // linked LLVM distribution. |
|
3002 - if (HadErrors) |
|
3003 + void __attribute__((noinline)) registerCategory(OptionCategory *cat); |
|
3004 + |
|
3005 +private: |
|
3006 + Option *LookupOption(StringRef &Arg, StringRef &Value); |
|
3007 + void HandleSpecialPrefixOptions(StringRef &ArgName, StringRef &Value); |
|
3008 +}; |
|
3009 + |
|
3010 +void __attribute__((noinline)) |
|
3011 +CommandLineParser::addLiteralOption(Option &Opt, const char *Name) { |
|
3012 + if (!Opt.hasArgStr()) { |
|
3013 + if (!OptionsMap.insert(std::make_pair(Name, &Opt)).second) { |
|
3014 + errs() << __PRETTY_FUNCTION__ << ": " << ProgramName |
|
3015 + << ": CommandLine Error: Option '" << Name |
|
3016 + << "' registered more than once!\n"; |
|
3017 report_fatal_error("inconsistency in registered CommandLine options"); |
|
3018 + } |
|
3019 } |
|
3020 +} |
|
3021 |
|
3022 - void removeOption(Option *O) { |
|
3023 - SmallVector<StringRef, 16> OptionNames; |
|
3024 - O->getExtraOptionNames(OptionNames); |
|
3025 - if (O->hasArgStr()) |
|
3026 - OptionNames.push_back(O->ArgStr); |
|
3027 - for (auto Name : OptionNames) |
|
3028 - OptionsMap.erase(Name); |
|
3029 +void __attribute__((noinline)) |
|
3030 +CommandLineParser::addOption(Option *O) { |
|
3031 + bool HadErrors = false; |
|
3032 + if (O->hasArgStr()) { |
|
3033 + // Add argument to the argument map! |
|
3034 + if (!OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) { |
|
3035 + errs() << __PRETTY_FUNCTION__ << ": " << ProgramName |
|
3036 + << ": CommandLine Error: Option '" << O->ArgStr |
|
3037 + << "' registered more than once!\n"; |
|
3038 + HadErrors = true; |
|
3039 + } |
|
3040 + } |
|
3041 |
|
3042 - if (O->getFormattingFlag() == cl::Positional) |
|
3043 - for (auto Opt = PositionalOpts.begin(); Opt != PositionalOpts.end(); |
|
3044 - ++Opt) { |
|
3045 - if (*Opt == O) { |
|
3046 - PositionalOpts.erase(Opt); |
|
3047 - break; |
|
3048 - } |
|
3049 + // Remember information about positional options. |
|
3050 + if (O->getFormattingFlag() == cl::Positional) |
|
3051 + PositionalOpts.push_back(O); |
|
3052 + else if (O->getMiscFlags() & cl::Sink) // Remember sink options |
|
3053 + SinkOpts.push_back(O); |
|
3054 + else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) { |
|
3055 + if (ConsumeAfterOpt) { |
|
3056 + O->error("Cannot specify more than one option with cl::ConsumeAfter!"); |
|
3057 + HadErrors = true; |
|
3058 + } |
|
3059 + |
|
3060 + ConsumeAfterOpt = O; |
|
3061 + } |
|
3062 + |
|
3063 + // Fail hard if there were errors. These are strictly unrecoverable and |
|
3064 + // indicate serious issues such as conflicting option names or an |
|
3065 + //incorrectly linked LLVM distribution. |
|
3066 + if (HadErrors) |
|
3067 + report_fatal_error("inconsistency in registered CommandLine options"); |
|
3068 +} |
|
3069 + |
|
3070 +void __attribute__((noinline)) |
|
3071 +CommandLineParser::removeOption(Option *O) { |
|
3072 + std::vector<const char*> OptionNames; |
|
3073 + O->getExtraOptionNames(OptionNames); |
|
3074 + if (O->hasArgStr()) |
|
3075 + OptionNames.push_back(O->ArgStr); |
|
3076 + for (auto Name : OptionNames) |
|
3077 + OptionsMap.erase(Name); |
|
3078 + |
|
3079 + if (O->getFormattingFlag() == cl::Positional) { |
|
3080 + for (auto Opt = PositionalOpts.begin(); Opt != PositionalOpts.end(); |
|
3081 + ++Opt) { |
|
3082 + if (*Opt == O) { |
|
3083 + PositionalOpts.erase(Opt); |
|
3084 + break; |
|
3085 } |
|
3086 - else if (O->getMiscFlags() & cl::Sink) |
|
3087 - for (auto Opt = SinkOpts.begin(); Opt != SinkOpts.end(); ++Opt) { |
|
3088 - if (*Opt == O) { |
|
3089 - SinkOpts.erase(Opt); |
|
3090 - break; |
|
3091 - } |
|
3092 + } |
|
3093 + } else if (O->getMiscFlags() & cl::Sink) { |
|
3094 + for (auto Opt = SinkOpts.begin(); Opt != SinkOpts.end(); ++Opt) { |
|
3095 + if (*Opt == O) { |
|
3096 + SinkOpts.erase(Opt); |
|
3097 + break; |
|
3098 } |
|
3099 - else if (O == ConsumeAfterOpt) |
|
3100 - ConsumeAfterOpt = nullptr; |
|
3101 + } |
|
3102 + } else if (O == ConsumeAfterOpt) { |
|
3103 + ConsumeAfterOpt = nullptr; |
|
3104 } |
|
3105 +} |
|
3106 |
|
3107 - bool hasOptions() { |
|
3108 - return (!OptionsMap.empty() || !PositionalOpts.empty() || |
|
3109 - nullptr != ConsumeAfterOpt); |
|
3110 - } |
|
3111 +bool __attribute__((noinline)) |
|
3112 +CommandLineParser::hasOptions() { |
|
3113 + return (!OptionsMap.empty() || !PositionalOpts.empty() || |
|
3114 + nullptr != ConsumeAfterOpt); |
|
3115 +} |
|
3116 |
|
3117 - void updateArgStr(Option *O, StringRef NewName) { |
|
3118 - if (!OptionsMap.insert(std::make_pair(NewName, O)).second) { |
|
3119 - errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr |
|
3120 - << "' registered more than once!\n"; |
|
3121 - report_fatal_error("inconsistency in registered CommandLine options"); |
|
3122 - } |
|
3123 - OptionsMap.erase(O->ArgStr); |
|
3124 +void __attribute__((noinline)) |
|
3125 +CommandLineParser::updateArgStr(Option *O, StringRef NewName) { |
|
3126 + if (!OptionsMap.insert(std::make_pair(NewName, O)).second) { |
|
3127 + errs() << __PRETTY_FUNCTION__ << ": " << ProgramName |
|
3128 + << ": CommandLine Error: Option '" << O->ArgStr |
|
3129 + << "' registered more than once!\n"; |
|
3130 + report_fatal_error("inconsistency in registered CommandLine options"); |
|
3131 } |
|
3132 |
|
3133 - void printOptionValues(); |
|
3134 + OptionsMap.erase(O->ArgStr); |
|
3135 +} |
|
3136 |
|
3137 - void registerCategory(OptionCategory *cat) { |
|
3138 - assert(std::count_if(RegisteredOptionCategories.begin(), |
|
3139 - RegisteredOptionCategories.end(), |
|
3140 - [cat](const OptionCategory *Category) { |
|
3141 - return cat->getName() == Category->getName(); |
|
3142 - }) == 0 && |
|
3143 - "Duplicate option categories"); |
|
3144 +void __attribute__((noinline)) |
|
3145 +CommandLineParser::registerCategory(OptionCategory *Cat) { |
|
3146 + assert(std::count_if(RegisteredOptionCategories.begin(), |
|
3147 + RegisteredOptionCategories.end(), |
|
3148 + [Cat](const OptionCategory *Category) { |
|
3149 + return Cat->getName() == Category->getName(); |
|
3150 + }) == 0 && "Duplicate option categories"); |
|
3151 |
|
3152 - RegisteredOptionCategories.insert(cat); |
|
3153 - } |
|
3154 + RegisteredOptionCategories.insert(Cat); |
|
3155 +} |
|
3156 |
|
3157 -private: |
|
3158 - Option *LookupOption(StringRef &Arg, StringRef &Value); |
|
3159 -}; |
|
3160 +std::string CommandLineParser::ProgramName("<premain>"); |
|
3161 +const char* CommandLineParser::ProgramOverview = 0L; |
|
3162 +std::vector<const char *> CommandLineParser::MoreHelp; |
|
3163 + |
|
3164 +} // end anonymous namespace |
|
3165 |
|
3166 -} // namespace |
|
3167 +llvm::cl::Option* llvm::cl::Option::RegisteredOptionList = nullptr; |
|
3168 +unsigned llvm::cl::Option::NumRegisteredOptions = 0U; |
|
3169 |
|
3170 static ManagedStatic<CommandLineParser> GlobalParser; |
|
3171 |
|
3172 @@ -222,14 +291,18 @@ |
|
3173 |
|
3174 void Option::addArgument() { |
|
3175 GlobalParser->addOption(this); |
|
3176 + Option *O = dynamic_cast<Option*>(this); |
|
3177 + assert(O && "Cannot dynamic_cast to correct type!"); |
|
3178 + Option::registerOption(O); |
|
3179 + |
|
3180 FullyInitialized = true; |
|
3181 } |
|
3182 |
|
3183 void Option::removeArgument() { GlobalParser->removeOption(this); } |
|
3184 |
|
3185 -void Option::setArgStr(StringRef S) { |
|
3186 +void Option::setArgStr(const char *S) { |
|
3187 if (FullyInitialized) |
|
3188 - GlobalParser->updateArgStr(this, S); |
|
3189 + GlobalParser->updateArgStr(this, StringRef(S)); |
|
3190 ArgStr = S; |
|
3191 } |
|
3192 |
|
3193 @@ -244,6 +317,107 @@ |
|
3194 // Basic, shared command line option processing machinery. |
|
3195 // |
|
3196 |
|
3197 +/// HandleSpecialPrefixOptions - certain options need special handling |
|
3198 +/// of their Argyment/Value pair, because there will be no space separator |
|
3199 +/// between the two. For example -O<N> (optimization level). |
|
3200 +void CommandLineParser::HandleSpecialPrefixOptions(StringRef &ArgName, |
|
3201 + StringRef &Value) { |
|
3202 + if (ArgName.empty()) |
|
3203 + return; |
|
3204 + |
|
3205 + const char *ArgStr = ArgName.data(); |
|
3206 + bool DoSubstitution; |
|
3207 + |
|
3208 + if (ArgStr[0] == 'O' && ArgStr[1] == '\0') |
|
3209 + DoSubstitution = true; |
|
3210 + else if (ArgStr[0] == 'O' && std::isalpha(ArgStr[1]) && ArgStr[2] == '\0') |
|
3211 + DoSubstitution = true; |
|
3212 + else if (ArgStr[0] == 'O' && std::isdigit(ArgStr[1]) && ArgStr[2] == '\0') |
|
3213 + DoSubstitution = true; |
|
3214 + else if (ArgStr[0] == 'g' && ArgStr[1] == '\0') |
|
3215 + DoSubstitution = true; |
|
3216 + else if (ArgStr[0] == 'g' && std::isdigit(ArgStr[1]) && ArgStr[2] == '\0') |
|
3217 + DoSubstitution = true; |
|
3218 + else |
|
3219 + DoSubstitution = false; |
|
3220 + |
|
3221 + if (DoSubstitution) { |
|
3222 + Value = ArgName.substr(1, 1); |
|
3223 + ArgName = ArgName.substr(0, 1); |
|
3224 + } |
|
3225 +} |
|
3226 + |
|
3227 +/// GetOptionInfo - Scan the list of registered options, turning them into data |
|
3228 +/// structures that are easier to handle. |
|
3229 +void CommandLineParser::GetOptionInfo(std::vector<Option *> &PO, |
|
3230 + std::vector<Option *> &SO, |
|
3231 + llvm::cl::StdStringMap &OM) { |
|
3232 + bool HadErrors = false; |
|
3233 + std::vector<const char *> OptionNames; |
|
3234 + Option *CAOpt = nullptr; // The ConsumeAfter option if it exists. |
|
3235 + |
|
3236 + for (Option *O = Option::getRegisteredOptionList(); O; |
|
3237 + O = O->getNextRegisteredOption()) { |
|
3238 + // If this option wants to handle multiple option names, get the full set. |
|
3239 + // This handles enum options like "-O1 -O2" etc. |
|
3240 + O->getExtraOptionNames(OptionNames); |
|
3241 + |
|
3242 + if (O->ArgStr && *O->ArgStr) |
|
3243 + OptionNames.push_back(O->ArgStr); |
|
3244 + |
|
3245 + llvm::cl::StdStringMap::iterator FI; |
|
3246 + |
|
3247 + // Handle named options. |
|
3248 + for (size_t i = 0, e = OptionNames.size(); i != e; ++i) { |
|
3249 + // Add argument to the argument map! |
|
3250 + FI = OM.find(OptionNames[i]); |
|
3251 + if (FI == OM.end()) { |
|
3252 + if (!OM.insert(std::make_pair(OptionNames[i], O)).second) { |
|
3253 + errs() << __PRETTY_FUNCTION__ << ": " << ProgramName.c_str() |
|
3254 + << ": CommandLine Error: Option '" << OptionNames[i] |
|
3255 + << "' insertion failed!\n"; |
|
3256 + HadErrors = true; |
|
3257 + } |
|
3258 + } else { |
|
3259 + if (FI->second != O) { |
|
3260 + errs() << __PRETTY_FUNCTION__ << ": " << ProgramName.c_str() |
|
3261 + << ": CommandLine Error: Option '" |
|
3262 + << OptionNames[i] << "' registered more than once!\n"; |
|
3263 + HadErrors = true; |
|
3264 + } |
|
3265 + } |
|
3266 + } |
|
3267 + |
|
3268 + OptionNames.clear(); |
|
3269 + |
|
3270 + // Remember information about positional options. |
|
3271 + if (O->getFormattingFlag() == cl::Positional) |
|
3272 + PO.push_back(O); |
|
3273 + else if (O->getMiscFlags() & cl::Sink) // Remember sink options |
|
3274 + SO.push_back(O); |
|
3275 + else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) { |
|
3276 + if (CAOpt) { |
|
3277 + O->error("Cannot specify more than one option with cl::ConsumeAfter!"); |
|
3278 + HadErrors = true; |
|
3279 + } |
|
3280 + |
|
3281 + CAOpt = O; |
|
3282 + } |
|
3283 + } |
|
3284 + |
|
3285 + if (CAOpt) |
|
3286 + PO.push_back(CAOpt); |
|
3287 + |
|
3288 + // Make sure that they are in order of registration not backwards. |
|
3289 + std::reverse(PO.begin(), PO.end()); |
|
3290 + |
|
3291 + // Fail hard if there were errors. These are strictly unrecoverable and |
|
3292 + // indicate serious issues such as conflicting option names or an incorrectly |
|
3293 + // linked LLVM distribution. |
|
3294 + if (HadErrors) |
|
3295 + report_fatal_error("inconsistency in registered CommandLine options"); |
|
3296 +} |
|
3297 + |
|
3298 /// LookupOption - Lookup the option specified by the specified option on the |
|
3299 /// command line. If there is a value specified (after an equal sign) return |
|
3300 /// that as well. This assumes that leading dashes have already been stripped. |
|
3301 @@ -252,18 +426,89 @@ |
|
3302 if (Arg.empty()) |
|
3303 return nullptr; |
|
3304 |
|
3305 + HandleSpecialPrefixOptions(Arg, Value); |
|
3306 + |
|
3307 size_t EqualPos = Arg.find('='); |
|
3308 |
|
3309 // If we have an equals sign, remember the value. |
|
3310 if (EqualPos == StringRef::npos) { |
|
3311 + StringRef LookupString; |
|
3312 + |
|
3313 // Look up the option. |
|
3314 - StringMap<Option *>::const_iterator I = OptionsMap.find(Arg); |
|
3315 + llvm::cl::StdStringMap::const_iterator I = OptionsMap.find(Arg); |
|
3316 + |
|
3317 + // TableGen |
|
3318 + if (I == OptionsMap.end()) { |
|
3319 + LookupString = "<input file>"; |
|
3320 + I = OptionsMap.find(LookupString); |
|
3321 + if (I != OptionsMap.end()) |
|
3322 + return I->second; |
|
3323 + } |
|
3324 + |
|
3325 + // lli && llc |
|
3326 + if (I == OptionsMap.end()) { |
|
3327 + LookupString = "<input bitcode>"; |
|
3328 + I = OptionsMap.find(LookupString); |
|
3329 + if (I != OptionsMap.end()) |
|
3330 + return I->second; |
|
3331 + } |
|
3332 + |
|
3333 + // opt |
|
3334 + if (I == OptionsMap.end()) { |
|
3335 + LookupString = "<input bitcode file>"; |
|
3336 + I = OptionsMap.find(LookupString); |
|
3337 + if (I != OptionsMap.end()) |
|
3338 + return I->second; |
|
3339 + } |
|
3340 + |
|
3341 + if (I == OptionsMap.end()) { |
|
3342 + LookupString = "Output filename"; |
|
3343 + I = OptionsMap.find(LookupString); |
|
3344 + if (I != OptionsMap.end()) |
|
3345 + return I->second; |
|
3346 + } |
|
3347 + |
|
3348 + if (I == OptionsMap.end()) { |
|
3349 + LookupString = "Output Filename"; |
|
3350 + I = OptionsMap.find(LookupString); |
|
3351 + if (I != OptionsMap.end()) |
|
3352 + return I->second; |
|
3353 + } |
|
3354 + |
|
3355 + if (I == OptionsMap.end()) { |
|
3356 + LookupString = "<Output filename>"; |
|
3357 + I = OptionsMap.find(LookupString); |
|
3358 + if (I != OptionsMap.end()) |
|
3359 + return I->second; |
|
3360 + } |
|
3361 + |
|
3362 + if (I == OptionsMap.end()) { |
|
3363 + LookupString = "<Output Filename>"; |
|
3364 + I = OptionsMap.find(LookupString); |
|
3365 + if (I != OptionsMap.end()) |
|
3366 + return I->second; |
|
3367 + } |
|
3368 + |
|
3369 + if (I == OptionsMap.end()) { |
|
3370 + LookupString = "output filename"; |
|
3371 + I = OptionsMap.find(LookupString); |
|
3372 + if (I != OptionsMap.end()) |
|
3373 + return I->second; |
|
3374 + } |
|
3375 + |
|
3376 + if (I == OptionsMap.end()) { |
|
3377 + LookupString = "<output filename>"; |
|
3378 + I = OptionsMap.find(LookupString); |
|
3379 + if (I != OptionsMap.end()) |
|
3380 + return I->second; |
|
3381 + } |
|
3382 + |
|
3383 return I != OptionsMap.end() ? I->second : nullptr; |
|
3384 } |
|
3385 |
|
3386 // If the argument before the = is a valid option name, we match. If not, |
|
3387 // return Arg unmolested. |
|
3388 - StringMap<Option *>::const_iterator I = |
|
3389 + llvm::cl::StdStringMap::const_iterator I = |
|
3390 OptionsMap.find(Arg.substr(0, EqualPos)); |
|
3391 if (I == OptionsMap.end()) |
|
3392 return nullptr; |
|
3393 @@ -278,7 +523,7 @@ |
|
3394 /// (after an equal sign) return that as well. This assumes that leading dashes |
|
3395 /// have already been stripped. |
|
3396 static Option *LookupNearestOption(StringRef Arg, |
|
3397 - const StringMap<Option *> &OptionsMap, |
|
3398 + const llvm::cl::StdStringMap &OptionsMap, |
|
3399 std::string &NearestString) { |
|
3400 // Reject all dashes. |
|
3401 if (Arg.empty()) |
|
3402 @@ -292,11 +537,10 @@ |
|
3403 // Find the closest match. |
|
3404 Option *Best = nullptr; |
|
3405 unsigned BestDistance = 0; |
|
3406 - for (StringMap<Option *>::const_iterator it = OptionsMap.begin(), |
|
3407 - ie = OptionsMap.end(); |
|
3408 - it != ie; ++it) { |
|
3409 + for (llvm::cl::StdStringMap::const_iterator it = OptionsMap.begin(), |
|
3410 + ie = OptionsMap.end(); it != ie; ++it) { |
|
3411 Option *O = it->second; |
|
3412 - SmallVector<StringRef, 16> OptionNames; |
|
3413 + std::vector<const char*> OptionNames; |
|
3414 O->getExtraOptionNames(OptionNames); |
|
3415 if (O->hasArgStr()) |
|
3416 OptionNames.push_back(O->ArgStr); |
|
3417 @@ -351,21 +595,33 @@ |
|
3418 /// ProvideOption - For Value, this differentiates between an empty value ("") |
|
3419 /// and a null value (StringRef()). The later is accepted for arguments that |
|
3420 /// don't allow a value (-foo) the former is rejected (-foo=). |
|
3421 -static inline bool ProvideOption(Option *Handler, StringRef ArgName, |
|
3422 - StringRef Value, int argc, |
|
3423 - const char *const *argv, int &i) { |
|
3424 +static bool ProvideOption(Option *Handler, StringRef &ArgName, |
|
3425 + StringRef &Value, int Argc, |
|
3426 + const char *const *Argv, int &i) { |
|
3427 // Is this a multi-argument option? |
|
3428 unsigned NumAdditionalVals = Handler->getNumAdditionalVals(); |
|
3429 |
|
3430 + std::string AS = ArgName.str(); |
|
3431 + std::string VS = Value.str(); |
|
3432 + |
|
3433 + if (AS.find("version") != std::string::npos) |
|
3434 + Value = "true"; |
|
3435 + else if (VS.find("help") != std::string::npos) |
|
3436 + Value = "true"; |
|
3437 + |
|
3438 + VS = Value.str(); |
|
3439 + |
|
3440 // Enforce value requirements |
|
3441 switch (Handler->getValueExpectedFlag()) { |
|
3442 case ValueRequired: |
|
3443 - if (!Value.data()) { // No value specified? |
|
3444 - if (i + 1 >= argc) |
|
3445 - return Handler->error("requires a value!"); |
|
3446 + if (Value.empty()) { // No value specified? |
|
3447 + if ((i + 1) >= Argc) |
|
3448 + return Handler->error("argument requires a value!"); |
|
3449 + |
|
3450 // Steal the next argument, like for '-o filename' |
|
3451 - assert(argv && "null check"); |
|
3452 - Value = argv[++i]; |
|
3453 + assert(Argv && "null check"); |
|
3454 + |
|
3455 + Value = Argv[++i]; |
|
3456 } |
|
3457 break; |
|
3458 case ValueDisallowed: |
|
3459 @@ -373,12 +629,18 @@ |
|
3460 return Handler->error("multi-valued option specified" |
|
3461 " with ValueDisallowed modifier!"); |
|
3462 |
|
3463 - if (Value.data()) |
|
3464 + if (!Value.empty()) |
|
3465 return Handler->error("does not allow a value! '" + Twine(Value) + |
|
3466 "' specified."); |
|
3467 break; |
|
3468 case ValueOptional: |
|
3469 break; |
|
3470 + case ValuePositionalNoArgs: |
|
3471 + case ValuePositionalWithArgs: |
|
3472 + break; |
|
3473 + default: |
|
3474 + return Handler->error("Unknown/invalid Option type!"); |
|
3475 + break; |
|
3476 } |
|
3477 |
|
3478 // If this isn't a multi-arg option, just run the handler. |
|
3479 @@ -388,30 +650,43 @@ |
|
3480 // If it is, run the handle several times. |
|
3481 bool MultiArg = false; |
|
3482 |
|
3483 - if (Value.data()) { |
|
3484 + if (!Value.empty()) { |
|
3485 if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg)) |
|
3486 return true; |
|
3487 + |
|
3488 --NumAdditionalVals; |
|
3489 MultiArg = true; |
|
3490 } |
|
3491 |
|
3492 while (NumAdditionalVals > 0) { |
|
3493 - if (i + 1 >= argc) |
|
3494 + if ((i + 1) >= Argc) |
|
3495 return Handler->error("not enough values!"); |
|
3496 - assert(argv && "null check"); |
|
3497 - Value = argv[++i]; |
|
3498 + |
|
3499 + assert(Argv && "null check"); |
|
3500 + Value = Argv[++i]; |
|
3501 |
|
3502 if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg)) |
|
3503 return true; |
|
3504 + |
|
3505 MultiArg = true; |
|
3506 --NumAdditionalVals; |
|
3507 } |
|
3508 + |
|
3509 return false; |
|
3510 } |
|
3511 |
|
3512 static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) { |
|
3513 int Dummy = i; |
|
3514 - return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy); |
|
3515 + StringRef ArgStr = Handler->ArgStr; |
|
3516 + bool R = ProvideOption(Handler, ArgStr, Arg, 0, nullptr, Dummy); |
|
3517 + return R; |
|
3518 +} |
|
3519 + |
|
3520 +static bool ProvidePositionalOptionWithArgs(Option *Handler, StringRef Arg, |
|
3521 + int i, unsigned &ValNo, |
|
3522 + unsigned &NumPositionsRequired) { |
|
3523 + // FIXME: IMPLEMENT |
|
3524 + return false; |
|
3525 } |
|
3526 |
|
3527 // Option predicates... |
|
3528 @@ -430,9 +705,9 @@ |
|
3529 // |
|
3530 static Option *getOptionPred(StringRef Name, size_t &Length, |
|
3531 bool (*Pred)(const Option *), |
|
3532 - const StringMap<Option *> &OptionsMap) { |
|
3533 + const llvm::cl::StdStringMap &OptionsMap) { |
|
3534 |
|
3535 - StringMap<Option *>::const_iterator OMI = OptionsMap.find(Name); |
|
3536 + llvm::cl::StdStringMap::const_iterator OMI = OptionsMap.find(Name); |
|
3537 |
|
3538 // Loop while we haven't found an option and Name still has at least two |
|
3539 // characters in it (so that the next iteration will not be the empty |
|
3540 @@ -454,9 +729,9 @@ |
|
3541 /// see if this is a prefix or grouped option. If so, split arg into output an |
|
3542 /// Arg/Value pair and return the Option to parse it with. |
|
3543 static Option * |
|
3544 -HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value, |
|
3545 +HandlePrefixedOrGroupedOption(std::string &Arg, std::string &Value, |
|
3546 bool &ErrorParsing, |
|
3547 - const StringMap<Option *> &OptionsMap) { |
|
3548 + const llvm::cl::StdStringMap &OptionsMap) { |
|
3549 if (Arg.size() == 1) |
|
3550 return nullptr; |
|
3551 |
|
3552 @@ -489,9 +764,10 @@ |
|
3553 // we don't need to pass argc/argv in. |
|
3554 assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired && |
|
3555 "Option can not be cl::Grouping AND cl::ValueRequired!"); |
|
3556 + |
|
3557 int Dummy = 0; |
|
3558 - ErrorParsing |= |
|
3559 - ProvideOption(PGOpt, OneArgName, StringRef(), 0, nullptr, Dummy); |
|
3560 + StringRef ES = ""; |
|
3561 + ErrorParsing |= ProvideOption(PGOpt, OneArgName, ES, 0, nullptr, Dummy); |
|
3562 |
|
3563 // Get the next grouping option. |
|
3564 PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap); |
|
3565 @@ -507,8 +783,12 @@ |
|
3566 } |
|
3567 |
|
3568 static bool EatsUnboundedNumberOfValues(const Option *O) { |
|
3569 - return O->getNumOccurrencesFlag() == cl::ZeroOrMore || |
|
3570 - O->getNumOccurrencesFlag() == cl::OneOrMore; |
|
3571 + return O->getNumOccurrencesFlag() == cl::Required || |
|
3572 + O->getNumOccurrencesFlag() == cl::ZeroOrMore || |
|
3573 + O->getNumOccurrencesFlag() == cl::OneOrMore || |
|
3574 + O->getValueExpectedFlag() == cl::ValueRequired || |
|
3575 + O->getValueExpectedFlag() == cl::ValuePositionalNoArgs || |
|
3576 + O->getValueExpectedFlag() == cl::ValuePositionalWithArgs; |
|
3577 } |
|
3578 |
|
3579 static bool isWhitespace(char C) { return strchr(" \t\n\r\f\v", C); } |
|
3580 @@ -518,7 +798,7 @@ |
|
3581 static bool isGNUSpecial(char C) { return strchr("\\\"\' ", C); } |
|
3582 |
|
3583 void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver, |
|
3584 - SmallVectorImpl<const char *> &NewArgv, |
|
3585 + std::vector<const char*> &NewArgv, |
|
3586 bool MarkEOLs) { |
|
3587 SmallString<128> Token; |
|
3588 for (size_t I = 0, E = Src.size(); I != E; ++I) { |
|
3589 @@ -594,7 +874,8 @@ |
|
3590 /// consumed in this case. |
|
3591 /// |
|
3592 /// * Otherwise, backslashes are interpreted literally. |
|
3593 -static size_t parseBackslash(StringRef Src, size_t I, SmallString<128> &Token) { |
|
3594 +static size_t parseBackslash(StringRef Src, size_t I, |
|
3595 + SmallString<512> &Token) { |
|
3596 size_t E = Src.size(); |
|
3597 int BackslashCount = 0; |
|
3598 // Skip the backslashes. |
|
3599 @@ -616,9 +897,9 @@ |
|
3600 } |
|
3601 |
|
3602 void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver, |
|
3603 - SmallVectorImpl<const char *> &NewArgv, |
|
3604 + std::vector<const char*> &NewArgv, |
|
3605 bool MarkEOLs) { |
|
3606 - SmallString<128> Token; |
|
3607 + SmallString<512> Token; |
|
3608 |
|
3609 // This is a small state machine to consume characters until it reaches the |
|
3610 // end of the source string. |
|
3611 @@ -699,14 +980,16 @@ |
|
3612 return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf'); |
|
3613 } |
|
3614 |
|
3615 -static bool ExpandResponseFile(const char *FName, StringSaver &Saver, |
|
3616 +bool CommandLineParser::ExpandResponseFile(const char *FName, |
|
3617 + StringSaver &Saver, |
|
3618 TokenizerCallback Tokenizer, |
|
3619 - SmallVectorImpl<const char *> &NewArgv, |
|
3620 - bool MarkEOLs = false) { |
|
3621 + std::vector<const char *> &NewArgv, |
|
3622 + bool MarkEOLs) { |
|
3623 ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = |
|
3624 MemoryBuffer::getFile(FName); |
|
3625 if (!MemBufOrErr) |
|
3626 return false; |
|
3627 + |
|
3628 MemoryBuffer &MemBuf = *MemBufOrErr.get(); |
|
3629 StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize()); |
|
3630 |
|
3631 @@ -730,10 +1013,13 @@ |
|
3632 return true; |
|
3633 } |
|
3634 |
|
3635 -/// \brief Expand response files on a command line recursively using the given |
|
3636 -/// StringSaver and tokenization strategy. |
|
3637 -bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, |
|
3638 - SmallVectorImpl<const char *> &Argv, |
|
3639 +namespace llvm { |
|
3640 + namespace cl { |
|
3641 + /// \brief Expand response files on a command line recursively using |
|
3642 + /// the given StringSaver and tokenization strategy. |
|
3643 + bool ExpandResponseFiles(StringSaver &Saver, |
|
3644 + TokenizerCallback Tokenizer, |
|
3645 + std::vector<const char *> &Argv, |
|
3646 bool MarkEOLs) { |
|
3647 unsigned RspFiles = 0; |
|
3648 bool AllExpanded = true; |
|
3649 @@ -741,37 +1027,43 @@ |
|
3650 // Don't cache Argv.size() because it can change. |
|
3651 for (unsigned I = 0; I != Argv.size();) { |
|
3652 const char *Arg = Argv[I]; |
|
3653 + |
|
3654 // Check if it is an EOL marker |
|
3655 if (Arg == nullptr) { |
|
3656 ++I; |
|
3657 continue; |
|
3658 } |
|
3659 + |
|
3660 if (Arg[0] != '@') { |
|
3661 ++I; |
|
3662 continue; |
|
3663 } |
|
3664 |
|
3665 - // If we have too many response files, leave some unexpanded. This avoids |
|
3666 - // crashing on self-referential response files. |
|
3667 + // If we have too many response files, leave some unexpanded. |
|
3668 + // This avoids crashing on self-referential response files. |
|
3669 if (RspFiles++ > 20) |
|
3670 return false; |
|
3671 |
|
3672 // Replace this response file argument with the tokenization of its |
|
3673 - // contents. Nested response files are expanded in subsequent iterations. |
|
3674 - // FIXME: If a nested response file uses a relative path, is it relative to |
|
3675 - // the cwd of the process or the response file? |
|
3676 - SmallVector<const char *, 0> ExpandedArgv; |
|
3677 - if (!ExpandResponseFile(Arg + 1, Saver, Tokenizer, ExpandedArgv, |
|
3678 - MarkEOLs)) { |
|
3679 - // We couldn't read this file, so we leave it in the argument stream and |
|
3680 - // move on. |
|
3681 + // contents. Nested response files are expanded in subsequent |
|
3682 + // iterations. |
|
3683 + // FIXME: If a nested response file uses a relative path, is it |
|
3684 + // relative to the cwd of the process or the response file? |
|
3685 + std::vector<const char*> ExpandedArgv; |
|
3686 + if (!CommandLineParser::ExpandResponseFile(Arg + 1, Saver, Tokenizer, |
|
3687 + ExpandedArgv, MarkEOLs)) { |
|
3688 + // We couldn't read this file, so we leave it in the argument stream |
|
3689 + // and move on. |
|
3690 AllExpanded = false; |
|
3691 ++I; |
|
3692 continue; |
|
3693 } |
|
3694 + |
|
3695 Argv.erase(Argv.begin() + I); |
|
3696 - Argv.insert(Argv.begin() + I, ExpandedArgv.begin(), ExpandedArgv.end()); |
|
3697 + Argv.insert(Argv.begin() + I, ExpandedArgv.begin(), |
|
3698 + ExpandedArgv.end()); |
|
3699 } |
|
3700 + |
|
3701 return AllExpanded; |
|
3702 } |
|
3703 |
|
3704 @@ -780,7 +1072,7 @@ |
|
3705 /// from the caller (as PROGNAME) and its command-line arguments from |
|
3706 /// an environment variable (whose name is given in ENVVAR). |
|
3707 /// |
|
3708 -void cl::ParseEnvironmentOptions(const char *progName, const char *envVar, |
|
3709 + void ParseEnvironmentOptions(const char *progName, const char *envVar, |
|
3710 const char *Overview) { |
|
3711 // Check args. |
|
3712 assert(progName && "Program name not specified"); |
|
3713 @@ -793,53 +1085,65 @@ |
|
3714 |
|
3715 // Get program's "name", which we wouldn't know without the caller |
|
3716 // telling us. |
|
3717 - SmallVector<const char *, 20> newArgv; |
|
3718 + std::vector<const char*> NewArgv; |
|
3719 BumpPtrAllocator A; |
|
3720 StringSaver Saver(A); |
|
3721 - newArgv.push_back(Saver.save(progName)); |
|
3722 + NewArgv.push_back(Saver.save(progName)); |
|
3723 |
|
3724 // Parse the value of the environment variable into a "command line" |
|
3725 // and hand it off to ParseCommandLineOptions(). |
|
3726 - TokenizeGNUCommandLine(envValue, Saver, newArgv); |
|
3727 - int newArgc = static_cast<int>(newArgv.size()); |
|
3728 - ParseCommandLineOptions(newArgc, &newArgv[0], Overview); |
|
3729 + TokenizeGNUCommandLine(envValue, Saver, NewArgv); |
|
3730 + int NewArgc = static_cast<int>(NewArgv.size()); |
|
3731 + ParseCommandLineOptions(NewArgc, &NewArgv[0], Overview); |
|
3732 } |
|
3733 |
|
3734 -void cl::ParseCommandLineOptions(int argc, const char *const *argv, |
|
3735 + void ParseCommandLineOptions(int Argc, const char *const *Argv, |
|
3736 const char *Overview) { |
|
3737 - GlobalParser->ParseCommandLineOptions(argc, argv, Overview); |
|
3738 + GlobalParser->ParseCommandLineOptions(Argc, Argv, Overview); |
|
3739 } |
|
3740 + } // end namespace cl |
|
3741 +} // end namespace llvm |
|
3742 |
|
3743 -void CommandLineParser::ParseCommandLineOptions(int argc, |
|
3744 - const char *const *argv, |
|
3745 - const char *Overview) { |
|
3746 - assert(hasOptions() && "No options specified!"); |
|
3747 - |
|
3748 +void __attribute__((noinline)) |
|
3749 +CommandLineParser::ParseCommandLineOptions(int Argc, |
|
3750 + const char *const *Argv, |
|
3751 + const char *Overview) { |
|
3752 // Expand response files. |
|
3753 - SmallVector<const char *, 20> newArgv(argv, argv + argc); |
|
3754 + std::vector<const char*> NewArgv; |
|
3755 + for (int i = 0; i != Argc; ++i) |
|
3756 + NewArgv.push_back(Argv[i]); |
|
3757 + |
|
3758 + // You have no clue what's wrong with this, do you. Time for some |
|
3759 + // cargo-cult programming. Make up a new and useless class, throw |
|
3760 + // in a new allocator for no valid reason and hope for the best, |
|
3761 + // without inasmuch as an inkling as to what is wrong with all of |
|
3762 + // this code to begin with. |
|
3763 BumpPtrAllocator A; |
|
3764 StringSaver Saver(A); |
|
3765 - ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv); |
|
3766 - argv = &newArgv[0]; |
|
3767 - argc = static_cast<int>(newArgv.size()); |
|
3768 + llvm::cl::ExpandResponseFiles(Saver, TokenizeGNUCommandLine, NewArgv); |
|
3769 + Argv = &NewArgv[0]; |
|
3770 + Argc = static_cast<int>(NewArgv.size()); |
|
3771 |
|
3772 // Copy the program name into ProgName, making sure not to overflow it. |
|
3773 - ProgramName = sys::path::filename(argv[0]); |
|
3774 + CommandLineParser::ProgramName = sys::path::filename(Argv[0]); |
|
3775 |
|
3776 ProgramOverview = Overview; |
|
3777 bool ErrorParsing = false; |
|
3778 |
|
3779 - // Check out the positional arguments to collect information about them. |
|
3780 - unsigned NumPositionalRequired = 0; |
|
3781 - |
|
3782 - // Determine whether or not there are an unlimited number of positionals |
|
3783 - bool HasUnlimitedPositionals = false; |
|
3784 + CommandLineParser::GetOptionInfo(PositionalOpts, SinkOpts, OptionsMap); |
|
3785 + assert(hasOptions() && "No options specified!"); |
|
3786 |
|
3787 if (ConsumeAfterOpt) { |
|
3788 assert(PositionalOpts.size() > 0 && |
|
3789 "Cannot specify cl::ConsumeAfter without a positional argument!"); |
|
3790 } |
|
3791 + |
|
3792 if (!PositionalOpts.empty()) { |
|
3793 + if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) { |
|
3794 + assert(PositionalOpts.size() > 1 && |
|
3795 + "Cannot specify cl::ConsumeAfter without a positional argument!"); |
|
3796 + ConsumeAfterOpt = PositionalOpts[0]; |
|
3797 + } |
|
3798 |
|
3799 // Calculate how many positional values are _required_. |
|
3800 bool UnboundedFound = false; |
|
3801 @@ -850,12 +1154,12 @@ |
|
3802 else if (ConsumeAfterOpt) { |
|
3803 // ConsumeAfter cannot be combined with "optional" positional options |
|
3804 // unless there is only one positional argument... |
|
3805 - if (PositionalOpts.size() > 1) |
|
3806 + if (PositionalOpts.size() > 2) |
|
3807 ErrorParsing |= Opt->error( |
|
3808 "error - this positional option will never be matched, " |
|
3809 "because it does not Require a value, and a " |
|
3810 "cl::ConsumeAfter option is active!"); |
|
3811 - } else if (UnboundedFound && !Opt->hasArgStr()) { |
|
3812 + } else if (UnboundedFound && !Opt->ArgStr[0]) { |
|
3813 // This option does not "require" a value... Make sure this option is |
|
3814 // not specified after an option that eats all extra arguments, or this |
|
3815 // one will never get any! |
|
3816 @@ -864,19 +1168,21 @@ |
|
3817 "another positional argument will match an " |
|
3818 "unbounded number of values, and this option" |
|
3819 " does not require a value!"); |
|
3820 - errs() << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr |
|
3821 - << "' is all messed up!\n"; |
|
3822 + errs() << ProgramName << ": CommandLine Error: Option '" |
|
3823 + << Opt->ArgStr << "' is all messed up!\n"; |
|
3824 errs() << PositionalOpts.size(); |
|
3825 } |
|
3826 + |
|
3827 UnboundedFound |= EatsUnboundedNumberOfValues(Opt); |
|
3828 } |
|
3829 + |
|
3830 HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt; |
|
3831 } |
|
3832 |
|
3833 // PositionalVals - A vector of "positional" arguments we accumulate into |
|
3834 // the process at the end. |
|
3835 // |
|
3836 - SmallVector<std::pair<StringRef, unsigned>, 4> PositionalVals; |
|
3837 + std::vector<std::pair<StringRef, unsigned> > PositionalVals; |
|
3838 |
|
3839 // If the program has named positional arguments, and the name has been run |
|
3840 // across, keep track of which positional argument was named. Otherwise put |
|
3841 @@ -885,40 +1191,51 @@ |
|
3842 |
|
3843 // Loop over all of the arguments... processing them. |
|
3844 bool DashDashFound = false; // Have we read '--'? |
|
3845 - for (int i = 1; i < argc; ++i) { |
|
3846 + for (int i = 1; i < Argc; ++i) { |
|
3847 Option *Handler = nullptr; |
|
3848 Option *NearestHandler = nullptr; |
|
3849 std::string NearestHandlerString; |
|
3850 - StringRef Value; |
|
3851 + StringRef Value = ""; |
|
3852 StringRef ArgName = ""; |
|
3853 |
|
3854 // Check to see if this is a positional argument. This argument is |
|
3855 // considered to be positional if it doesn't start with '-', if it is "-" |
|
3856 // itself, or if we have seen "--" already. |
|
3857 // |
|
3858 - if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) { |
|
3859 + if (((Argv[i][0] != '-') && (Argv[i][1] != '\0')) || |
|
3860 + ((Argv[i][0] == '-') && (Argv[i][1] == '\0')) || DashDashFound) { |
|
3861 // Positional argument! |
|
3862 if (ActivePositionalArg) { |
|
3863 - ProvidePositionalOption(ActivePositionalArg, argv[i], i); |
|
3864 + ProvidePositionalOption(ActivePositionalArg, Argv[i], i); |
|
3865 + continue; // We are done! |
|
3866 + } |
|
3867 + |
|
3868 + ArgName = Argv[i - 1]; |
|
3869 + Value = Argv[i]; |
|
3870 + Handler = LookupOption(ArgName, Value); |
|
3871 + if (Handler && (Handler->getValueExpectedFlag() == cl::ValueRequired || |
|
3872 + Handler->getValueExpectedFlag() == cl::ValueOptional)) { |
|
3873 + ErrorParsing |= ProvideOption(Handler, ArgName, Value, |
|
3874 + Argc, Argv, i); |
|
3875 continue; // We are done! |
|
3876 } |
|
3877 |
|
3878 if (!PositionalOpts.empty()) { |
|
3879 - PositionalVals.push_back(std::make_pair(argv[i], i)); |
|
3880 + PositionalVals.push_back(std::make_pair(Argv[i], i)); |
|
3881 |
|
3882 // All of the positional arguments have been fulfulled, give the rest to |
|
3883 // the consume after option... if it's specified... |
|
3884 // |
|
3885 if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) { |
|
3886 - for (++i; i < argc; ++i) |
|
3887 - PositionalVals.push_back(std::make_pair(argv[i], i)); |
|
3888 + for (++i; i < Argc; ++i) |
|
3889 + PositionalVals.push_back(std::make_pair(Argv[i], i)); |
|
3890 break; // Handle outside of the argument processing loop... |
|
3891 } |
|
3892 |
|
3893 // Delay processing positional arguments until the end... |
|
3894 continue; |
|
3895 } |
|
3896 - } else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 && |
|
3897 + } else if (Argv[i][0] == '-' && Argv[i][1] == '-' && Argv[i][2] == 0 && |
|
3898 !DashDashFound) { |
|
3899 DashDashFound = true; // This is the mythical "--"? |
|
3900 continue; // Don't try to process it as an argument itself. |
|
3901 @@ -927,29 +1244,65 @@ |
|
3902 // If there is a positional argument eating options, check to see if this |
|
3903 // option is another positional argument. If so, treat it as an argument, |
|
3904 // otherwise feed it to the eating positional. |
|
3905 - ArgName = argv[i] + 1; |
|
3906 + ArgName = Argv[i] + 1; |
|
3907 + |
|
3908 // Eat leading dashes. |
|
3909 while (!ArgName.empty() && ArgName[0] == '-') |
|
3910 ArgName = ArgName.substr(1); |
|
3911 |
|
3912 Handler = LookupOption(ArgName, Value); |
|
3913 + if (Handler && (Handler->getValueExpectedFlag() == cl::ValueRequired || |
|
3914 + Handler->getValueExpectedFlag() == cl::ValueOptional)) { |
|
3915 + ErrorParsing |= ProvideOption(Handler, ArgName, Value, |
|
3916 + Argc, Argv, i); |
|
3917 + continue; // We are done! |
|
3918 + } |
|
3919 + |
|
3920 if (!Handler || Handler->getFormattingFlag() != cl::Positional) { |
|
3921 - ProvidePositionalOption(ActivePositionalArg, argv[i], i); |
|
3922 + ProvidePositionalOption(ActivePositionalArg, Argv[i], i); |
|
3923 continue; // We are done! |
|
3924 } |
|
3925 |
|
3926 } else { // We start with a '-', must be an argument. |
|
3927 - ArgName = argv[i] + 1; |
|
3928 + ArgName = Argv[i]; |
|
3929 + |
|
3930 // Eat leading dashes. |
|
3931 while (!ArgName.empty() && ArgName[0] == '-') |
|
3932 ArgName = ArgName.substr(1); |
|
3933 |
|
3934 Handler = LookupOption(ArgName, Value); |
|
3935 + if (Handler) { |
|
3936 + enum FormattingFlags FF = Handler->getFormattingFlag(); |
|
3937 + enum ValueExpected VEF = Handler->getValueExpectedFlag(); |
|
3938 + |
|
3939 + if ((FF == llvm::cl::Prefix) || (FF == llvm::cl::Grouping)) { |
|
3940 + if (Value.empty()) |
|
3941 + Value = Argv[++i]; |
|
3942 + |
|
3943 + std::string SA = ArgName.str(); |
|
3944 + std::string SV = Value.str(); |
|
3945 + SA.append(SV); |
|
3946 + |
|
3947 + // Check to see if this "option" is really a prefixed or |
|
3948 + // grouped argument. |
|
3949 + Option *PrefixOrGroupHandler = |
|
3950 + HandlePrefixedOrGroupedOption(SA, SV, ErrorParsing, OptionsMap); |
|
3951 + if (PrefixOrGroupHandler) |
|
3952 + Handler = PrefixOrGroupHandler; |
|
3953 + } else if (VEF == llvm::cl::ValueRequired) { |
|
3954 + ErrorParsing |= ProvideOption(Handler, ArgName, Value, Argc, |
|
3955 + Argv, i); |
|
3956 + continue; // We are done! |
|
3957 + } |
|
3958 + } |
|
3959 |
|
3960 // Check to see if this "option" is really a prefixed or grouped argument. |
|
3961 - if (!Handler) |
|
3962 - Handler = HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing, |
|
3963 + if (!Handler) { |
|
3964 + std::string SA = ArgName.str(); |
|
3965 + std::string SV = Value.str(); |
|
3966 + Handler = HandlePrefixedOrGroupedOption(SA, SV, ErrorParsing, |
|
3967 OptionsMap); |
|
3968 + } |
|
3969 |
|
3970 // Otherwise, look for the closest available option to report to the user |
|
3971 // in the upcoming error. |
|
3972 @@ -960,8 +1313,8 @@ |
|
3973 |
|
3974 if (!Handler) { |
|
3975 if (SinkOpts.empty()) { |
|
3976 - errs() << ProgramName << ": Unknown command line argument '" << argv[i] |
|
3977 - << "'. Try: '" << argv[0] << " -help'\n"; |
|
3978 + errs() << ProgramName << ": Unknown command line argument '" << Argv[i] |
|
3979 + << "'. Try: '" << Argv[0] << " -help'\n"; |
|
3980 |
|
3981 if (NearestHandler) { |
|
3982 // If we know a near match, report it as well. |
|
3983 @@ -971,10 +1324,9 @@ |
|
3984 |
|
3985 ErrorParsing = true; |
|
3986 } else { |
|
3987 - for (SmallVectorImpl<Option *>::iterator I = SinkOpts.begin(), |
|
3988 - E = SinkOpts.end(); |
|
3989 - I != E; ++I) |
|
3990 - (*I)->addOccurrence(i, "", argv[i]); |
|
3991 + for (std::vector<Option*>::iterator I = SinkOpts.begin(), |
|
3992 + E = SinkOpts.end(); I != E; ++I) |
|
3993 + (*I)->addOccurrence(i, "", Argv[i]); |
|
3994 } |
|
3995 continue; |
|
3996 } |
|
3997 @@ -984,7 +1336,7 @@ |
|
3998 if (Handler->getFormattingFlag() == cl::Positional) |
|
3999 ActivePositionalArg = Handler; |
|
4000 else |
|
4001 - ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i); |
|
4002 + ErrorParsing |= ProvideOption(Handler, ArgName, Value, Argc, Argv, i); |
|
4003 } |
|
4004 |
|
4005 // Check and handle positional arguments now... |
|
4006 @@ -992,59 +1344,85 @@ |
|
4007 errs() << ProgramName |
|
4008 << ": Not enough positional command line arguments specified!\n" |
|
4009 << "Must specify at least " << NumPositionalRequired |
|
4010 - << " positional arguments: See: " << argv[0] << " -help\n"; |
|
4011 + << " positional arguments: See: " << Argv[0] << " -help\n"; |
|
4012 |
|
4013 ErrorParsing = true; |
|
4014 } else if (!HasUnlimitedPositionals && |
|
4015 PositionalVals.size() > PositionalOpts.size()) { |
|
4016 errs() << ProgramName << ": Too many positional arguments specified!\n" |
|
4017 << "Can specify at most " << PositionalOpts.size() |
|
4018 - << " positional arguments: See: " << argv[0] << " -help\n"; |
|
4019 + << " positional arguments: See: " << Argv[0] << " -help\n"; |
|
4020 ErrorParsing = true; |
|
4021 |
|
4022 } else if (!ConsumeAfterOpt) { |
|
4023 // Positional args have already been handled if ConsumeAfter is specified. |
|
4024 - unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size()); |
|
4025 + unsigned ValNo = 0; |
|
4026 + unsigned NumVals = static_cast<unsigned>(PositionalVals.size()); |
|
4027 for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) { |
|
4028 - if (RequiresValue(PositionalOpts[i])) { |
|
4029 + Option *PO = PositionalOpts[i]; |
|
4030 + if (RequiresValue(PO)) { |
|
4031 ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo].first, |
|
4032 PositionalVals[ValNo].second); |
|
4033 ValNo++; |
|
4034 --NumPositionalRequired; // We fulfilled our duty... |
|
4035 } |
|
4036 |
|
4037 + enum llvm::cl::ValueExpected VE = PO->getValueExpectedFlag(); |
|
4038 + |
|
4039 + // If it's a positional argument, provide it |
|
4040 + if ((NumVals - ValNo) > NumPositionalRequired) { |
|
4041 + if (VE == llvm::cl::ValuePositionalNoArgs) { |
|
4042 + ProvidePositionalOption(PO, PositionalVals[ValNo].first, |
|
4043 + PositionalVals[ValNo].second); |
|
4044 + ++ValNo; |
|
4045 + --NumPositionalRequired; |
|
4046 + continue; |
|
4047 + } else if (VE == llvm::cl::ValuePositionalWithArgs) { |
|
4048 + ProvidePositionalOptionWithArgs(PO, PositionalVals[ValNo].first, |
|
4049 + PositionalVals[ValNo].second, |
|
4050 + ValNo, |
|
4051 + NumPositionalRequired); |
|
4052 + continue; |
|
4053 + } |
|
4054 + } |
|
4055 + |
|
4056 // If we _can_ give this option more arguments, do so now, as long as we |
|
4057 // do not give it values that others need. 'Done' controls whether the |
|
4058 // option even _WANTS_ any more. |
|
4059 // |
|
4060 - bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required; |
|
4061 - while (NumVals - ValNo > NumPositionalRequired && !Done) { |
|
4062 - switch (PositionalOpts[i]->getNumOccurrencesFlag()) { |
|
4063 + bool Done = |
|
4064 + ((PO->getNumOccurrencesFlag() == cl::Required) && |
|
4065 + (VE != llvm::cl::ValuePositionalNoArgs)); |
|
4066 + |
|
4067 + while (((NumVals - ValNo) > NumPositionalRequired) && !Done) { |
|
4068 + switch (PO->getNumOccurrencesFlag()) { |
|
4069 case cl::Optional: |
|
4070 Done = true; // Optional arguments want _at most_ one value |
|
4071 // FALL THROUGH |
|
4072 case cl::ZeroOrMore: // Zero or more will take all they can get... |
|
4073 case cl::OneOrMore: // One or more will take all they can get... |
|
4074 - ProvidePositionalOption(PositionalOpts[i], |
|
4075 - PositionalVals[ValNo].first, |
|
4076 + ProvidePositionalOption(PO, PositionalVals[ValNo].first, |
|
4077 PositionalVals[ValNo].second); |
|
4078 ValNo++; |
|
4079 break; |
|
4080 default: |
|
4081 - llvm_unreachable("Internal error, unexpected NumOccurrences flag in " |
|
4082 + assert(0 && "Internal Compiler Error: " |
|
4083 + "unexpected NumOccurrences flag in " |
|
4084 "positional argument processing!"); |
|
4085 + break; |
|
4086 } |
|
4087 } |
|
4088 } |
|
4089 } else { |
|
4090 - assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size()); |
|
4091 + assert(ConsumeAfterOpt && (NumPositionalRequired <= PositionalVals.size())); |
|
4092 unsigned ValNo = 0; |
|
4093 - for (size_t j = 1, e = PositionalOpts.size(); j != e; ++j) |
|
4094 - if (RequiresValue(PositionalOpts[j])) { |
|
4095 - ErrorParsing |= ProvidePositionalOption(PositionalOpts[j], |
|
4096 - PositionalVals[ValNo].first, |
|
4097 + for (size_t j = 1, e = PositionalOpts.size(); j != e; ++j) { |
|
4098 + Option *PO = PositionalOpts[j]; |
|
4099 + if (RequiresValue(PO)) { |
|
4100 + ErrorParsing |= ProvidePositionalOption(PO, PositionalVals[ValNo].first, |
|
4101 PositionalVals[ValNo].second); |
|
4102 - ValNo++; |
|
4103 + ++ValNo; |
|
4104 + } |
|
4105 } |
|
4106 |
|
4107 // Handle the case where there is just one positional option, and it's |
|
4108 @@ -1052,11 +1430,11 @@ |
|
4109 // positional option and keep the rest for the consume after. The above |
|
4110 // loop would have assigned no values to positional options in this case. |
|
4111 // |
|
4112 - if (PositionalOpts.size() == 1 && ValNo == 0 && !PositionalVals.empty()) { |
|
4113 - ErrorParsing |= ProvidePositionalOption(PositionalOpts[0], |
|
4114 + if (PositionalOpts.size() == 2 && ValNo == 0 && !PositionalVals.empty()) { |
|
4115 + ErrorParsing |= ProvidePositionalOption(PositionalOpts[1], |
|
4116 PositionalVals[ValNo].first, |
|
4117 PositionalVals[ValNo].second); |
|
4118 - ValNo++; |
|
4119 + ++ValNo; |
|
4120 } |
|
4121 |
|
4122 // Handle over all of the rest of the arguments to the |
|
4123 @@ -1076,7 +1454,7 @@ |
|
4124 Opt.second->error("must be specified at least once!"); |
|
4125 ErrorParsing = true; |
|
4126 } |
|
4127 - // Fall through |
|
4128 + break; |
|
4129 default: |
|
4130 break; |
|
4131 } |
|
4132 @@ -1086,8 +1464,8 @@ |
|
4133 // Note that if ReadResponseFiles == true, this must be done before the |
|
4134 // memory allocated for the expanded command line is free()d below. |
|
4135 DEBUG(dbgs() << "Args: "; |
|
4136 - for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' '; |
|
4137 - dbgs() << '\n';); |
|
4138 + for (int i = 0; i < Argc; ++i) |
|
4139 + dbgs() << Argv[i] << ' '; dbgs() << '\n';); |
|
4140 |
|
4141 // Free all of the memory allocated to the map. Command line options may only |
|
4142 // be processed once! |
|
4143 @@ -1119,7 +1497,8 @@ |
|
4144 if (!MultiArg) |
|
4145 NumOccurrences++; // Increment the number of times we have been seen |
|
4146 |
|
4147 - switch (getNumOccurrencesFlag()) { |
|
4148 + llvm::cl::NumOccurrencesFlag NOF = getNumOccurrencesFlag(); |
|
4149 + switch (NOF) { |
|
4150 case Optional: |
|
4151 if (NumOccurrences > 1) |
|
4152 return error("may only occur zero or one times!", ArgName); |
|
4153 @@ -1134,16 +1513,28 @@ |
|
4154 break; |
|
4155 } |
|
4156 |
|
4157 - return handleOccurrence(pos, ArgName, Value); |
|
4158 + std::string SAN = ArgName; |
|
4159 + std::string SV = Value; |
|
4160 + |
|
4161 + bool R = handleOccurrence(pos, SAN.c_str(), SV.c_str()); |
|
4162 + return R; |
|
4163 +} |
|
4164 + |
|
4165 +void Option::addOccurrence() { |
|
4166 + ++NumOccurrences; |
|
4167 } |
|
4168 |
|
4169 // getValueStr - Get the value description string, using "DefaultMsg" if nothing |
|
4170 // has been specified yet. |
|
4171 // |
|
4172 static StringRef getValueStr(const Option &O, StringRef DefaultMsg) { |
|
4173 - if (O.ValueStr.empty()) |
|
4174 + if (!O.ValueStr) |
|
4175 + return DefaultMsg; |
|
4176 + |
|
4177 + if (O.ValueStr == '\0') |
|
4178 return DefaultMsg; |
|
4179 - return O.ValueStr; |
|
4180 + |
|
4181 + return StringRef(O.ValueStr); |
|
4182 } |
|
4183 |
|
4184 //===----------------------------------------------------------------------===// |
|
4185 @@ -1151,7 +1542,10 @@ |
|
4186 // |
|
4187 |
|
4188 // Return the width of the option tag for printing... |
|
4189 -size_t alias::getOptionWidth() const { return ArgStr.size() + 6; } |
|
4190 +size_t alias::getOptionWidth() const { |
|
4191 + StringRef ArgStrRef(ArgStr); |
|
4192 + return ArgStrRef.size() + 6; |
|
4193 +} |
|
4194 |
|
4195 static void printHelpStr(StringRef HelpStr, size_t Indent, |
|
4196 size_t FirstLineIndentedBy) { |
|
4197 @@ -1166,7 +1560,8 @@ |
|
4198 // Print out the option for the alias. |
|
4199 void alias::printOptionInfo(size_t GlobalWidth) const { |
|
4200 outs() << " -" << ArgStr; |
|
4201 - printHelpStr(HelpStr, GlobalWidth, ArgStr.size() + 6); |
|
4202 + StringRef ArgStrRef(ArgStr); |
|
4203 + printHelpStr(HelpStr, GlobalWidth, ArgStrRef.size() + 6); |
|
4204 } |
|
4205 |
|
4206 //===----------------------------------------------------------------------===// |
|
4207 @@ -1178,7 +1573,8 @@ |
|
4208 |
|
4209 // Return the width of the option tag for printing... |
|
4210 size_t basic_parser_impl::getOptionWidth(const Option &O) const { |
|
4211 - size_t Len = O.ArgStr.size(); |
|
4212 + StringRef ArgStrRef(O.ArgStr); |
|
4213 + size_t Len = ArgStrRef.size(); |
|
4214 if (const char *ValName = getValueName()) |
|
4215 Len += getValueStr(O, ValName).size() + 3; |
|
4216 |
|
4217 @@ -1190,10 +1586,28 @@ |
|
4218 // |
|
4219 void basic_parser_impl::printOptionInfo(const Option &O, |
|
4220 size_t GlobalWidth) const { |
|
4221 + const char *ArgStr = O.ArgStr ? O.ArgStr : ""; |
|
4222 + bool PrintValue; |
|
4223 + |
|
4224 + if (ArgStr[0] == 'O' && ArgStr[1] == '\0') |
|
4225 + PrintValue = false; |
|
4226 + else if (ArgStr[0] == 'O' && std::isalpha(ArgStr[1]) && ArgStr[2] == '\0') |
|
4227 + PrintValue = false; |
|
4228 + else if (ArgStr[0] == 'O' && std::isdigit(ArgStr[1]) && ArgStr[2] == '\0') |
|
4229 + PrintValue = false; |
|
4230 + else if (ArgStr[0] == 'g' && ArgStr[1] == '\0') |
|
4231 + PrintValue = false; |
|
4232 + else if (ArgStr[0] == 'g' && std::isdigit(ArgStr[1]) && ArgStr[2] == '\0') |
|
4233 + PrintValue = false; |
|
4234 + else |
|
4235 + PrintValue = true; |
|
4236 + |
|
4237 outs() << " -" << O.ArgStr; |
|
4238 |
|
4239 - if (const char *ValName = getValueName()) |
|
4240 - outs() << "=<" << getValueStr(O, ValName) << '>'; |
|
4241 + if (const char *ValName = getValueName()) { |
|
4242 + if (PrintValue) |
|
4243 + outs() << "=<" << getValueStr(O, ValName) << '>'; |
|
4244 + } |
|
4245 |
|
4246 printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O)); |
|
4247 } |
|
4248 @@ -1201,7 +1615,8 @@ |
|
4249 void basic_parser_impl::printOptionName(const Option &O, |
|
4250 size_t GlobalWidth) const { |
|
4251 outs() << " -" << O.ArgStr; |
|
4252 - outs().indent(GlobalWidth - O.ArgStr.size()); |
|
4253 + StringRef ArgStrRef(O.ArgStr); |
|
4254 + outs().indent(GlobalWidth - ArgStrRef.size()); |
|
4255 } |
|
4256 |
|
4257 // parser<bool> implementation |
|
4258 @@ -1315,7 +1730,8 @@ |
|
4259 // Return the width of the option tag for printing... |
|
4260 size_t generic_parser_base::getOptionWidth(const Option &O) const { |
|
4261 if (O.hasArgStr()) { |
|
4262 - size_t Size = O.ArgStr.size() + 6; |
|
4263 + StringRef ArgStrRef(O.ArgStr); |
|
4264 + size_t Size = ArgStrRef.size() + 6; |
|
4265 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) |
|
4266 Size = std::max(Size, std::strlen(getOption(i)) + 8); |
|
4267 return Size; |
|
4268 @@ -1334,7 +1750,8 @@ |
|
4269 size_t GlobalWidth) const { |
|
4270 if (O.hasArgStr()) { |
|
4271 outs() << " -" << O.ArgStr; |
|
4272 - printHelpStr(O.HelpStr, GlobalWidth, O.ArgStr.size() + 6); |
|
4273 + StringRef ArgStrRef(O.ArgStr); |
|
4274 + printHelpStr(O.HelpStr, GlobalWidth, ArgStrRef.size() + 6); |
|
4275 |
|
4276 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { |
|
4277 size_t NumSpaces = GlobalWidth - strlen(getOption(i)) - 8; |
|
4278 @@ -1342,7 +1759,8 @@ |
|
4279 outs().indent(NumSpaces) << " - " << getDescription(i) << '\n'; |
|
4280 } |
|
4281 } else { |
|
4282 - if (!O.HelpStr.empty()) |
|
4283 + StringRef HelpStrRef(O.HelpStr); |
|
4284 + if (!HelpStrRef.empty()) |
|
4285 outs() << " " << O.HelpStr << '\n'; |
|
4286 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { |
|
4287 const char *Option = getOption(i); |
|
4288 @@ -1361,7 +1779,8 @@ |
|
4289 const Option &O, const GenericOptionValue &Value, |
|
4290 const GenericOptionValue &Default, size_t GlobalWidth) const { |
|
4291 outs() << " -" << O.ArgStr; |
|
4292 - outs().indent(GlobalWidth - O.ArgStr.size()); |
|
4293 + StringRef ArgStrRef(O.ArgStr); |
|
4294 + outs().indent(GlobalWidth - ArgStrRef.size()); |
|
4295 |
|
4296 unsigned NumOpts = getNumOptions(); |
|
4297 for (unsigned i = 0; i != NumOpts; ++i) { |
|
4298 @@ -1387,7 +1806,8 @@ |
|
4299 // printOptionDiff - Specializations for printing basic value types. |
|
4300 // |
|
4301 #define PRINT_OPT_DIFF(T) \ |
|
4302 - void parser<T>::printOptionDiff(const Option &O, T V, OptionValue<T> D, \ |
|
4303 + void llvm::cl::parser<T>::printOptionDiff(const Option &O, const T &V, \ |
|
4304 + const llvm::cl::OptionValue<T> &D, \ |
|
4305 size_t GlobalWidth) const { \ |
|
4306 printOptionName(O, GlobalWidth); \ |
|
4307 std::string Str; \ |
|
4308 @@ -1406,6 +1826,30 @@ |
|
4309 outs() << ")\n"; \ |
|
4310 } |
|
4311 |
|
4312 +#if 0 |
|
4313 +void |
|
4314 +llvm::cl::parser<bool>::printOptionDiff(const Option &O, bool V, |
|
4315 + const llvm::cl::OptionValue<bool> &D, |
|
4316 + size_t GlobalWidth) const { |
|
4317 + printOptionName(O, GlobalWidth); |
|
4318 + std::string Str; |
|
4319 + { |
|
4320 + raw_string_ostream SS(Str); |
|
4321 + SS << V; |
|
4322 + } |
|
4323 + outs() << "= " << Str; |
|
4324 + size_t NumSpaces = |
|
4325 + MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; |
|
4326 + outs().indent(NumSpaces) << " (default: "; |
|
4327 + if (D.hasValue()) |
|
4328 + outs() << D.getValue(); |
|
4329 + else |
|
4330 + outs() << "*no default*"; |
|
4331 + outs() << ")\n"; |
|
4332 +} |
|
4333 +#endif |
|
4334 + |
|
4335 + |
|
4336 PRINT_OPT_DIFF(bool) |
|
4337 PRINT_OPT_DIFF(boolOrDefault) |
|
4338 PRINT_OPT_DIFF(int) |
|
4339 @@ -1415,11 +1859,13 @@ |
|
4340 PRINT_OPT_DIFF(float) |
|
4341 PRINT_OPT_DIFF(char) |
|
4342 |
|
4343 -void parser<std::string>::printOptionDiff(const Option &O, StringRef V, |
|
4344 - OptionValue<std::string> D, |
|
4345 +void |
|
4346 +parser<std::string>::printOptionDiff(const Option &O, |
|
4347 + const std::string &V, |
|
4348 + const llvm::cl::OptionValue<std::string> &D, |
|
4349 size_t GlobalWidth) const { |
|
4350 printOptionName(O, GlobalWidth); |
|
4351 - outs() << "= " << V; |
|
4352 + outs() << "= " << V.c_str(); |
|
4353 size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0; |
|
4354 outs().indent(NumSpaces) << " (default: "; |
|
4355 if (D.hasValue()) |
|
4356 @@ -1439,19 +1885,21 @@ |
|
4357 //===----------------------------------------------------------------------===// |
|
4358 // -help and -help-hidden option implementation |
|
4359 // |
|
4360 - |
|
4361 -static int OptNameCompare(const std::pair<const char *, Option *> *LHS, |
|
4362 - const std::pair<const char *, Option *> *RHS) { |
|
4363 - return strcmp(LHS->first, RHS->first); |
|
4364 +template<typename Ty> |
|
4365 +struct OptNameCompare : public std::binary_function<Ty, Ty, bool> { |
|
4366 + inline bool operator()(const Ty& LHS, const Ty& RHS) const { |
|
4367 + return std::strcmp(LHS.first, RHS.first) <= 0; |
|
4368 } |
|
4369 +}; |
|
4370 |
|
4371 // Copy Options into a vector so we can sort them as we like. |
|
4372 -static void sortOpts(StringMap<Option *> &OptMap, |
|
4373 - SmallVectorImpl<std::pair<const char *, Option *>> &Opts, |
|
4374 +static void sortOpts(llvm::cl::StdStringMap &OptMap, |
|
4375 + std::vector<std::pair<const char *, Option *>> &Opts, |
|
4376 bool ShowHidden) { |
|
4377 - SmallPtrSet<Option *, 128> OptionSet; // Duplicate option detection. |
|
4378 + SmallPtrSet<Option *, 256> OptionSet; // Duplicate option detection. |
|
4379 + // Uh-huh. Really? Where is it used? |
|
4380 |
|
4381 - for (StringMap<Option *>::iterator I = OptMap.begin(), E = OptMap.end(); |
|
4382 + for (llvm::cl::StdStringMap::iterator I = OptMap.begin(), E = OptMap.end(); |
|
4383 I != E; ++I) { |
|
4384 // Ignore really-hidden options. |
|
4385 if (I->second->getOptionHiddenFlag() == ReallyHidden) |
|
4386 @@ -1465,21 +1913,29 @@ |
|
4387 if (!OptionSet.insert(I->second).second) |
|
4388 continue; |
|
4389 |
|
4390 - Opts.push_back( |
|
4391 - std::pair<const char *, Option *>(I->getKey().data(), I->second)); |
|
4392 + std::pair<const char*, Option*> KVP(I->first.c_str(), I->second); |
|
4393 + Opts.push_back(KVP); |
|
4394 } |
|
4395 |
|
4396 // Sort the options list alphabetically. |
|
4397 - array_pod_sort(Opts.begin(), Opts.end(), OptNameCompare); |
|
4398 + OptNameCompare<std::pair<const char*, Option*> > ONC; |
|
4399 + std::sort(Opts.begin(), Opts.end(), ONC); |
|
4400 } |
|
4401 |
|
4402 namespace { |
|
4403 |
|
4404 class HelpPrinter { |
|
4405 +private: |
|
4406 + /// Force the allocation of storage space with suitable alignment |
|
4407 + /// for this class because we use a static instance of it as |
|
4408 + /// designated external storage for version option parsing (see below). |
|
4409 + uint64_t B[4]; |
|
4410 + |
|
4411 protected: |
|
4412 const bool ShowHidden; |
|
4413 - typedef SmallVector<std::pair<const char *, Option *>, 128> |
|
4414 + typedef std::vector<std::pair<const char *, Option *> > |
|
4415 StrOptionPairVector; |
|
4416 + |
|
4417 // Print the options. Opts is assumed to be alphabetically sorted. |
|
4418 virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) { |
|
4419 for (size_t i = 0, e = Opts.size(); i != e; ++i) |
|
4420 @@ -1487,7 +1943,11 @@ |
|
4421 } |
|
4422 |
|
4423 public: |
|
4424 - explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {} |
|
4425 + explicit HelpPrinter(bool showHidden = false) |
|
4426 + : ShowHidden(showHidden) { |
|
4427 + (void) std::memset(B, 0, sizeof(B)); |
|
4428 + } |
|
4429 + |
|
4430 virtual ~HelpPrinter() {} |
|
4431 |
|
4432 // Invoke the printer. |
|
4433 @@ -1495,6 +1955,12 @@ |
|
4434 if (!Value) |
|
4435 return; |
|
4436 |
|
4437 + // Get all the options, |
|
4438 + std::vector<Option *> PositionalOpts; |
|
4439 + std::vector<Option *> SinkOpts; |
|
4440 + llvm::cl::StdStringMap OptionsMap; |
|
4441 + CommandLineParser::GetOptionInfo(PositionalOpts, SinkOpts, OptionsMap); |
|
4442 + |
|
4443 StrOptionPairVector Opts; |
|
4444 sortOpts(GlobalParser->OptionsMap, Opts, ShowHidden); |
|
4445 |
|
4446 @@ -1503,6 +1969,12 @@ |
|
4447 |
|
4448 outs() << "USAGE: " << GlobalParser->ProgramName << " [options]"; |
|
4449 |
|
4450 + // Print out the positional options. |
|
4451 + Option *CAOpt = nullptr; // The cl::ConsumeAfter option, if it exists... |
|
4452 + if (!PositionalOpts.empty() && |
|
4453 + PositionalOpts[0]->getNumOccurrencesFlag() == ConsumeAfter) |
|
4454 + CAOpt = PositionalOpts[0]; |
|
4455 + |
|
4456 for (auto Opt : GlobalParser->PositionalOpts) { |
|
4457 if (Opt->hasArgStr()) |
|
4458 outs() << " --" << Opt->ArgStr; |
|
4459 @@ -1512,6 +1984,8 @@ |
|
4460 // Print the consume after option info if it exists... |
|
4461 if (GlobalParser->ConsumeAfterOpt) |
|
4462 outs() << " " << GlobalParser->ConsumeAfterOpt->HelpStr; |
|
4463 + else if (CAOpt) |
|
4464 + outs() << " " << CAOpt->HelpStr; |
|
4465 |
|
4466 outs() << "\n\n"; |
|
4467 |
|
4468 @@ -1531,6 +2005,11 @@ |
|
4469 // Halt the program since help information was printed |
|
4470 exit(0); |
|
4471 } |
|
4472 + |
|
4473 + void operator=(const HelpPrinter &RHS) { |
|
4474 + HelpPrinter::operator=(true); |
|
4475 + } |
|
4476 + |
|
4477 }; |
|
4478 |
|
4479 class CategorizedHelpPrinter : public HelpPrinter { |
|
4480 @@ -1619,80 +2098,148 @@ |
|
4481 } |
|
4482 }; |
|
4483 |
|
4484 -// This wraps the Uncategorizing and Categorizing printers and decides |
|
4485 -// at run time which should be invoked. |
|
4486 -class HelpPrinterWrapper { |
|
4487 +// Declare the four HelpPrinter instances that are used to print out help, or |
|
4488 +// help-hidden as an uncategorized list or in categories. |
|
4489 +static HelpPrinter UncategorizedNormalPrinter(false); |
|
4490 +static HelpPrinter UncategorizedHiddenPrinter(true); |
|
4491 +static CategorizedHelpPrinter CategorizedNormalPrinter(false); |
|
4492 +static CategorizedHelpPrinter CategorizedHiddenPrinter(true); |
|
4493 + |
|
4494 +// This wraps the Uncategorizing and Categorizing Normal printers |
|
4495 +// and decides at run time which should be invoked. |
|
4496 +// Except it doesn't work the way you think it does. |
|
4497 +class NormalHelpPrinterWrapper { |
|
4498 private: |
|
4499 HelpPrinter &UncategorizedPrinter; |
|
4500 CategorizedHelpPrinter &CategorizedPrinter; |
|
4501 |
|
4502 public: |
|
4503 - explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter, |
|
4504 - CategorizedHelpPrinter &CategorizedPrinter) |
|
4505 - : UncategorizedPrinter(UncategorizedPrinter), |
|
4506 - CategorizedPrinter(CategorizedPrinter) {} |
|
4507 + explicit NormalHelpPrinterWrapper(HelpPrinter &UNP = |
|
4508 + UncategorizedNormalPrinter, |
|
4509 + CategorizedHelpPrinter &CNP = |
|
4510 + CategorizedNormalPrinter) |
|
4511 + : UncategorizedPrinter(UNP), CategorizedPrinter(CNP) { } |
|
4512 |
|
4513 // Invoke the printer. |
|
4514 void operator=(bool Value); |
|
4515 + void operator=(const NormalHelpPrinterWrapper &RHS); |
|
4516 +}; |
|
4517 + |
|
4518 +class HiddenHelpPrinterWrapper { |
|
4519 +private: |
|
4520 + HelpPrinter &UncategorizedPrinter; |
|
4521 + CategorizedHelpPrinter &CategorizedPrinter; |
|
4522 + |
|
4523 +public: |
|
4524 + explicit HiddenHelpPrinterWrapper(HelpPrinter &UHP = |
|
4525 + UncategorizedHiddenPrinter, |
|
4526 + CategorizedHelpPrinter &CHP = |
|
4527 + CategorizedHiddenPrinter) |
|
4528 + : UncategorizedPrinter(UHP), CategorizedPrinter(CHP) { } |
|
4529 + |
|
4530 + // Invoke the printer. |
|
4531 + void operator=(bool Value); |
|
4532 + void operator=(const HiddenHelpPrinterWrapper &RHS); |
|
4533 }; |
|
4534 |
|
4535 } // End anonymous namespace |
|
4536 |
|
4537 +#if 0 |
|
4538 // Declare the four HelpPrinter instances that are used to print out help, or |
|
4539 // help-hidden as an uncategorized list or in categories. |
|
4540 static HelpPrinter UncategorizedNormalPrinter(false); |
|
4541 static HelpPrinter UncategorizedHiddenPrinter(true); |
|
4542 static CategorizedHelpPrinter CategorizedNormalPrinter(false); |
|
4543 static CategorizedHelpPrinter CategorizedHiddenPrinter(true); |
|
4544 +#endif |
|
4545 |
|
4546 // Declare HelpPrinter wrappers that will decide whether or not to invoke |
|
4547 // a categorizing help printer |
|
4548 -static HelpPrinterWrapper WrappedNormalPrinter(UncategorizedNormalPrinter, |
|
4549 - CategorizedNormalPrinter); |
|
4550 -static HelpPrinterWrapper WrappedHiddenPrinter(UncategorizedHiddenPrinter, |
|
4551 - CategorizedHiddenPrinter); |
|
4552 +static NormalHelpPrinterWrapper |
|
4553 +WrappedNormalPrinter(UncategorizedNormalPrinter, CategorizedNormalPrinter); |
|
4554 + |
|
4555 +static HiddenHelpPrinterWrapper |
|
4556 +WrappedHiddenPrinter(UncategorizedHiddenPrinter, CategorizedHiddenPrinter); |
|
4557 |
|
4558 // Define a category for generic options that all tools should have. |
|
4559 -static cl::OptionCategory GenericCategory("Generic Options"); |
|
4560 +static cl::OptionCategory |
|
4561 +GenericCategory("Generic Options"); |
|
4562 |
|
4563 // Define uncategorized help printers. |
|
4564 // -help-list is hidden by default because if Option categories are being used |
|
4565 // then -help behaves the same as -help-list. |
|
4566 -static cl::opt<HelpPrinter, true, parser<bool>> HLOp( |
|
4567 - "help-list", |
|
4568 +// static cl::opt<HelpPrinter, true, parser<bool>> HLOp( |
|
4569 +static cl::opt<HelpPrinter, false, parser<bool>> |
|
4570 +HLOp("help-list", |
|
4571 cl::desc("Display list of available options (-help-list-hidden for more)"), |
|
4572 - cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed, |
|
4573 + cl::location(UncategorizedNormalPrinter), cl::Hidden, |
|
4574 + cl::ValueDisallowed, |
|
4575 cl::cat(GenericCategory)); |
|
4576 |
|
4577 -static cl::opt<HelpPrinter, true, parser<bool>> |
|
4578 - HLHOp("help-list-hidden", cl::desc("Display list of all available options"), |
|
4579 - cl::location(UncategorizedHiddenPrinter), cl::Hidden, |
|
4580 - cl::ValueDisallowed, cl::cat(GenericCategory)); |
|
4581 +// static cl::opt<HelpPrinter, true, parser<bool>> |
|
4582 +static cl::opt<HelpPrinter, false, parser<bool>> |
|
4583 +HLHOp("help-list-hidden", |
|
4584 + cl::desc("Display list of all available options"), |
|
4585 + cl::location(UncategorizedHiddenPrinter), |
|
4586 + cl::Hidden, |
|
4587 + cl::ValueDisallowed, |
|
4588 + cl::cat(GenericCategory)); |
|
4589 |
|
4590 // Define uncategorized/categorized help printers. These printers change their |
|
4591 // behaviour at runtime depending on whether one or more Option categories have |
|
4592 // been declared. |
|
4593 -static cl::opt<HelpPrinterWrapper, true, parser<bool>> |
|
4594 - HOp("help", cl::desc("Display available options (-help-hidden for more)"), |
|
4595 - cl::location(WrappedNormalPrinter), cl::ValueDisallowed, |
|
4596 +// static cl::opt<HelpPrinterWrapper, true, parser<bool>> |
|
4597 +static cl::opt<NormalHelpPrinterWrapper, false, parser<bool>> |
|
4598 +HOp("help", |
|
4599 + cl::desc("Display available options (-help-hidden for more)"), |
|
4600 + cl::location(WrappedNormalPrinter), |
|
4601 + cl::ValueDisallowed, |
|
4602 cl::cat(GenericCategory)); |
|
4603 |
|
4604 -static cl::opt<HelpPrinterWrapper, true, parser<bool>> |
|
4605 - HHOp("help-hidden", cl::desc("Display all available options"), |
|
4606 - cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed, |
|
4607 +// static cl::opt<HelpPrinterWrapper, true, parser<bool>> |
|
4608 +static cl::opt<HiddenHelpPrinterWrapper, false, parser<bool>> |
|
4609 +HHOp("help-hidden", |
|
4610 + cl::desc("Display all available options"), |
|
4611 + cl::location(WrappedHiddenPrinter), cl::Hidden, |
|
4612 + cl::ValueDisallowed, |
|
4613 cl::cat(GenericCategory)); |
|
4614 |
|
4615 -static cl::opt<bool> PrintOptions( |
|
4616 - "print-options", |
|
4617 +static cl::opt<bool> |
|
4618 +PrintOptions("print-options", |
|
4619 cl::desc("Print non-default options after command line parsing"), |
|
4620 - cl::Hidden, cl::init(false), cl::cat(GenericCategory)); |
|
4621 + cl::Hidden, |
|
4622 + cl::init(false), |
|
4623 + cl::cat(GenericCategory)); |
|
4624 + |
|
4625 +static cl::opt<bool> |
|
4626 +PrintAllOptions("print-all-options", |
|
4627 + cl::desc("Print all option values after command line parsing"), |
|
4628 + cl::Hidden, |
|
4629 + cl::init(false), |
|
4630 + cl::cat(GenericCategory)); |
|
4631 |
|
4632 -static cl::opt<bool> PrintAllOptions( |
|
4633 - "print-all-options", |
|
4634 - cl::desc("Print all option values after command line parsing"), cl::Hidden, |
|
4635 - cl::init(false), cl::cat(GenericCategory)); |
|
4636 +void NormalHelpPrinterWrapper::operator=(bool Value) { |
|
4637 + if (!Value) |
|
4638 + return; |
|
4639 |
|
4640 -void HelpPrinterWrapper::operator=(bool Value) { |
|
4641 + // Decide which printer to invoke. If more than one option category is |
|
4642 + // registered then it is useful to show the categorized help instead of |
|
4643 + // uncategorized help. |
|
4644 + if (GlobalParser->RegisteredOptionCategories.size() > 1) { |
|
4645 + // unhide -help-list option so user can have uncategorized output if they |
|
4646 + // want it. |
|
4647 + HLOp.setHiddenFlag(NotHidden); |
|
4648 + |
|
4649 + CategorizedPrinter = true; // Invoke categorized printer |
|
4650 + } else |
|
4651 + UncategorizedPrinter = true; // Invoke uncategorized printer |
|
4652 +} |
|
4653 + |
|
4654 +void NormalHelpPrinterWrapper::operator=(const NormalHelpPrinterWrapper &RHS) { |
|
4655 + NormalHelpPrinterWrapper::operator=(true); |
|
4656 +} |
|
4657 + |
|
4658 +void HiddenHelpPrinterWrapper::operator=(bool Value) { |
|
4659 if (!Value) |
|
4660 return; |
|
4661 |
|
4662 @@ -1709,14 +2256,20 @@ |
|
4663 UncategorizedPrinter = true; // Invoke uncategorized printer |
|
4664 } |
|
4665 |
|
4666 +void HiddenHelpPrinterWrapper::operator=(const HiddenHelpPrinterWrapper &RHS) { |
|
4667 + HiddenHelpPrinterWrapper::operator=(true); |
|
4668 +} |
|
4669 + |
|
4670 // Print the value of each option. |
|
4671 -void cl::PrintOptionValues() { GlobalParser->printOptionValues(); } |
|
4672 +void cl::PrintOptionValues() { GlobalParser->PrintOptionValues(); } |
|
4673 |
|
4674 -void CommandLineParser::printOptionValues() { |
|
4675 +void CommandLineParser::PrintOptionValues() { |
|
4676 if (!PrintOptions && !PrintAllOptions) |
|
4677 return; |
|
4678 |
|
4679 - SmallVector<std::pair<const char *, Option *>, 128> Opts; |
|
4680 + GetOptionInfo(PositionalOpts, SinkOpts, OptionsMap); |
|
4681 + |
|
4682 + std::vector<std::pair<const char *, Option *> > Opts; |
|
4683 sortOpts(OptionsMap, Opts, /*ShowHidden*/ true); |
|
4684 |
|
4685 // Compute the maximum argument length... |
|
4686 @@ -1732,35 +2285,51 @@ |
|
4687 |
|
4688 static std::vector<void (*)()> *ExtraVersionPrinters = nullptr; |
|
4689 |
|
4690 -namespace { |
|
4691 +namespace llvm { |
|
4692 + namespace cl { |
|
4693 class VersionPrinter { |
|
4694 + private: |
|
4695 + /// Force the allocation of storage space with suitable alignment |
|
4696 + /// for this class because we use a static instance of it as |
|
4697 + /// designated external storage for version option parsing (see below). |
|
4698 + uint64_t B[4]; |
|
4699 + |
|
4700 public: |
|
4701 + VersionPrinter() { |
|
4702 + (void) std::memset(B, 0, sizeof(B)); |
|
4703 + } |
|
4704 + |
|
4705 + static VersionPrinter &instance(); |
|
4706 + |
|
4707 void print() { |
|
4708 raw_ostream &OS = outs(); |
|
4709 - OS << "LLVM (http://llvm.org/):\n" |
|
4710 + std::cout << "LLVM (http://llvm.org/):\n" |
|
4711 << " " << PACKAGE_NAME << " version " << PACKAGE_VERSION; |
|
4712 #ifdef LLVM_VERSION_INFO |
|
4713 - OS << " " << LLVM_VERSION_INFO; |
|
4714 + std::cout < " " << LLVM_VERSION_INFO; |
|
4715 #endif |
|
4716 - OS << "\n "; |
|
4717 + std::cout << "\n "; |
|
4718 #ifndef __OPTIMIZE__ |
|
4719 - OS << "DEBUG build"; |
|
4720 + std::cout << "DEBUG build"; |
|
4721 #else |
|
4722 - OS << "Optimized build"; |
|
4723 + std::cout << "Optimized build"; |
|
4724 #endif |
|
4725 #ifndef NDEBUG |
|
4726 - OS << " with assertions"; |
|
4727 + std::cout << " with assertions"; |
|
4728 #endif |
|
4729 std::string CPU = sys::getHostCPUName(); |
|
4730 if (CPU == "generic") |
|
4731 CPU = "(unknown)"; |
|
4732 - OS << ".\n" |
|
4733 + |
|
4734 + std::cout << ".\n" |
|
4735 + |
|
4736 #if (ENABLE_TIMESTAMPS == 1) |
|
4737 << " Built " << __DATE__ << " (" << __TIME__ << ").\n" |
|
4738 #endif |
|
4739 << " Default target: " << sys::getDefaultTargetTriple() << '\n' |
|
4740 << " Host CPU: " << CPU << '\n'; |
|
4741 } |
|
4742 + |
|
4743 void operator=(bool OptionWasSpecified) { |
|
4744 if (!OptionWasSpecified) |
|
4745 return; |
|
4746 @@ -1769,33 +2338,42 @@ |
|
4747 (*OverrideVersionPrinter)(); |
|
4748 exit(0); |
|
4749 } |
|
4750 + |
|
4751 print(); |
|
4752 |
|
4753 - // Iterate over any registered extra printers and call them to add further |
|
4754 - // information. |
|
4755 + // Iterate over any registered extra printers and call them |
|
4756 + // to add further information. |
|
4757 if (ExtraVersionPrinters != nullptr) { |
|
4758 - outs() << '\n'; |
|
4759 - for (std::vector<void (*)()>::iterator I = ExtraVersionPrinters->begin(), |
|
4760 - E = ExtraVersionPrinters->end(); |
|
4761 + std::cout << std::endl; |
|
4762 + for (std::vector<void (*)()>::iterator I = |
|
4763 + ExtraVersionPrinters->begin(), E = ExtraVersionPrinters->end(); |
|
4764 I != E; ++I) |
|
4765 (*I)(); |
|
4766 } |
|
4767 |
|
4768 exit(0); |
|
4769 } |
|
4770 + |
|
4771 + void operator=(const VersionPrinter &RHS) { |
|
4772 + VersionPrinter::operator=(true); |
|
4773 + } |
|
4774 }; |
|
4775 -} // End anonymous namespace |
|
4776 + } // end namespace cl |
|
4777 +} // End namespace llvm |
|
4778 |
|
4779 // Define the --version option that prints out the LLVM version for the tool |
|
4780 -static VersionPrinter VersionPrinterInstance; |
|
4781 +static llvm::cl::VersionPrinter VersionPrinterInstance; |
|
4782 |
|
4783 -static cl::opt<VersionPrinter, true, parser<bool>> |
|
4784 - VersOp("version", cl::desc("Display the version of this program"), |
|
4785 - cl::location(VersionPrinterInstance), cl::ValueDisallowed, |
|
4786 - cl::cat(GenericCategory)); |
|
4787 +static |
|
4788 +cl::opt<llvm::cl::VersionPrinter, false, parser<bool> > |
|
4789 +VersOp("version", cl::desc("Display the version of this program"), |
|
4790 + cl::location(VersionPrinterInstance), |
|
4791 + cl::ValueRequired, |
|
4792 + cl::cat(GenericCategory)); |
|
4793 |
|
4794 // Utility function for printing the help message. |
|
4795 void cl::PrintHelpMessage(bool Hidden, bool Categorized) { |
|
4796 + |
|
4797 // This looks weird, but it actually prints the help message. The Printers are |
|
4798 // types of HelpPrinter and the help gets printed when its operator= is |
|
4799 // invoked. That's because the "normal" usages of the help printer is to be |
|
4800 @@ -1814,7 +2392,9 @@ |
|
4801 } |
|
4802 |
|
4803 /// Utility function for printing version number. |
|
4804 -void cl::PrintVersionMessage() { VersionPrinterInstance.print(); } |
|
4805 +void cl::PrintVersionMessage() { |
|
4806 + VersionPrinterInstance.print(); |
|
4807 +} |
|
4808 |
|
4809 void cl::SetVersionPrinter(void (*func)()) { OverrideVersionPrinter = func; } |
|
4810 |
|
4811 @@ -1826,7 +2406,16 @@ |
|
4812 } |
|
4813 |
|
4814 StringMap<Option *> &cl::getRegisteredOptions() { |
|
4815 - return GlobalParser->OptionsMap; |
|
4816 + |
|
4817 + GlobalParser->ReturnOptionsMap.clear(); |
|
4818 + for (llvm::cl::StdStringMap::const_iterator I = |
|
4819 + GlobalParser->OptionsMap.begin(), E = GlobalParser->OptionsMap.end(); |
|
4820 + I != E; ++I) { |
|
4821 + GlobalParser->ReturnOptionsMap.insert(std::make_pair((*I).first.c_str(), |
|
4822 + (*I).second)); |
|
4823 + } |
|
4824 + |
|
4825 + return GlobalParser->ReturnOptionsMap; |
|
4826 } |
|
4827 |
|
4828 void cl::HideUnrelatedOptions(cl::OptionCategory &Category) { |
|
4829 @@ -1852,3 +2441,4 @@ |
|
4830 const char *Overview) { |
|
4831 llvm::cl::ParseCommandLineOptions(argc, argv, Overview); |
|
4832 } |
|
4833 + |
|
4834 ### |
|
4835 --- lib/Support/Options.cpp 2014-10-15 14:54:35.000000000 -0700 |
|
4836 +++ lib/Support/Options.cpp 2016-05-14 12:34:43.808666693 -0700 |
|
4837 @@ -24,8 +24,9 @@ |
|
4838 |
|
4839 void OptionRegistry::addOption(void *Key, cl::Option *O) { |
|
4840 assert(Options.find(Key) == Options.end() && |
|
4841 - "Argument with this key already registerd"); |
|
4842 + "Argument with this key already registered"); |
|
4843 Options.insert(std::make_pair(Key, O)); |
|
4844 + O->addOccurrence(); |
|
4845 } |
|
4846 |
|
4847 static ManagedStatic<OptionRegistry> OR; |
|
4848 ### |
|
4849 --- include/llvm/Support/RandomNumberGenerator.h 2015-06-23 01:49:53.000000000 -0800 |
|
4850 +++ include/llvm/Support/RandomNumberGenerator.h 2016-07-05 06:13:50.168003475 -0800 |
|
4851 @@ -32,7 +32,11 @@ |
|
4852 class RandomNumberGenerator { |
|
4853 public: |
|
4854 /// Returns a random number in the range [0, Max). |
|
4855 - uint_fast64_t operator()(); |
|
4856 + uint64_t operator()(); |
|
4857 + |
|
4858 + /// Workaround for static global initialization order in shared |
|
4859 + /// libraries in Solaris. Solaris ld does not support init_priority. |
|
4860 + static bool Initialize(); |
|
4861 |
|
4862 private: |
|
4863 /// Seeds and salts the underlying RNG engine. |
|
4864 ### |
|
4865 --- lib/Support/RandomNumberGenerator.cpp 2015-03-23 10:19:41.000000000 -0800 |
|
4866 +++ lib/Support/RandomNumberGenerator.cpp 2016-07-05 18:49:45.063365340 -0800 |
|
4867 @@ -20,19 +20,45 @@ |
|
4868 |
|
4869 using namespace llvm; |
|
4870 |
|
4871 +#include <chrono> |
|
4872 + |
|
4873 #define DEBUG_TYPE "rng" |
|
4874 |
|
4875 + |
|
4876 // Tracking BUG: 19665 |
|
4877 // http://llvm.org/bugs/show_bug.cgi?id=19665 |
|
4878 // |
|
4879 -// Do not change to cl::opt<uint64_t> since this silently breaks argument parsing. |
|
4880 -static cl::opt<unsigned long long> |
|
4881 -Seed("rng-seed", cl::value_desc("seed"), |
|
4882 - cl::desc("Seed for the random number generator"), cl::init(0)); |
|
4883 +// Do not change to cl::opt<uint64_t> since this silently breaks |
|
4884 +// argument parsing. |
|
4885 +static llvm::cl::opt<unsigned long long> |
|
4886 +Seed(cl::Prefix, "rng-seed", |
|
4887 + cl::desc("Seed for the random number generator"), |
|
4888 + cl::value_desc("seed"), |
|
4889 + cl::NotHidden, |
|
4890 + cl::Optional, |
|
4891 + cl::init(0ULL), |
|
4892 + cl::ValueRequired); |
|
4893 + |
|
4894 +static bool InitFirst = false; |
|
4895 + |
|
4896 +bool __attribute__((noinline)) |
|
4897 +RandomNumberGenerator::Initialize() { |
|
4898 + auto Now = std::chrono::system_clock::now(); |
|
4899 + Seed.setValue(static_cast<unsigned long long>( |
|
4900 + std::chrono::system_clock::to_time_t(Now))); |
|
4901 + return true; |
|
4902 +} |
|
4903 + |
|
4904 +RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) |
|
4905 + : Generator() { |
|
4906 + if (!InitFirst) { |
|
4907 + InitFirst = RandomNumberGenerator::Initialize(); |
|
4908 + if (!InitFirst) |
|
4909 + llvm_unreachable("Static initialization failed!"); |
|
4910 + } |
|
4911 |
|
4912 -RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { |
|
4913 DEBUG( |
|
4914 - if (Seed == 0) |
|
4915 + if (Seed.getValue() == 0ULL) |
|
4916 dbgs() << "Warning! Using unseeded random number generator.\n" |
|
4917 ); |
|
4918 |
|
4919 @@ -42,9 +68,10 @@ |
|
4920 // are using a 64-bit RNG. This isn't a problem since the Mersenne |
|
4921 // twister constructor copies these correctly into its initial state. |
|
4922 std::vector<uint32_t> Data; |
|
4923 - Data.reserve(2 + Salt.size()); |
|
4924 - Data.push_back(Seed); |
|
4925 - Data.push_back(Seed >> 32); |
|
4926 + Data.resize(2 + Salt.size()); |
|
4927 + unsigned long long V = Seed.getValue(); |
|
4928 + Data.push_back(V); |
|
4929 + Data.push_back(V >> 32); |
|
4930 |
|
4931 std::copy(Salt.begin(), Salt.end(), Data.end()); |
|
4932 |
|
4933 @@ -52,6 +79,7 @@ |
|
4934 Generator.seed(SeedSeq); |
|
4935 } |
|
4936 |
|
4937 -uint_fast64_t RandomNumberGenerator::operator()() { |
|
4938 - return Generator(); |
|
4939 +uint64_t RandomNumberGenerator::operator()() { |
|
4940 + return static_cast<uint64_t>(Generator()); |
|
4941 } |
|
4942 + |
|
4943 ### |
|
4944 --- lib/Support/Unix/Path.inc 2015-11-02 09:57:24.000000000 -0500 |
|
4945 +++ lib/Support/Unix/Path.inc 2016-05-22 16:56:44.390780570 -0400 |
|
4946 @@ -469,7 +469,7 @@ |
|
4947 |
|
4948 std::error_code detail::directory_iterator_construct(detail::DirIterState &it, |
|
4949 StringRef path){ |
|
4950 - SmallString<128> path_null(path); |
|
4951 + SmallString<PATH_MAX> path_null(path); |
|
4952 DIR *directory = ::opendir(path_null.c_str()); |
|
4953 if (!directory) |
|
4954 return std::error_code(errno, std::generic_category()); |
|
4955 @@ -484,8 +484,10 @@ |
|
4956 std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) { |
|
4957 if (it.IterationHandle) |
|
4958 ::closedir(reinterpret_cast<DIR *>(it.IterationHandle)); |
|
4959 + |
|
4960 it.IterationHandle = 0; |
|
4961 - it.CurrentEntry = directory_entry(); |
|
4962 + directory_entry de; |
|
4963 + it.CurrentEntry = de; |
|
4964 return std::error_code(); |
|
4965 } |
|
4966 |
|
4967 ### |
|
4968 --- include/llvm/Support/FileSystem.h 2015-11-05 20:45:30.000000000 -0500 |
|
4969 +++ include/llvm/Support/FileSystem.h 2016-05-22 20:58:26.603743052 -0400 |
|
4970 @@ -695,15 +695,43 @@ |
|
4971 mutable file_status Status; |
|
4972 |
|
4973 public: |
|
4974 - explicit directory_entry(const Twine &path, file_status st = file_status()) |
|
4975 - : Path(path.str()) |
|
4976 - , Status(st) {} |
|
4977 + explicit directory_entry(const Twine &path, file_status ST = file_status()) |
|
4978 + : Path(path.str()), Status(ST) { } |
|
4979 |
|
4980 - directory_entry() {} |
|
4981 + directory_entry() : Path(""), Status(file_status()) { } |
|
4982 |
|
4983 - void assign(const Twine &path, file_status st = file_status()) { |
|
4984 + directory_entry(const directory_entry &RHS) |
|
4985 + : Path(RHS.Path), Status(RHS.Status) { } |
|
4986 + |
|
4987 + directory_entry(directory_entry &&RHS) |
|
4988 + : Path(""), Status(file_status()) { |
|
4989 + Path = std::move(RHS.Path); |
|
4990 + Status = std::move(RHS.Status); |
|
4991 + } |
|
4992 + |
|
4993 + ~directory_entry() { } |
|
4994 + |
|
4995 + directory_entry &operator=(const directory_entry &rhs) { |
|
4996 + if (this != &rhs) { |
|
4997 + Path = rhs.Path; |
|
4998 + Status = rhs.Status; |
|
4999 + } |
|
5000 + |
|
5001 + return *this; |
|
5002 + } |
|
5003 + |
|
5004 + const directory_entry &operator=(directory_entry &&rhs) { |
|
5005 + if (this != &rhs) { |
|
5006 + Path = std::move(rhs.Path); |
|
5007 + Status = std::move(rhs.Status); |
|
5008 + } |
|
5009 + |
|
5010 + return *this; |
|
5011 + } |
|
5012 + |
|
5013 + void assign(const Twine &path, file_status ST = file_status()) { |
|
5014 Path = path.str(); |
|
5015 - Status = st; |
|
5016 + Status = ST; |
|
5017 } |
|
5018 |
|
5019 void replace_filename(const Twine &filename, file_status st = file_status()); |
|
5020 ### |
|
5021 --- include/llvm/Support/PluginLoader.h 2015-06-23 05:49:53.000000000 -0400 |
|
5022 +++ include/llvm/Support/PluginLoader.h 2016-05-08 23:19:20.527430631 -0400 |
|
5023 @@ -22,6 +22,9 @@ |
|
5024 namespace llvm { |
|
5025 struct PluginLoader { |
|
5026 void operator=(const std::string &Filename); |
|
5027 + bool operator==(const std::string &Filename) const; |
|
5028 + bool operator!=(const std::string &Filename) const; |
|
5029 + |
|
5030 static unsigned getNumPlugins(); |
|
5031 static std::string& getPlugin(unsigned num); |
|
5032 }; |
|
5033 ### |
|
5034 --- include/llvm/Support/Process.h 2015-06-23 05:49:53.000000000 -0400 |
|
5035 +++ include/llvm/Support/Process.h 2016-05-08 23:19:20.527430631 -0400 |
|
5036 @@ -88,6 +88,12 @@ |
|
5037 ArrayRef<const char *> ArgsFromMain, |
|
5038 SpecificBumpPtrAllocator<char> &ArgAllocator); |
|
5039 |
|
5040 + /// Overload the above for a std::vector, and without the |
|
5041 + /// useless SpecificBumpPtrAllocator argument. |
|
5042 + static std::error_code |
|
5043 + GetArgumentVector(std::vector<const char *> &ArgsOut, |
|
5044 + ArrayRef<const char *> ArgsIn); |
|
5045 + |
|
5046 // This functions ensures that the standard file descriptors (input, output, |
|
5047 // and error) are properly mapped to a file descriptor before we use any of |
|
5048 // them. This should only be called by standalone programs, library |
|
5049 ### |
|
5050 --- include/llvm/Support/ThreadLocal.h 2015-06-23 02:49:53.000000000 -0700 |
|
5051 +++ include/llvm/Support/ThreadLocal.h 2016-05-24 18:32:55.335317270 -0700 |
|
5052 @@ -28,10 +28,8 @@ |
|
5053 /// |
|
5054 /// This is embedded in the class and we avoid malloc'ing/free'ing it, |
|
5055 /// to make this class more safe for use along with CrashRecoveryContext. |
|
5056 - union { |
|
5057 - char data[sizeof(ThreadLocalDataTy)]; |
|
5058 - ThreadLocalDataTy align_data; |
|
5059 - }; |
|
5060 + uint64_t data[2]; |
|
5061 + |
|
5062 public: |
|
5063 ThreadLocalImpl(); |
|
5064 virtual ~ThreadLocalImpl(); |
|
5065 @@ -42,7 +40,7 @@ |
|
5066 |
|
5067 /// ThreadLocal - A class used to abstract thread-local storage. It holds, |
|
5068 /// for each thread, a pointer a single object of type T. |
|
5069 - template<class T> |
|
5070 + template<typename T> |
|
5071 class ThreadLocal : public ThreadLocalImpl { |
|
5072 public: |
|
5073 ThreadLocal() : ThreadLocalImpl() { } |
|
5074 ### |
|
5075 --- lib/Support/ThreadLocal.cpp 2014-12-14 17:19:53.000000000 -0800 |
|
5076 +++ lib/Support/ThreadLocal.cpp 2016-05-24 18:36:15.908033311 -0700 |
|
5077 @@ -15,6 +15,8 @@ |
|
5078 #include "llvm/Support/Compiler.h" |
|
5079 #include "llvm/Support/ThreadLocal.h" |
|
5080 |
|
5081 +#include <cstring> |
|
5082 + |
|
5083 //===----------------------------------------------------------------------===// |
|
5084 //=== WARNING: Implementation here must contain only TRULY operating system |
|
5085 //=== independent code. |
|
5086 @@ -24,17 +26,24 @@ |
|
5087 // Define all methods as no-ops if threading is explicitly disabled |
|
5088 namespace llvm { |
|
5089 using namespace sys; |
|
5090 -ThreadLocalImpl::ThreadLocalImpl() : data() { } |
|
5091 + |
|
5092 +ThreadLocalImpl::ThreadLocalImpl() { |
|
5093 + (void) std::memset(data, 0, sizeof(data)); |
|
5094 +} |
|
5095 + |
|
5096 ThreadLocalImpl::~ThreadLocalImpl() { } |
|
5097 + |
|
5098 void ThreadLocalImpl::setInstance(const void* d) { |
|
5099 static_assert(sizeof(d) <= sizeof(data), "size too big"); |
|
5100 void **pd = reinterpret_cast<void**>(&data); |
|
5101 *pd = const_cast<void*>(d); |
|
5102 } |
|
5103 + |
|
5104 void *ThreadLocalImpl::getInstance() { |
|
5105 void **pd = reinterpret_cast<void**>(&data); |
|
5106 return *pd; |
|
5107 } |
|
5108 + |
|
5109 void ThreadLocalImpl::removeInstance() { |
|
5110 setInstance(nullptr); |
|
5111 } |
|
5112 ### |
|
5113 --- include/llvm/Support/BranchProbability.h 2015-12-22 09:56:14.000000000 -0900 |
|
5114 +++ include/llvm/Support/BranchProbability.h 2016-07-07 09:50:50.352228870 -0800 |
|
5115 @@ -29,6 +29,7 @@ |
|
5116 // denominator is always a constant value (here we use 1<<31 for maximum |
|
5117 // precision). |
|
5118 class BranchProbability { |
|
5119 +private: |
|
5120 // Numerator |
|
5121 uint32_t N; |
|
5122 |
|
5123 @@ -38,12 +39,32 @@ |
|
5124 |
|
5125 // Construct a BranchProbability with only numerator assuming the denominator |
|
5126 // is 1<<31. For internal use only. |
|
5127 - explicit BranchProbability(uint32_t n) : N(n) {} |
|
5128 + explicit BranchProbability(uint32_t n) : N(n) { } |
|
5129 |
|
5130 public: |
|
5131 - BranchProbability() : N(UnknownN) {} |
|
5132 + BranchProbability() : N(UnknownN) { } |
|
5133 BranchProbability(uint32_t Numerator, uint32_t Denominator); |
|
5134 |
|
5135 + // If we are using this class in STL containers (such as std::vector), |
|
5136 + // and we are indeed doing that (see CodeGen/MachineBasicBlock.cpp), |
|
5137 + // then this class must satisfiy MoveInsertable, CopyInsertable and |
|
5138 + // DefaultInsertable. |
|
5139 + BranchProbability(const BranchProbability &RHS) : N(RHS.N) { } |
|
5140 + BranchProbability(BranchProbability &&RHS) : N(std::move(RHS.N)) { } |
|
5141 + BranchProbability &operator=(const BranchProbability &RHS) { |
|
5142 + if (this != &RHS) |
|
5143 + N = RHS.N; |
|
5144 + return *this; |
|
5145 + } |
|
5146 + |
|
5147 + const BranchProbability &operator=(BranchProbability &&RHS) { |
|
5148 + if (this != &RHS) |
|
5149 + N = std::move(RHS.N); |
|
5150 + return *this; |
|
5151 + } |
|
5152 + |
|
5153 + ~BranchProbability() { } |
|
5154 + |
|
5155 bool isZero() const { return N == 0; } |
|
5156 bool isUnknown() const { return N == UnknownN; } |
|
5157 |
|
5158 ###. |
|
5159 --- lib/Support/Host.cpp 2015-12-15 08:35:29.000000000 -0500 |
|
5160 +++ lib/Support/Host.cpp 2016-05-08 23:19:20.536430850 -0400 |
|
5161 @@ -39,6 +39,11 @@ |
|
5162 #include <mach/machine.h> |
|
5163 #endif |
|
5164 |
|
5165 +#if defined(__sun__) |
|
5166 +#include <cstring> |
|
5167 +#include <kstat.h> |
|
5168 +#endif |
|
5169 + |
|
5170 #define DEBUG_TYPE "host-detection" |
|
5171 |
|
5172 //===----------------------------------------------------------------------===// |
|
5173 @@ -733,6 +738,42 @@ |
|
5174 |
|
5175 return "generic"; |
|
5176 } |
|
5177 +#elif defined(__sun__) && defined(__sparc__) |
|
5178 +StringRef sys::getHostCPUName() { |
|
5179 + kstat_ctl_t *KC = 0; |
|
5180 + kstat_t *KSP = 0; |
|
5181 + kstat_named_t *KNP = 0; |
|
5182 + static char Buffer[256]; |
|
5183 + static bool Init = false; |
|
5184 + const char *Value; |
|
5185 + |
|
5186 + if (!Init) { |
|
5187 + KC = kstat_open(); |
|
5188 + if (KC) { |
|
5189 + KSP = kstat_lookup(KC, "cpu_info", -1, "cpu_info0"); |
|
5190 + kstat_read(KC, KSP, NULL); |
|
5191 + KNP = reinterpret_cast<kstat_named_t*>(kstat_data_lookup(KSP, "brand")); |
|
5192 + Value = (const char *) KNP->value.str.addr.ptr; |
|
5193 + (void) std::sprintf(Buffer, "%s (", Value); |
|
5194 + |
|
5195 + KNP = |
|
5196 + reinterpret_cast<kstat_named_t*>(kstat_data_lookup(KSP, "cpu_type")); |
|
5197 + Value = (const char*) KNP->value.c; |
|
5198 + (void) std::strcat(Buffer, Value); |
|
5199 + (void) std::strcat(Buffer, ") "); |
|
5200 + |
|
5201 + KNP = |
|
5202 + reinterpret_cast<kstat_named_t*>(kstat_data_lookup(KSP, |
|
5203 + "implementation")); |
|
5204 + Value = (const char*) KNP->value.str.addr.ptr; |
|
5205 + (void) std::strcat(Buffer, Value); |
|
5206 + Init = true; |
|
5207 + kstat_close(KC); |
|
5208 + } |
|
5209 + } |
|
5210 + |
|
5211 + return Buffer; |
|
5212 +} |
|
5213 #else |
|
5214 StringRef sys::getHostCPUName() { |
|
5215 return "generic"; |
|
5216 --- lib/Support/MemoryBuffer.cpp 2015-10-14 21:27:19.000000000 -0400 |
|
5217 +++ lib/Support/MemoryBuffer.cpp 2016-05-08 23:19:20.536430850 -0400 |
|
5218 @@ -32,6 +32,9 @@ |
|
5219 #else |
|
5220 #include <io.h> |
|
5221 #endif |
|
5222 + |
|
5223 +#include <climits> |
|
5224 + |
|
5225 using namespace llvm; |
|
5226 |
|
5227 //===----------------------------------------------------------------------===// |
|
5228 @@ -70,7 +73,7 @@ |
|
5229 } |
|
5230 |
|
5231 void *operator new(size_t N, const NamedBufferAlloc &Alloc) { |
|
5232 - SmallString<256> NameBuf; |
|
5233 + SmallString<PATH_MAX> NameBuf; |
|
5234 StringRef NameRef = Alloc.Name.toStringRef(NameBuf); |
|
5235 |
|
5236 char *Mem = static_cast<char *>(operator new(N + NameRef.size() + 1)); |
|
5237 @@ -132,7 +135,7 @@ |
|
5238 // that MemoryBuffer and data are aligned so PointerIntPair works with them. |
|
5239 // TODO: Is 16-byte alignment enough? We copy small object files with large |
|
5240 // alignment expectations into this buffer. |
|
5241 - SmallString<256> NameBuf; |
|
5242 + SmallString<PATH_MAX> NameBuf; |
|
5243 StringRef NameRef = BufferName.toStringRef(NameBuf); |
|
5244 size_t AlignedStringLen = |
|
5245 RoundUpToAlignment(sizeof(MemoryBufferMem) + NameRef.size() + 1, 16); |
|
5246 @@ -164,7 +167,7 @@ |
|
5247 ErrorOr<std::unique_ptr<MemoryBuffer>> |
|
5248 MemoryBuffer::getFileOrSTDIN(const Twine &Filename, int64_t FileSize, |
|
5249 bool RequiresNullTerminator) { |
|
5250 - SmallString<256> NameBuf; |
|
5251 + SmallString<PATH_MAX> NameBuf; |
|
5252 StringRef NameRef = Filename.toStringRef(NameBuf); |
|
5253 |
|
5254 if (NameRef == "-") |
|
5255 --- lib/Support/PluginLoader.cpp 2012-12-03 11:50:05.000000000 -0500 |
|
5256 +++ lib/Support/PluginLoader.cpp 2016-05-08 23:19:20.536430850 -0400 |
|
5257 @@ -34,6 +34,21 @@ |
|
5258 } |
|
5259 } |
|
5260 |
|
5261 +bool PluginLoader::operator==(const std::string &Filename) const { |
|
5262 + sys::SmartScopedLock<true> Lock(*PluginsLock); |
|
5263 + for (std::vector<std::string>::const_iterator I = Plugins->begin(), |
|
5264 + E = Plugins->end(); I != E; ++I) { |
|
5265 + if (*I == Filename) |
|
5266 + return true; |
|
5267 + } |
|
5268 + |
|
5269 + return false; |
|
5270 +} |
|
5271 + |
|
5272 +bool PluginLoader::operator!=(const std::string &Filename) const { |
|
5273 + return !this->operator==(Filename); |
|
5274 +} |
|
5275 + |
|
5276 unsigned PluginLoader::getNumPlugins() { |
|
5277 sys::SmartScopedLock<true> Lock(*PluginsLock); |
|
5278 return Plugins.isConstructed() ? Plugins->size() : 0; |
|
5279 ### |
|
5280 --- lib/Support/SmallVector.cpp 2015-06-09 02:47:46.000000000 -0700 |
|
5281 +++ lib/Support/SmallVector.cpp 2016-05-23 11:37:44.177294041 -0700 |
|
5282 @@ -11,9 +11,13 @@ |
|
5283 // |
|
5284 //===----------------------------------------------------------------------===// |
|
5285 |
|
5286 +#include "llvm/Support/MathExtras.h" |
|
5287 +#include "llvm/Support/raw_ostream.h" |
|
5288 #include "llvm/ADT/SmallVector.h" |
|
5289 using namespace llvm; |
|
5290 |
|
5291 +#include <stdlib.h> |
|
5292 + |
|
5293 /// grow_pod - This is an implementation of the grow() method which only works |
|
5294 /// on POD-like datatypes and is out of line to reduce code duplication. |
|
5295 void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSizeInBytes, |
|
5296 @@ -23,15 +27,41 @@ |
|
5297 if (NewCapacityInBytes < MinSizeInBytes) |
|
5298 NewCapacityInBytes = MinSizeInBytes; |
|
5299 |
|
5300 + NewCapacityInBytes = |
|
5301 + llvm::RoundUpToAlignment(NewCapacityInBytes, llvm::alignOf<uint64_t>()); |
|
5302 + |
|
5303 void *NewElts; |
|
5304 + size_t Alignment = llvm::alignOf<uint64_t>(); |
|
5305 if (BeginX == FirstEl) { |
|
5306 - NewElts = malloc(NewCapacityInBytes); |
|
5307 +#if defined(_MSC_VER) |
|
5308 + NewElts = _aligned_malloc(Alignment, NewCapacityInBytes); |
|
5309 + assert(NewElts && "_aligned_malloc failed!"); |
|
5310 +#else |
|
5311 + int R = posix_memalign(&NewElts, Alignment, NewCapacityInBytes); |
|
5312 + assert((R == 0) && "posix_memalign failed!"); |
|
5313 +#endif |
|
5314 + |
|
5315 + assert(NewElts && "Invalid pointer after aligned allocation!"); |
|
5316 + (void) std::memset(NewElts, 0, NewCapacityInBytes); |
|
5317 |
|
5318 // Copy the elements over. No need to run dtors on PODs. |
|
5319 - memcpy(NewElts, this->BeginX, CurSizeBytes); |
|
5320 + (void) std::memcpy(NewElts, this->BeginX, CurSizeBytes); |
|
5321 } else { |
|
5322 // If this wasn't grown from the inline copy, grow the allocated space. |
|
5323 - NewElts = realloc(this->BeginX, NewCapacityInBytes); |
|
5324 +#if defined(_MSC_VER) |
|
5325 + NewElts = _aligned_malloc(Alignment, NewCapacityInBytes); |
|
5326 + assert(NewElts && "_aligned_malloc failed!"); |
|
5327 +#else |
|
5328 + int R = posix_memalign(&NewElts, Alignment, NewCapacityInBytes); |
|
5329 + assert((R == 0) && "posix_memalign failed!"); |
|
5330 +#endif |
|
5331 + |
|
5332 + assert(NewElts && "Invalid pointer after aligned allocation!"); |
|
5333 + (void) std::memset(NewElts, 0, NewCapacityInBytes); |
|
5334 + |
|
5335 + // Copy the elements over. No need to run dtors on PODs. |
|
5336 + (void) std::memcpy(NewElts, this->BeginX, CurSizeBytes); |
|
5337 + std::free(this->BeginX); |
|
5338 } |
|
5339 assert(NewElts && "Out of memory"); |
|
5340 |
|
5341 @@ -39,3 +69,4 @@ |
|
5342 this->BeginX = NewElts; |
|
5343 this->CapacityX = (char*)this->BeginX + NewCapacityInBytes; |
|
5344 } |
|
5345 + |
|
5346 ### |
|
5347 --- lib/Support/Unix/Process.inc 2015-12-11 17:52:32.000000000 -0500 |
|
5348 +++ lib/Support/Unix/Process.inc 2016-05-08 23:19:20.537430874 -0400 |
|
5349 @@ -188,6 +188,14 @@ |
|
5350 return std::error_code(); |
|
5351 } |
|
5352 |
|
5353 +std::error_code |
|
5354 +Process::GetArgumentVector(std::vector<const char *> &ArgsOut, |
|
5355 + ArrayRef<const char *> ArgsIn) { |
|
5356 + ArgsOut.insert(ArgsOut.end(), ArgsIn.begin(), ArgsIn.end()); |
|
5357 + |
|
5358 + return std::error_code(); |
|
5359 +} |
|
5360 + |
|
5361 namespace { |
|
5362 class FDCloser { |
|
5363 public: |
|
5364 --- lib/Support/Unix/Program.inc 2016-01-05 14:56:12.000000000 -0500 |
|
5365 +++ lib/Support/Unix/Program.inc 2016-05-08 23:19:20.537430874 -0400 |
|
5366 @@ -40,9 +40,6 @@ |
|
5367 #include <unistd.h> |
|
5368 #endif |
|
5369 #ifdef HAVE_POSIX_SPAWN |
|
5370 -#ifdef __sun__ |
|
5371 -#define _RESTRICT_KYWD |
|
5372 -#endif |
|
5373 #include <spawn.h> |
|
5374 |
|
5375 #if defined(__APPLE__) |
|
5376 ### |
|
5377 --- include/llvm/LinkAllPasses.h 2016-01-13 10:37:51.000000000 -0900 |
|
5378 +++ include/llvm/LinkAllPasses.h 2016-07-06 07:55:00.479529980 -0800 |
|
5379 @@ -43,18 +43,24 @@ |
|
5380 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" |
|
5381 #include "llvm/Transforms/Vectorize.h" |
|
5382 #include "llvm/Support/Valgrind.h" |
|
5383 + |
|
5384 #include <cstdlib> |
|
5385 |
|
5386 -namespace { |
|
5387 - struct ForcePassLinking { |
|
5388 +namespace llvm { |
|
5389 + class ForcePassLinking { |
|
5390 + public: |
|
5391 ForcePassLinking() { |
|
5392 // We must reference the passes in such a way that compilers will not |
|
5393 // delete it all as dead code, even with whole program optimization, |
|
5394 // yet is effectively a NO-OP. As the compiler isn't smart enough |
|
5395 // to know that getenv() never returns -1, this will do the job. |
|
5396 + // Except for the fact that your theory doesn't work. |
|
5397 if (std::getenv("bar") != (char*) -1) |
|
5398 return; |
|
5399 |
|
5400 + // Hi, GCC. Please don't throw this function away. |
|
5401 + asm(""); |
|
5402 + |
|
5403 (void) llvm::createAAEvalPass(); |
|
5404 (void) llvm::createAggressiveDCEPass(); |
|
5405 (void) llvm::createBitTrackingDCEPass(); |
|
5406 @@ -160,11 +166,13 @@ |
|
5407 (void) llvm::createPostOrderFunctionAttrsPass(); |
|
5408 (void) llvm::createReversePostOrderFunctionAttrsPass(); |
|
5409 (void) llvm::createMergeFunctionsPass(); |
|
5410 - std::string buf; |
|
5411 - llvm::raw_string_ostream os(buf); |
|
5412 - (void) llvm::createPrintModulePass(os); |
|
5413 - (void) llvm::createPrintFunctionPass(os); |
|
5414 - (void) llvm::createPrintBasicBlockPass(os); |
|
5415 + |
|
5416 + std::string S; |
|
5417 + llvm::raw_string_ostream RSO(S); |
|
5418 + (void) llvm::createPrintModulePass(RSO); |
|
5419 + (void) llvm::createPrintFunctionPass(RSO); |
|
5420 + (void) llvm::createPrintBasicBlockPass(RSO); |
|
5421 + |
|
5422 (void) llvm::createModuleDebugInfoPrinterPass(); |
|
5423 (void) llvm::createPartialInliningPass(); |
|
5424 (void) llvm::createLintPass(); |
|
5425 @@ -186,17 +194,39 @@ |
|
5426 (void) llvm::createFloat2IntPass(); |
|
5427 (void) llvm::createEliminateAvailableExternallyPass(); |
|
5428 |
|
5429 - (void)new llvm::IntervalPartition(); |
|
5430 - (void)new llvm::ScalarEvolutionWrapperPass(); |
|
5431 - llvm::Function::Create(nullptr, llvm::GlobalValue::ExternalLinkage)->viewCFGOnly(); |
|
5432 + llvm::IntervalPartition *LIP = new llvm::IntervalPartition(); |
|
5433 + (void) LIP; |
|
5434 + |
|
5435 + llvm::ScalarEvolutionWrapperPass *LSE = |
|
5436 + new llvm::ScalarEvolutionWrapperPass(); |
|
5437 + (void) LSE; |
|
5438 + |
|
5439 + llvm::Function *F = |
|
5440 + llvm::Function::Create(nullptr, llvm::GlobalValue::ExternalLinkage); |
|
5441 + (void) F; |
|
5442 + F->viewCFGOnly(); |
|
5443 + |
|
5444 llvm::RGPassManager RGM; |
|
5445 llvm::AliasAnalysis AA; |
|
5446 llvm::AliasSetTracker X(AA); |
|
5447 X.add(nullptr, 0, llvm::AAMDNodes()); // for -print-alias-sets |
|
5448 - (void) llvm::AreStatisticsEnabled(); |
|
5449 - (void) llvm::sys::RunningOnValgrind(); |
|
5450 + |
|
5451 + bool B1 = llvm::AreStatisticsEnabled(); |
|
5452 + (void) B1; |
|
5453 + bool B2 = llvm::sys::RunningOnValgrind(); |
|
5454 + (void) B1; |
|
5455 } |
|
5456 - } ForcePassLinking; // Force link by creating a global definition. |
|
5457 + |
|
5458 + ~ForcePassLinking() { } |
|
5459 + |
|
5460 + private: |
|
5461 + /// Initialization of this is done in lib/CodeGen/Passes.cpp |
|
5462 + /// because of initialization ordering problems with global |
|
5463 + /// static variables. The design of this static initialization |
|
5464 + /// dependency chain is completely broken. |
|
5465 + static ForcePassLinking *FPL; |
|
5466 + }; |
|
5467 } |
|
5468 |
|
5469 #endif |
|
5470 + |
|
5471 |
|
5472 |