1 # 21851513 severe memory corruption in the LLVM command-line parsing module |
|
2 # 21870103 TableGen makes incorrect assumptions about anonymous namespace instantiation |
|
3 # 21870087 naming convention for the InputFile key is inconsistent across LLVM utilities |
|
4 # 21870099 128 bytes for a filesystem path is definitely not enough |
|
5 # clang makes incorrect assumptions about anonymous namespace instantiation order |
|
6 # For upstream - maybe. |
|
7 --- include/llvm/Support/ThreadLocal.h 2014-12-14 17:04:45.000000000 -0800 |
|
8 +++ include/llvm/Support/ThreadLocal.h 2015-09-16 14:08:58.000000000 -0700 |
|
9 @@ -21,24 +21,22 @@ |
|
10 namespace llvm { |
|
11 namespace sys { |
|
12 // ThreadLocalImpl - Common base class of all ThreadLocal instantiations. |
|
13 // YOU SHOULD NEVER USE THIS DIRECTLY. |
|
14 class ThreadLocalImpl { |
|
15 typedef uint64_t ThreadLocalDataTy; |
|
16 /// \brief Platform-specific thread local data. |
|
17 /// |
|
18 /// This is embedded in the class and we avoid malloc'ing/free'ing it, |
|
19 /// to make this class more safe for use along with CrashRecoveryContext. |
|
20 - union { |
|
21 - char data[sizeof(ThreadLocalDataTy)]; |
|
22 - ThreadLocalDataTy align_data; |
|
23 - }; |
|
24 + uint64_t data[2]; |
|
25 + |
|
26 public: |
|
27 ThreadLocalImpl(); |
|
28 virtual ~ThreadLocalImpl(); |
|
29 void setInstance(const void* d); |
|
30 void *getInstance(); |
|
31 void removeInstance(); |
|
32 }; |
|
33 |
|
34 /// ThreadLocal - A class used to abstract thread-local storage. It holds, |
|
35 /// for each thread, a pointer a single object of type T. |
|
36 --- lib/Support/MemoryBuffer.cpp 2014-12-12 14:27:53.000000000 -0800 |
|
37 +++ lib/Support/MemoryBuffer.cpp 2015-09-19 14:20:06.472430028 -0700 |
|
38 @@ -21,25 +21,29 @@ |
|
39 #include "llvm/Support/Path.h" |
|
40 #include "llvm/Support/Process.h" |
|
41 #include "llvm/Support/Program.h" |
|
42 #include <cassert> |
|
43 #include <cerrno> |
|
44 #include <cstdio> |
|
45 #include <cstring> |
|
46 #include <new> |
|
47 #include <sys/types.h> |
|
48 #include <system_error> |
|
49 + |
|
50 #if !defined(_MSC_VER) && !defined(__MINGW32__) |
|
51 #include <unistd.h> |
|
52 #else |
|
53 #include <io.h> |
|
54 #endif |
|
55 + |
|
56 +#include <climits> |
|
57 + |
|
58 using namespace llvm; |
|
59 |
|
60 //===----------------------------------------------------------------------===// |
|
61 // MemoryBuffer implementation itself. |
|
62 //===----------------------------------------------------------------------===// |
|
63 |
|
64 MemoryBuffer::~MemoryBuffer() { } |
|
65 |
|
66 /// init - Initialize this MemoryBuffer as a reference to externally allocated |
|
67 /// memory, memory that we know is already null terminated. |
|
68 @@ -63,21 +67,21 @@ |
|
69 } |
|
70 |
|
71 namespace { |
|
72 struct NamedBufferAlloc { |
|
73 const Twine &Name; |
|
74 NamedBufferAlloc(const Twine &Name) : Name(Name) {} |
|
75 }; |
|
76 } |
|
77 |
|
78 void *operator new(size_t N, const NamedBufferAlloc &Alloc) { |
|
79 - SmallString<256> NameBuf; |
|
80 + SmallString<PATH_MAX> NameBuf; |
|
81 StringRef NameRef = Alloc.Name.toStringRef(NameBuf); |
|
82 |
|
83 char *Mem = static_cast<char *>(operator new(N + NameRef.size() + 1)); |
|
84 CopyStringRef(Mem + N, NameRef); |
|
85 return Mem; |
|
86 } |
|
87 |
|
88 namespace { |
|
89 /// MemoryBufferMem - Named MemoryBuffer pointing to a block of memory. |
|
90 class MemoryBufferMem : public MemoryBuffer { |
|
91 @@ -156,21 +160,21 @@ |
|
92 MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) { |
|
93 std::unique_ptr<MemoryBuffer> SB = getNewUninitMemBuffer(Size, BufferName); |
|
94 if (!SB) |
|
95 return nullptr; |
|
96 memset(const_cast<char*>(SB->getBufferStart()), 0, Size); |
|
97 return SB; |
|
98 } |
|
99 |
|
100 ErrorOr<std::unique_ptr<MemoryBuffer>> |
|
101 MemoryBuffer::getFileOrSTDIN(const Twine &Filename, int64_t FileSize) { |
|
102 - SmallString<256> NameBuf; |
|
103 + SmallString<PATH_MAX> NameBuf; |
|
104 StringRef NameRef = Filename.toStringRef(NameBuf); |
|
105 |
|
106 if (NameRef == "-") |
|
107 return getSTDIN(); |
|
108 return getFile(Filename, FileSize); |
|
109 } |
|
110 |
|
111 ErrorOr<std::unique_ptr<MemoryBuffer>> |
|
112 MemoryBuffer::getFileSlice(const Twine &FilePath, uint64_t MapSize, |
|
113 uint64_t Offset) { |
|
114 --- lib/Support/Unix/Program.inc 2014-12-01 16:52:01.000000000 -0800 |
|
115 +++ lib/Support/Unix/Program.inc 2015-09-19 15:34:57.144042911 -0700 |
|
116 @@ -31,23 +31,20 @@ |
|
117 #if HAVE_SIGNAL_H |
|
118 #include <signal.h> |
|
119 #endif |
|
120 #if HAVE_FCNTL_H |
|
121 #include <fcntl.h> |
|
122 #endif |
|
123 #if HAVE_UNISTD_H |
|
124 #include <unistd.h> |
|
125 #endif |
|
126 #ifdef HAVE_POSIX_SPAWN |
|
127 -#ifdef __sun__ |
|
128 -#define _RESTRICT_KYWD |
|
129 -#endif |
|
130 #include <spawn.h> |
|
131 #if !defined(__APPLE__) |
|
132 extern char **environ; |
|
133 #else |
|
134 #include <crt_externs.h> // _NSGetEnviron |
|
135 #endif |
|
136 #endif |
|
137 |
|
138 namespace llvm { |
|
139 |
|
140 --- lib/TableGen/Main.cpp 2014-12-10 23:04:54.000000000 -0800 |
|
141 +++ lib/TableGen/Main.cpp 2015-09-19 18:04:08.147911223 -0700 |
|
142 @@ -21,97 +21,118 @@ |
|
143 #include "llvm/Support/MemoryBuffer.h" |
|
144 #include "llvm/Support/ToolOutputFile.h" |
|
145 #include "llvm/TableGen/Error.h" |
|
146 #include "llvm/TableGen/Main.h" |
|
147 #include "llvm/TableGen/Record.h" |
|
148 #include <algorithm> |
|
149 #include <cstdio> |
|
150 #include <system_error> |
|
151 using namespace llvm; |
|
152 |
|
153 -namespace { |
|
154 - cl::opt<std::string> |
|
155 - OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), |
|
156 - cl::init("-")); |
|
157 - |
|
158 - cl::opt<std::string> |
|
159 - DependFilename("d", |
|
160 - cl::desc("Dependency filename"), |
|
161 - cl::value_desc("filename"), |
|
162 - cl::init("")); |
|
163 - |
|
164 - cl::opt<std::string> |
|
165 - InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); |
|
166 - |
|
167 - cl::list<std::string> |
|
168 - IncludeDirs("I", cl::desc("Directory of include files"), |
|
169 - cl::value_desc("directory"), cl::Prefix); |
|
170 -} |
|
171 +static cl::opt<std::string> |
|
172 +OutputFilename(cl::Prefix, "o", |
|
173 + cl::desc("Output filename"), |
|
174 + cl::value_desc("filename"), |
|
175 + cl::NotHidden, |
|
176 + cl::Optional, |
|
177 + cl::init("-"), |
|
178 + cl::ValueRequired); |
|
179 + |
|
180 +static cl::opt<std::string> |
|
181 +DependFilename(cl::Prefix, "d", |
|
182 + cl::desc("Dependency filename"), |
|
183 + cl::value_desc("filename"), |
|
184 + cl::NotHidden, |
|
185 + cl::Optional, |
|
186 + cl::init(""), |
|
187 + cl::ValueRequired); |
|
188 + |
|
189 +static cl::opt<std::string> |
|
190 +InputFilename(cl::Positional, "<input file>", |
|
191 + cl::desc("<input file>"), |
|
192 + cl::value_desc("Input filename"), |
|
193 + cl::NotHidden, |
|
194 + cl::Optional, |
|
195 + cl::init("-"), |
|
196 + cl::ValuePositionalNoArgs); |
|
197 + |
|
198 +static cl::list<std::string> |
|
199 +IncludeDirs(cl::Prefix, "I", |
|
200 + cl::desc("Directory of include files"), |
|
201 + cl::value_desc("directory"), |
|
202 + cl::NotHidden, |
|
203 + cl::ZeroOrMore, |
|
204 + cl::ValueRequired); |
|
205 |
|
206 /// \brief Create a dependency file for `-d` option. |
|
207 /// |
|
208 /// This functionality is really only for the benefit of the build system. |
|
209 /// It is similar to GCC's `-M*` family of options. |
|
210 static int createDependencyFile(const TGParser &Parser, const char *argv0) { |
|
211 if (OutputFilename == "-") { |
|
212 errs() << argv0 << ": the option -d must be used together with -o\n"; |
|
213 return 1; |
|
214 } |
|
215 std::error_code EC; |
|
216 tool_output_file DepOut(DependFilename, EC, sys::fs::F_Text); |
|
217 if (EC) { |
|
218 errs() << argv0 << ": error opening " << DependFilename << ":" |
|
219 << EC.message() << "\n"; |
|
220 return 1; |
|
221 } |
|
222 + |
|
223 DepOut.os() << OutputFilename << ":"; |
|
224 + |
|
225 for (const auto &Dep : Parser.getDependencies()) { |
|
226 DepOut.os() << ' ' << Dep.first; |
|
227 } |
|
228 DepOut.os() << "\n"; |
|
229 DepOut.keep(); |
|
230 return 0; |
|
231 } |
|
232 |
|
233 namespace llvm { |
|
234 |
|
235 int TableGenMain(char *argv0, TableGenMainFn *MainFn) { |
|
236 RecordKeeper Records; |
|
237 |
|
238 // Parse the input file. |
|
239 + llvm::Twine TFN(InputFilename); |
|
240 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = |
|
241 - MemoryBuffer::getFileOrSTDIN(InputFilename); |
|
242 + MemoryBuffer::getFileOrSTDIN(TFN); |
|
243 + |
|
244 if (std::error_code EC = FileOrErr.getError()) { |
|
245 errs() << "Could not open input file '" << InputFilename |
|
246 - << "': " << EC.message() << "\n"; |
|
247 + << "': " << EC.message() << "\n"; |
|
248 return 1; |
|
249 } |
|
250 |
|
251 // Tell SrcMgr about this buffer, which is what TGParser will pick up. |
|
252 SrcMgr.AddNewSourceBuffer(std::move(*FileOrErr), SMLoc()); |
|
253 |
|
254 // Record the location of the include directory so that the lexer can find |
|
255 // it later. |
|
256 - SrcMgr.setIncludeDirs(IncludeDirs); |
|
257 + SrcMgr.setIncludeDirs(IncludeDirs.getStorage()); |
|
258 |
|
259 TGParser Parser(SrcMgr, Records); |
|
260 |
|
261 if (Parser.ParseFile()) |
|
262 return 1; |
|
263 |
|
264 std::error_code EC; |
|
265 tool_output_file Out(OutputFilename, EC, sys::fs::F_Text); |
|
266 if (EC) { |
|
267 errs() << argv0 << ": error opening " << OutputFilename << ":" |
|
268 << EC.message() << "\n"; |
|
269 return 1; |
|
270 } |
|
271 + |
|
272 if (!DependFilename.empty()) { |
|
273 if (int Ret = createDependencyFile(Parser, argv0)) |
|
274 return Ret; |
|
275 } |
|
276 |
|
277 if (MainFn(Out.os(), Records)) |
|
278 return 1; |
|
279 |
|
280 if (ErrorsPrinted > 0) { |
|
281 errs() << argv0 << ": " << ErrorsPrinted << " errors.\n"; |
|
282 --- utils/TableGen/TableGen.cpp 2014-12-10 23:04:54.000000000 -0800 |
|
283 +++ utils/TableGen/TableGen.cpp 2015-09-14 16:23:45.000000000 -0700 |
|
284 @@ -37,67 +37,67 @@ |
|
285 GenFastISel, |
|
286 GenSubtarget, |
|
287 GenIntrinsic, |
|
288 GenTgtIntrinsic, |
|
289 PrintEnums, |
|
290 PrintSets, |
|
291 GenOptParserDefs, |
|
292 GenCTags |
|
293 }; |
|
294 |
|
295 -namespace { |
|
296 - cl::opt<ActionType> |
|
297 - Action(cl::desc("Action to perform:"), |
|
298 - cl::values(clEnumValN(PrintRecords, "print-records", |
|
299 - "Print all records to stdout (default)"), |
|
300 - clEnumValN(GenEmitter, "gen-emitter", |
|
301 - "Generate machine code emitter"), |
|
302 - clEnumValN(GenRegisterInfo, "gen-register-info", |
|
303 - "Generate registers and register classes info"), |
|
304 - clEnumValN(GenInstrInfo, "gen-instr-info", |
|
305 - "Generate instruction descriptions"), |
|
306 - clEnumValN(GenCallingConv, "gen-callingconv", |
|
307 - "Generate calling convention descriptions"), |
|
308 - clEnumValN(GenAsmWriter, "gen-asm-writer", |
|
309 - "Generate assembly writer"), |
|
310 - clEnumValN(GenDisassembler, "gen-disassembler", |
|
311 - "Generate disassembler"), |
|
312 - clEnumValN(GenPseudoLowering, "gen-pseudo-lowering", |
|
313 - "Generate pseudo instruction lowering"), |
|
314 - clEnumValN(GenAsmMatcher, "gen-asm-matcher", |
|
315 - "Generate assembly instruction matcher"), |
|
316 - clEnumValN(GenDAGISel, "gen-dag-isel", |
|
317 - "Generate a DAG instruction selector"), |
|
318 - clEnumValN(GenDFAPacketizer, "gen-dfa-packetizer", |
|
319 - "Generate DFA Packetizer for VLIW targets"), |
|
320 - clEnumValN(GenFastISel, "gen-fast-isel", |
|
321 - "Generate a \"fast\" instruction selector"), |
|
322 - clEnumValN(GenSubtarget, "gen-subtarget", |
|
323 - "Generate subtarget enumerations"), |
|
324 - clEnumValN(GenIntrinsic, "gen-intrinsic", |
|
325 - "Generate intrinsic information"), |
|
326 - clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic", |
|
327 - "Generate target intrinsic information"), |
|
328 - clEnumValN(PrintEnums, "print-enums", |
|
329 - "Print enum values for a class"), |
|
330 - clEnumValN(PrintSets, "print-sets", |
|
331 - "Print expanded sets for testing DAG exprs"), |
|
332 - clEnumValN(GenOptParserDefs, "gen-opt-parser-defs", |
|
333 - "Generate option definitions"), |
|
334 - clEnumValN(GenCTags, "gen-ctags", |
|
335 - "Generate ctags-compatible index"), |
|
336 - clEnumValEnd)); |
|
337 +static cl::opt<ActionType> |
|
338 +Action(cl::desc("Action to perform:"), |
|
339 + cl::values(clEnumValN(PrintRecords, "print-records", |
|
340 + "Print all records to stdout (default)"), |
|
341 + clEnumValN(GenEmitter, "gen-emitter", |
|
342 + "Generate machine code emitter"), |
|
343 + clEnumValN(GenRegisterInfo, "gen-register-info", |
|
344 + "Generate registers and register classes info"), |
|
345 + clEnumValN(GenInstrInfo, "gen-instr-info", |
|
346 + "Generate instruction descriptions"), |
|
347 + clEnumValN(GenCallingConv, "gen-callingconv", |
|
348 + "Generate calling convention descriptions"), |
|
349 + clEnumValN(GenAsmWriter, "gen-asm-writer", |
|
350 + "Generate assembly writer"), |
|
351 + clEnumValN(GenDisassembler, "gen-disassembler", |
|
352 + "Generate disassembler"), |
|
353 + clEnumValN(GenPseudoLowering, "gen-pseudo-lowering", |
|
354 + "Generate pseudo instruction lowering"), |
|
355 + clEnumValN(GenAsmMatcher, "gen-asm-matcher", |
|
356 + "Generate assembly instruction matcher"), |
|
357 + clEnumValN(GenDAGISel, "gen-dag-isel", |
|
358 + "Generate a DAG instruction selector"), |
|
359 + clEnumValN(GenDFAPacketizer, "gen-dfa-packetizer", |
|
360 + "Generate DFA Packetizer for VLIW targets"), |
|
361 + clEnumValN(GenFastISel, "gen-fast-isel", |
|
362 + "Generate a \"fast\" instruction selector"), |
|
363 + clEnumValN(GenSubtarget, "gen-subtarget", |
|
364 + "Generate subtarget enumerations"), |
|
365 + clEnumValN(GenIntrinsic, "gen-intrinsic", |
|
366 + "Generate intrinsic information"), |
|
367 + clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic", |
|
368 + "Generate target intrinsic information"), |
|
369 + clEnumValN(PrintEnums, "print-enums", |
|
370 + "Print enum values for a class"), |
|
371 + clEnumValN(PrintSets, "print-sets", |
|
372 + "Print expanded sets for testing DAG exprs"), |
|
373 + clEnumValN(GenOptParserDefs, "gen-opt-parser-defs", |
|
374 + "Generate option definitions"), |
|
375 + clEnumValN(GenCTags, "gen-ctags", |
|
376 + "Generate ctags-compatible index"), |
|
377 + clEnumValEnd)); |
|
378 |
|
379 - cl::opt<std::string> |
|
380 - Class("class", cl::desc("Print Enum list for this class"), |
|
381 - cl::value_desc("class name")); |
|
382 +static cl::opt<std::string> |
|
383 +Class("class", cl::desc("Print Enum list for this class"), |
|
384 + cl::value_desc("class name")); |
|
385 |
|
386 +namespace { |
|
387 bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { |
|
388 switch (Action) { |
|
389 case PrintRecords: |
|
390 OS << Records; // No argument, dump all contents |
|
391 break; |
|
392 case GenEmitter: |
|
393 EmitCodeEmitter(Records, OS); |
|
394 break; |
|
395 case GenRegisterInfo: |
|
396 EmitRegisterInfo(Records, OS); |
|
397 --- tools/clang/utils/TableGen/TableGen.cpp 2015-09-19 19:30:26.983452195 -0700 |
|
398 +++ tools/clang/utils/TableGen/TableGen.cpp 2015-09-19 23:12:38.299907988 -0700 |
|
399 @@ -48,101 +48,99 @@ |
|
400 GenClangCommentHTMLTagsProperties, |
|
401 GenClangCommentHTMLNamedCharacterReferences, |
|
402 GenClangCommentCommandInfo, |
|
403 GenClangCommentCommandList, |
|
404 GenArmNeon, |
|
405 GenArmNeonSema, |
|
406 GenArmNeonTest, |
|
407 GenAttrDocs |
|
408 }; |
|
409 |
|
410 -namespace { |
|
411 -cl::opt<ActionType> Action( |
|
412 - cl::desc("Action to perform:"), |
|
413 - cl::values( |
|
414 - clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes", |
|
415 - "Generate clang attribute clases"), |
|
416 - clEnumValN(GenClangAttrParserStringSwitches, |
|
417 - "gen-clang-attr-parser-string-switches", |
|
418 - "Generate all parser-related attribute string switches"), |
|
419 - clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl", |
|
420 - "Generate clang attribute implementations"), |
|
421 - clEnumValN(GenClangAttrList, "gen-clang-attr-list", |
|
422 - "Generate a clang attribute list"), |
|
423 - clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read", |
|
424 - "Generate clang PCH attribute reader"), |
|
425 - clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write", |
|
426 - "Generate clang PCH attribute writer"), |
|
427 - clEnumValN(GenClangAttrHasAttributeImpl, |
|
428 - "gen-clang-attr-has-attribute-impl", |
|
429 - "Generate a clang attribute spelling list"), |
|
430 - clEnumValN(GenClangAttrSpellingListIndex, |
|
431 - "gen-clang-attr-spelling-index", |
|
432 - "Generate a clang attribute spelling index"), |
|
433 - clEnumValN(GenClangAttrASTVisitor, |
|
434 - "gen-clang-attr-ast-visitor", |
|
435 - "Generate a recursive AST visitor for clang attributes"), |
|
436 - clEnumValN(GenClangAttrTemplateInstantiate, |
|
437 - "gen-clang-attr-template-instantiate", |
|
438 - "Generate a clang template instantiate code"), |
|
439 - clEnumValN(GenClangAttrParsedAttrList, |
|
440 - "gen-clang-attr-parsed-attr-list", |
|
441 - "Generate a clang parsed attribute list"), |
|
442 - clEnumValN(GenClangAttrParsedAttrImpl, |
|
443 - "gen-clang-attr-parsed-attr-impl", |
|
444 - "Generate the clang parsed attribute helpers"), |
|
445 - clEnumValN(GenClangAttrParsedAttrKinds, |
|
446 - "gen-clang-attr-parsed-attr-kinds", |
|
447 - "Generate a clang parsed attribute kinds"), |
|
448 - clEnumValN(GenClangAttrDump, "gen-clang-attr-dump", |
|
449 - "Generate clang attribute dumper"), |
|
450 - clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", |
|
451 - "Generate Clang diagnostics definitions"), |
|
452 - clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", |
|
453 - "Generate Clang diagnostic groups"), |
|
454 - clEnumValN(GenClangDiagsIndexName, "gen-clang-diags-index-name", |
|
455 - "Generate Clang diagnostic name index"), |
|
456 - clEnumValN(GenClangCommentNodes, "gen-clang-comment-nodes", |
|
457 - "Generate Clang AST comment nodes"), |
|
458 - clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes", |
|
459 - "Generate Clang AST declaration nodes"), |
|
460 - clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes", |
|
461 - "Generate Clang AST statement nodes"), |
|
462 - clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers", |
|
463 - "Generate Clang Static Analyzer checkers"), |
|
464 - clEnumValN(GenClangCommentHTMLTags, "gen-clang-comment-html-tags", |
|
465 - "Generate efficient matchers for HTML tag " |
|
466 - "names that are used in documentation comments"), |
|
467 - clEnumValN(GenClangCommentHTMLTagsProperties, |
|
468 - "gen-clang-comment-html-tags-properties", |
|
469 - "Generate efficient matchers for HTML tag " |
|
470 - "properties"), |
|
471 - clEnumValN(GenClangCommentHTMLNamedCharacterReferences, |
|
472 - "gen-clang-comment-html-named-character-references", |
|
473 - "Generate function to translate named character " |
|
474 - "references to UTF-8 sequences"), |
|
475 - clEnumValN(GenClangCommentCommandInfo, "gen-clang-comment-command-info", |
|
476 - "Generate command properties for commands that " |
|
477 - "are used in documentation comments"), |
|
478 - clEnumValN(GenClangCommentCommandList, "gen-clang-comment-command-list", |
|
479 - "Generate list of commands that are used in " |
|
480 - "documentation comments"), |
|
481 - clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"), |
|
482 - clEnumValN(GenArmNeonSema, "gen-arm-neon-sema", |
|
483 - "Generate ARM NEON sema support for clang"), |
|
484 - clEnumValN(GenArmNeonTest, "gen-arm-neon-test", |
|
485 - "Generate ARM NEON tests for clang"), |
|
486 - clEnumValN(GenAttrDocs, "gen-attr-docs", |
|
487 - "Generate attribute documentation"), |
|
488 - clEnumValEnd)); |
|
489 +static cl::opt<ActionType> |
|
490 +Action(cl::desc("Action to perform:"), |
|
491 + cl::values(clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes", |
|
492 + "Generate clang attribute clases"), |
|
493 + clEnumValN(GenClangAttrParserStringSwitches, |
|
494 + "gen-clang-attr-parser-string-switches", |
|
495 + "Generate all parser-related attribute string switches"), |
|
496 + clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl", |
|
497 + "Generate clang attribute implementations"), |
|
498 + clEnumValN(GenClangAttrList, "gen-clang-attr-list", |
|
499 + "Generate a clang attribute list"), |
|
500 + clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read", |
|
501 + "Generate clang PCH attribute reader"), |
|
502 + clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write", |
|
503 + "Generate clang PCH attribute writer"), |
|
504 + clEnumValN(GenClangAttrHasAttributeImpl, |
|
505 + "gen-clang-attr-has-attribute-impl", |
|
506 + "Generate a clang attribute spelling list"), |
|
507 + clEnumValN(GenClangAttrSpellingListIndex, |
|
508 + "gen-clang-attr-spelling-index", |
|
509 + "Generate a clang attribute spelling index"), |
|
510 + clEnumValN(GenClangAttrASTVisitor, |
|
511 + "gen-clang-attr-ast-visitor", |
|
512 + "Generate a recursive AST visitor for clang attributes"), |
|
513 + clEnumValN(GenClangAttrTemplateInstantiate, |
|
514 + "gen-clang-attr-template-instantiate", |
|
515 + "Generate a clang template instantiate code"), |
|
516 + clEnumValN(GenClangAttrParsedAttrList, |
|
517 + "gen-clang-attr-parsed-attr-list", |
|
518 + "Generate a clang parsed attribute list"), |
|
519 + clEnumValN(GenClangAttrParsedAttrImpl, |
|
520 + "gen-clang-attr-parsed-attr-impl", |
|
521 + "Generate the clang parsed attribute helpers"), |
|
522 + clEnumValN(GenClangAttrParsedAttrKinds, |
|
523 + "gen-clang-attr-parsed-attr-kinds", |
|
524 + "Generate a clang parsed attribute kinds"), |
|
525 + clEnumValN(GenClangAttrDump, "gen-clang-attr-dump", |
|
526 + "Generate clang attribute dumper"), |
|
527 + clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", |
|
528 + "Generate Clang diagnostics definitions"), |
|
529 + clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", |
|
530 + "Generate Clang diagnostic groups"), |
|
531 + clEnumValN(GenClangDiagsIndexName, "gen-clang-diags-index-name", |
|
532 + "Generate Clang diagnostic name index"), |
|
533 + clEnumValN(GenClangCommentNodes, "gen-clang-comment-nodes", |
|
534 + "Generate Clang AST comment nodes"), |
|
535 + clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes", |
|
536 + "Generate Clang AST declaration nodes"), |
|
537 + clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes", |
|
538 + "Generate Clang AST statement nodes"), |
|
539 + clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers", |
|
540 + "Generate Clang Static Analyzer checkers"), |
|
541 + clEnumValN(GenClangCommentHTMLTags, "gen-clang-comment-html-tags", |
|
542 + "Generate efficient matchers for HTML tag " |
|
543 + "names that are used in documentation comments"), |
|
544 + clEnumValN(GenClangCommentHTMLTagsProperties, |
|
545 + "gen-clang-comment-html-tags-properties", |
|
546 + "Generate efficient matchers for HTML tag " |
|
547 + "properties"), |
|
548 + clEnumValN(GenClangCommentHTMLNamedCharacterReferences, |
|
549 + "gen-clang-comment-html-named-character-references", |
|
550 + "Generate function to translate named character " |
|
551 + "references to UTF-8 sequences"), |
|
552 + clEnumValN(GenClangCommentCommandInfo, "gen-clang-comment-command-info", |
|
553 + "Generate command properties for commands that " |
|
554 + "are used in documentation comments"), |
|
555 + clEnumValN(GenClangCommentCommandList, "gen-clang-comment-command-list", |
|
556 + "Generate list of commands that are used in " |
|
557 + "documentation comments"), |
|
558 + clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"), |
|
559 + clEnumValN(GenArmNeonSema, "gen-arm-neon-sema", |
|
560 + "Generate ARM NEON sema support for clang"), |
|
561 + clEnumValN(GenArmNeonTest, "gen-arm-neon-test", |
|
562 + "Generate ARM NEON tests for clang"), |
|
563 + clEnumValN(GenAttrDocs, "gen-attr-docs", |
|
564 + "Generate attribute documentation"), |
|
565 + clEnumValEnd)); |
|
566 |
|
567 -cl::opt<std::string> |
|
568 +static cl::opt<std::string> |
|
569 ClangComponent("clang-component", |
|
570 cl::desc("Only use warnings from specified component"), |
|
571 cl::value_desc("component"), cl::Hidden); |
|
572 |
|
573 bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { |
|
574 switch (Action) { |
|
575 case GenClangAttrClasses: |
|
576 EmitClangAttrClass(Records, OS); |
|
577 break; |
|
578 case GenClangAttrParserStringSwitches: |
|
579 @@ -230,21 +228,20 @@ |
|
580 case GenArmNeonTest: |
|
581 EmitNeonTest(Records, OS); |
|
582 break; |
|
583 case GenAttrDocs: |
|
584 EmitClangAttrDocs(Records, OS); |
|
585 break; |
|
586 } |
|
587 |
|
588 return false; |
|
589 } |
|
590 -} |
|
591 |
|
592 int main(int argc, char **argv) { |
|
593 sys::PrintStackTraceOnErrorSignal(); |
|
594 PrettyStackTraceProgram X(argc, argv); |
|
595 cl::ParseCommandLineOptions(argc, argv); |
|
596 |
|
597 return TableGenMain(argv[0], &ClangTableGenMain); |
|
598 } |
|
599 |
|
600 #ifdef __has_feature |
|
601 --- lib/IR/LegacyPassManager.cpp 2015-01-28 09:39:35.000000000 -0800 |
|
602 +++ lib/IR/LegacyPassManager.cpp 2015-10-05 11:01:32.789436446 -0700 |
|
603 @@ -40,15 +40,18 @@ |
|
604 // pass name to be printed before it executes. |
|
605 // |
|
606 |
|
607 -namespace { |
|
608 // Different debug levels that can be enabled... |
|
609 enum PassDebugLevel { |
|
610 - Disabled, Arguments, Structure, Executions, Details |
|
611 + Disabled, |
|
612 + Arguments, |
|
613 + Structure, |
|
614 + Executions, |
|
615 + Details |
|
616 }; |
|
617 -} |
|
618 |
|
619 static cl::opt<enum PassDebugLevel> |
|
620 -PassDebugging("debug-pass", cl::Hidden, |
|
621 +PassDebugging("debug-pass", |
|
622 + cl::Hidden, |
|
623 cl::desc("Print PassManager debugging information"), |
|
624 cl::values( |
|
625 clEnumVal(Disabled , "disable debug output"), |
|
626 @@ -58,36 +61,44 @@ |
|
627 clEnumVal(Details , "print pass details when it is executed"), |
|
628 clEnumValEnd)); |
|
629 |
|
630 -namespace { |
|
631 -typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> |
|
632 -PassOptionList; |
|
633 -} |
|
634 - |
|
635 // Print IR out before/after specified passes. |
|
636 -static PassOptionList |
|
637 -PrintBefore("print-before", |
|
638 - llvm::cl::desc("Print IR before specified passes"), |
|
639 - cl::Hidden); |
|
640 - |
|
641 -static PassOptionList |
|
642 -PrintAfter("print-after", |
|
643 - llvm::cl::desc("Print IR after specified passes"), |
|
644 - cl::Hidden); |
|
645 +static llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> |
|
646 +PrintBefore(cl::Prefix, "print-before", |
|
647 + cl::desc("Print IR before specified passes"), |
|
648 + cl::value_desc("Print IR before specified passes"), |
|
649 + cl::Hidden, |
|
650 + cl::ZeroOrMore); |
|
651 + |
|
652 +static llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> |
|
653 +PrintAfter(cl::Prefix, "print-after", |
|
654 + cl::desc("Print IR after specified passes"), |
|
655 + cl::value_desc("Print IR after specified passes"), |
|
656 + cl::Hidden, |
|
657 + cl::ZeroOrMore); |
|
658 |
|
659 static cl::opt<bool> |
|
660 -PrintBeforeAll("print-before-all", |
|
661 +PrintBeforeAll(cl::NormalFormatting, "print-before-all", |
|
662 llvm::cl::desc("Print IR before each pass"), |
|
663 + llvm::cl::value_desc("Print IR before each pass"), |
|
664 + cl::Hidden, |
|
665 + cl::Optional, |
|
666 cl::init(false)); |
|
667 + |
|
668 static cl::opt<bool> |
|
669 -PrintAfterAll("print-after-all", |
|
670 +PrintAfterAll(cl::NormalFormatting, "print-after-all", |
|
671 llvm::cl::desc("Print IR after each pass"), |
|
672 + llvm::cl::value_desc("Print IR after each pass"), |
|
673 + cl::Hidden, |
|
674 + cl::Optional, |
|
675 cl::init(false)); |
|
676 |
|
677 /// This is a helper to determine whether to print IR before or |
|
678 /// after a pass. |
|
679 |
|
680 -static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI, |
|
681 - PassOptionList &PassesToPrint) { |
|
682 +static bool |
|
683 +ShouldPrintBeforeOrAfterPass(const PassInfo *PI, |
|
684 + llvm::cl::list<const llvm::PassInfo *, bool, |
|
685 + PassNameParser> &PassesToPrint) { |
|
686 for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { |
|
687 const llvm::PassInfo *PassInf = PassesToPrint[i]; |
|
688 if (PassInf) |
|
689 --- lib/Support/CommandLine.cpp 2015-01-13 11:14:20.000000000 -0800 |
|
690 +++ lib/Support/CommandLine.cpp 2016-01-19 10:13:33.212967353 -0800 |
|
691 @@ -41,6 +41,8 @@ |
|
692 |
|
693 #define DEBUG_TYPE "commandline" |
|
694 |
|
695 +#include <iostream> |
|
696 + |
|
697 //===----------------------------------------------------------------------===// |
|
698 // Template instantiations and anchors. |
|
699 // |
|
700 @@ -85,7 +87,7 @@ |
|
701 |
|
702 // Globals for name and overview of program. Program name is not a string to |
|
703 // avoid static ctor/dtor issues. |
|
704 -static char ProgramName[80] = "<premain>"; |
|
705 +static std::string ProgramName("<premain>"); |
|
706 static const char *ProgramOverview = nullptr; |
|
707 |
|
708 // This collects additional help to be printed. |
|
709 @@ -102,14 +104,14 @@ |
|
710 |
|
711 /// RegisteredOptionList - This is the list of the command line options that |
|
712 /// have statically constructed themselves. |
|
713 -static Option *RegisteredOptionList = nullptr; |
|
714 +Option *Option::RegisteredOptionList = nullptr; |
|
715 |
|
716 void Option::addArgument() { |
|
717 assert(!NextRegistered && "argument multiply registered!"); |
|
718 + Option *O = dynamic_cast<Option*>(this); |
|
719 + assert(O && "Cannot dynamic_cast to correct type!"); |
|
720 |
|
721 - NextRegistered = RegisteredOptionList; |
|
722 - RegisteredOptionList = this; |
|
723 - MarkOptionsChanged(); |
|
724 + Option::registerOption(O); |
|
725 } |
|
726 |
|
727 void Option::removeArgument() { |
|
728 @@ -149,24 +151,26 @@ |
|
729 |
|
730 /// GetOptionInfo - Scan the list of registered options, turning them into data |
|
731 /// structures that are easier to handle. |
|
732 -static void GetOptionInfo(SmallVectorImpl<Option *> &PositionalOpts, |
|
733 - SmallVectorImpl<Option *> &SinkOpts, |
|
734 +static void GetOptionInfo(std::vector<Option *> &PositionalOpts, |
|
735 + std::vector<Option *> &SinkOpts, |
|
736 StringMap<Option *> &OptionsMap) { |
|
737 bool HadErrors = false; |
|
738 - SmallVector<const char *, 16> OptionNames; |
|
739 + std::vector<const char *> OptionNames; |
|
740 Option *CAOpt = nullptr; // The ConsumeAfter option if it exists. |
|
741 - for (Option *O = RegisteredOptionList; O; O = O->getNextRegisteredOption()) { |
|
742 + for (Option *O = Option::getRegisteredOptionList(); O; |
|
743 + O = O->getNextRegisteredOption()) { |
|
744 // If this option wants to handle multiple option names, get the full set. |
|
745 // This handles enum options like "-O1 -O2" etc. |
|
746 O->getExtraOptionNames(OptionNames); |
|
747 - if (O->ArgStr[0]) |
|
748 + |
|
749 + if (O->ArgStr && *O->ArgStr) |
|
750 OptionNames.push_back(O->ArgStr); |
|
751 |
|
752 // Handle named options. |
|
753 for (size_t i = 0, e = OptionNames.size(); i != e; ++i) { |
|
754 // Add argument to the argument map! |
|
755 if (!OptionsMap.insert(std::make_pair(OptionNames[i], O)).second) { |
|
756 - errs() << ProgramName << ": CommandLine Error: Option '" |
|
757 + errs() << ProgramName.c_str() << ": CommandLine Error: Option '" |
|
758 << OptionNames[i] << "' registered more than once!\n"; |
|
759 HadErrors = true; |
|
760 } |
|
761 @@ -201,6 +205,24 @@ |
|
762 report_fatal_error("inconsistency in registered CommandLine options"); |
|
763 } |
|
764 |
|
765 +/// HandleSpecialPrefixOptions - certain options need special handling |
|
766 +/// of their Argyment/Value pair, because there will be no space separator |
|
767 +/// between the two. For example -O<N> (optimization level). |
|
768 +static void HandleSpecialPrefixOptions(StringRef &ArgName, StringRef &Value) { |
|
769 + if (ArgName.empty()) |
|
770 + return; |
|
771 + |
|
772 + char AN = ArgName.front(); |
|
773 + switch (AN) { |
|
774 + default: |
|
775 + break; |
|
776 + case 'O': |
|
777 + Value = ArgName.substr(1, 1); |
|
778 + ArgName = ArgName.substr(0, 1); |
|
779 + break; |
|
780 + } |
|
781 +} |
|
782 + |
|
783 /// LookupOption - Lookup the option specified by the specified option on the |
|
784 /// command line. If there is a value specified (after an equal sign) return |
|
785 /// that as well. This assumes that leading dashes have already been stripped. |
|
786 @@ -210,12 +232,35 @@ |
|
787 if (Arg.empty()) |
|
788 return nullptr; |
|
789 |
|
790 + HandleSpecialPrefixOptions(Arg, Value); |
|
791 + |
|
792 size_t EqualPos = Arg.find('='); |
|
793 |
|
794 // If we have an equals sign, remember the value. |
|
795 if (EqualPos == StringRef::npos) { |
|
796 + StringRef InputFile; |
|
797 + |
|
798 // Look up the option. |
|
799 StringMap<Option *>::const_iterator I = OptionsMap.find(Arg); |
|
800 + |
|
801 + // TableGen |
|
802 + if (I == OptionsMap.end()) { |
|
803 + InputFile = "<input file>"; |
|
804 + I = OptionsMap.find(InputFile); |
|
805 + } |
|
806 + |
|
807 + // lli && llc |
|
808 + if (I == OptionsMap.end()) { |
|
809 + InputFile = "<input bitcode>"; |
|
810 + I = OptionsMap.find(InputFile); |
|
811 + } |
|
812 + |
|
813 + // opt |
|
814 + if (I == OptionsMap.end()) { |
|
815 + InputFile = "<input bitcode file>"; |
|
816 + I = OptionsMap.find(InputFile); |
|
817 + } |
|
818 + |
|
819 return I != OptionsMap.end() ? I->second : nullptr; |
|
820 } |
|
821 |
|
822 @@ -254,7 +299,7 @@ |
|
823 ie = OptionsMap.end(); |
|
824 it != ie; ++it) { |
|
825 Option *O = it->second; |
|
826 - SmallVector<const char *, 16> OptionNames; |
|
827 + std::vector<const char *> OptionNames; |
|
828 O->getExtraOptionNames(OptionNames); |
|
829 if (O->ArgStr[0]) |
|
830 OptionNames.push_back(O->ArgStr); |
|
831 @@ -322,9 +367,11 @@ |
|
832 // Enforce value requirements |
|
833 switch (Handler->getValueExpectedFlag()) { |
|
834 case ValueRequired: |
|
835 - if (!Value.data()) { // No value specified? |
|
836 + if (Value.empty()) { // No value specified? |
|
837 if (i + 1 >= argc) |
|
838 - return Handler->error("requires a value!"); |
|
839 + return |
|
840 + Handler->error("argument requires a value but none was provided!"); |
|
841 + |
|
842 // Steal the next argument, like for '-o filename' |
|
843 assert(argv && "null check"); |
|
844 Value = argv[++i]; |
|
845 @@ -335,11 +382,17 @@ |
|
846 return Handler->error("multi-valued option specified" |
|
847 " with ValueDisallowed modifier!"); |
|
848 |
|
849 - if (Value.data()) |
|
850 + if (!Value.empty()) |
|
851 return Handler->error("does not allow a value! '" + Twine(Value) + |
|
852 "' specified."); |
|
853 break; |
|
854 case ValueOptional: |
|
855 + case ValuePositionalNoArgs: |
|
856 + break; |
|
857 + case ValuePositionalWithArgs: |
|
858 + break; |
|
859 + default: |
|
860 + return Handler->error("Unknown/invalid Option type!"); |
|
861 break; |
|
862 } |
|
863 |
|
864 @@ -373,7 +426,15 @@ |
|
865 |
|
866 static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) { |
|
867 int Dummy = i; |
|
868 - return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy); |
|
869 + bool R = ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy); |
|
870 + return R; |
|
871 +} |
|
872 + |
|
873 +static bool ProvidePositionalOptionWithArgs(Option *Handler, StringRef Arg, |
|
874 + int i, unsigned &ValNo, |
|
875 + unsigned &NumPositionsRequired) { |
|
876 + // FIXME: IMPLEMENT |
|
877 + return false; |
|
878 } |
|
879 |
|
880 // Option predicates... |
|
881 @@ -416,7 +477,7 @@ |
|
882 /// see if this is a prefix or grouped option. If so, split arg into output an |
|
883 /// Arg/Value pair and return the Option to parse it with. |
|
884 static Option * |
|
885 -HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value, |
|
886 +HandlePrefixedOrGroupedOption(std::string &Arg, std::string &Value, |
|
887 bool &ErrorParsing, |
|
888 const StringMap<Option *> &OptionsMap) { |
|
889 if (Arg.size() == 1) |
|
890 @@ -465,7 +526,10 @@ |
|
891 |
|
892 static bool RequiresValue(const Option *O) { |
|
893 return O->getNumOccurrencesFlag() == cl::Required || |
|
894 - O->getNumOccurrencesFlag() == cl::OneOrMore; |
|
895 + O->getNumOccurrencesFlag() == cl::OneOrMore || |
|
896 + O->getValueExpectedFlag() == cl::ValueRequired || |
|
897 + O->getValueExpectedFlag() == cl::ValuePositionalNoArgs || |
|
898 + O->getValueExpectedFlag() == cl::ValuePositionalWithArgs; |
|
899 } |
|
900 |
|
901 static bool EatsUnboundedNumberOfValues(const Option *O) { |
|
902 @@ -480,9 +544,9 @@ |
|
903 static bool isGNUSpecial(char C) { return strchr("\\\"\' ", C); } |
|
904 |
|
905 void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver, |
|
906 - SmallVectorImpl<const char *> &NewArgv, |
|
907 + std::vector<const char *> &NewArgv, |
|
908 bool MarkEOLs) { |
|
909 - SmallString<128> Token; |
|
910 + SmallString<PATH_MAX> Token; |
|
911 for (size_t I = 0, E = Src.size(); I != E; ++I) { |
|
912 // Consume runs of whitespace. |
|
913 if (Token.empty()) { |
|
914 @@ -556,7 +620,7 @@ |
|
915 /// consumed in this case. |
|
916 /// |
|
917 /// * Otherwise, backslashes are interpreted literally. |
|
918 -static size_t parseBackslash(StringRef Src, size_t I, SmallString<128> &Token) { |
|
919 +static size_t parseBackslash(StringRef Src, size_t I, SmallString<256> &Token) { |
|
920 size_t E = Src.size(); |
|
921 int BackslashCount = 0; |
|
922 // Skip the backslashes. |
|
923 @@ -578,9 +642,9 @@ |
|
924 } |
|
925 |
|
926 void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver, |
|
927 - SmallVectorImpl<const char *> &NewArgv, |
|
928 + std::vector<const char *> &NewArgv, |
|
929 bool MarkEOLs) { |
|
930 - SmallString<128> Token; |
|
931 + SmallString<256> Token; |
|
932 |
|
933 // This is a small state machine to consume characters until it reaches the |
|
934 // end of the source string. |
|
935 @@ -657,7 +721,7 @@ |
|
936 |
|
937 static bool ExpandResponseFile(const char *FName, StringSaver &Saver, |
|
938 TokenizerCallback Tokenizer, |
|
939 - SmallVectorImpl<const char *> &NewArgv, |
|
940 + std::vector<const char *> &NewArgv, |
|
941 bool MarkEOLs = false) { |
|
942 ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = |
|
943 MemoryBuffer::getFile(FName); |
|
944 @@ -684,7 +748,7 @@ |
|
945 /// \brief Expand response files on a command line recursively using the given |
|
946 /// StringSaver and tokenization strategy. |
|
947 bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, |
|
948 - SmallVectorImpl<const char *> &Argv, |
|
949 + std::vector<const char *> &Argv, |
|
950 bool MarkEOLs) { |
|
951 unsigned RspFiles = 0; |
|
952 bool AllExpanded = true; |
|
953 @@ -711,7 +775,7 @@ |
|
954 // contents. Nested response files are expanded in subsequent iterations. |
|
955 // FIXME: If a nested response file uses a relative path, is it relative to |
|
956 // the cwd of the process or the response file? |
|
957 - SmallVector<const char *, 0> ExpandedArgv; |
|
958 + std::vector<const char *> ExpandedArgv; |
|
959 if (!ExpandResponseFile(Arg + 1, Saver, Tokenizer, ExpandedArgv, |
|
960 MarkEOLs)) { |
|
961 // We couldn't read this file, so we leave it in the argument stream and |
|
962 @@ -764,7 +828,7 @@ |
|
963 |
|
964 // Get program's "name", which we wouldn't know without the caller |
|
965 // telling us. |
|
966 - SmallVector<const char *, 20> newArgv; |
|
967 + std::vector<const char *> newArgv; |
|
968 StrDupSaver Saver; |
|
969 newArgv.push_back(Saver.SaveString(progName)); |
|
970 |
|
971 @@ -778,27 +842,25 @@ |
|
972 void cl::ParseCommandLineOptions(int argc, const char *const *argv, |
|
973 const char *Overview) { |
|
974 // Process all registered options. |
|
975 - SmallVector<Option *, 4> PositionalOpts; |
|
976 - SmallVector<Option *, 4> SinkOpts; |
|
977 + std::vector<Option*> PositionalOpts; |
|
978 + std::vector<Option*> SinkOpts; |
|
979 StringMap<Option *> Opts; |
|
980 GetOptionInfo(PositionalOpts, SinkOpts, Opts); |
|
981 |
|
982 assert((!Opts.empty() || !PositionalOpts.empty()) && "No options specified!"); |
|
983 |
|
984 // Expand response files. |
|
985 - SmallVector<const char *, 20> newArgv; |
|
986 + std::vector<const char*> newArgv; |
|
987 + |
|
988 for (int i = 0; i != argc; ++i) |
|
989 newArgv.push_back(argv[i]); |
|
990 + |
|
991 StrDupSaver Saver; |
|
992 ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv); |
|
993 argv = &newArgv[0]; |
|
994 argc = static_cast<int>(newArgv.size()); |
|
995 |
|
996 - // Copy the program name into ProgName, making sure not to overflow it. |
|
997 - StringRef ProgName = sys::path::filename(argv[0]); |
|
998 - size_t Len = std::min(ProgName.size(), size_t(79)); |
|
999 - memcpy(ProgramName, ProgName.data(), Len); |
|
1000 - ProgramName[Len] = '\0'; |
|
1001 + ProgramName = sys::path::filename(argv[0]).str(); |
|
1002 |
|
1003 ProgramOverview = Overview; |
|
1004 bool ErrorParsing = false; |
|
1005 @@ -810,6 +872,7 @@ |
|
1006 bool HasUnlimitedPositionals = false; |
|
1007 |
|
1008 Option *ConsumeAfterOpt = nullptr; |
|
1009 + |
|
1010 if (!PositionalOpts.empty()) { |
|
1011 if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) { |
|
1012 assert(PositionalOpts.size() > 1 && |
|
1013 @@ -819,8 +882,7 @@ |
|
1014 |
|
1015 // Calculate how many positional values are _required_. |
|
1016 bool UnboundedFound = false; |
|
1017 - for (size_t i = ConsumeAfterOpt ? 1 : 0, e = PositionalOpts.size(); i != e; |
|
1018 - ++i) { |
|
1019 + for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) { |
|
1020 Option *Opt = PositionalOpts[i]; |
|
1021 if (RequiresValue(Opt)) |
|
1022 ++NumPositionalRequired; |
|
1023 @@ -844,13 +906,14 @@ |
|
1024 } |
|
1025 UnboundedFound |= EatsUnboundedNumberOfValues(Opt); |
|
1026 } |
|
1027 + |
|
1028 HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt; |
|
1029 } |
|
1030 |
|
1031 // PositionalVals - A vector of "positional" arguments we accumulate into |
|
1032 // the process at the end. |
|
1033 // |
|
1034 - SmallVector<std::pair<StringRef, unsigned>, 4> PositionalVals; |
|
1035 + std::vector<std::pair<StringRef, unsigned> > PositionalVals; |
|
1036 |
|
1037 // If the program has named positional arguments, and the name has been run |
|
1038 // across, keep track of which positional argument was named. Otherwise put |
|
1039 @@ -862,39 +925,25 @@ |
|
1040 for (int i = 1; i < argc; ++i) { |
|
1041 Option *Handler = nullptr; |
|
1042 Option *NearestHandler = nullptr; |
|
1043 + Option *PrefixOrGroupHandler = nullptr; |
|
1044 std::string NearestHandlerString; |
|
1045 - StringRef Value; |
|
1046 + StringRef Value = ""; |
|
1047 StringRef ArgName = ""; |
|
1048 |
|
1049 - // If the option list changed, this means that some command line |
|
1050 - // option has just been registered or deregistered. This can occur in |
|
1051 - // response to things like -load, etc. If this happens, rescan the options. |
|
1052 - if (OptionListChanged) { |
|
1053 - PositionalOpts.clear(); |
|
1054 - SinkOpts.clear(); |
|
1055 - Opts.clear(); |
|
1056 - GetOptionInfo(PositionalOpts, SinkOpts, Opts); |
|
1057 - OptionListChanged = false; |
|
1058 - } |
|
1059 - |
|
1060 // Check to see if this is a positional argument. This argument is |
|
1061 // considered to be positional if it doesn't start with '-', if it is "-" |
|
1062 // itself, or if we have seen "--" already. |
|
1063 // |
|
1064 - if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) { |
|
1065 - // Positional argument! |
|
1066 - if (ActivePositionalArg) { |
|
1067 - ProvidePositionalOption(ActivePositionalArg, argv[i], i); |
|
1068 - continue; // We are done! |
|
1069 - } |
|
1070 - |
|
1071 + if (((argv[i][0] != '-') && (argv[i][1] != '\0')) || |
|
1072 + ((argv[i][0] == '-') && (argv[i][1] == '\0')) || DashDashFound) { |
|
1073 if (!PositionalOpts.empty()) { |
|
1074 PositionalVals.push_back(std::make_pair(argv[i], i)); |
|
1075 |
|
1076 // All of the positional arguments have been fulfulled, give the rest to |
|
1077 // the consume after option... if it's specified... |
|
1078 // |
|
1079 - if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) { |
|
1080 + if ((PositionalVals.size() >= NumPositionalRequired) && |
|
1081 + ConsumeAfterOpt) { |
|
1082 for (++i; i < argc; ++i) |
|
1083 PositionalVals.push_back(std::make_pair(argv[i], i)); |
|
1084 break; // Handle outside of the argument processing loop... |
|
1085 @@ -913,6 +962,7 @@ |
|
1086 // option is another positional argument. If so, treat it as an argument, |
|
1087 // otherwise feed it to the eating positional. |
|
1088 ArgName = argv[i] + 1; |
|
1089 + |
|
1090 // Eat leading dashes. |
|
1091 while (!ArgName.empty() && ArgName[0] == '-') |
|
1092 ArgName = ArgName.substr(1); |
|
1093 @@ -924,17 +974,32 @@ |
|
1094 } |
|
1095 |
|
1096 } else { // We start with a '-', must be an argument. |
|
1097 - ArgName = argv[i] + 1; |
|
1098 + // ArgName = i == (argc - 1) ? argv[i] : argv[i] + 1; |
|
1099 + ArgName = argv[i]; |
|
1100 + |
|
1101 // Eat leading dashes. |
|
1102 while (!ArgName.empty() && ArgName[0] == '-') |
|
1103 ArgName = ArgName.substr(1); |
|
1104 |
|
1105 Handler = LookupOption(ArgName, Value, Opts); |
|
1106 - |
|
1107 - // Check to see if this "option" is really a prefixed or grouped argument. |
|
1108 - if (!Handler) |
|
1109 - Handler = |
|
1110 - HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing, Opts); |
|
1111 + if (Handler) { |
|
1112 + enum FormattingFlags FF = Handler->getFormattingFlag(); |
|
1113 + if ((FF == llvm::cl::Prefix) || (FF == llvm::cl::Grouping)) { |
|
1114 + if (Value.empty()) |
|
1115 + Value = argv[++i]; |
|
1116 + |
|
1117 + std::string SA = ArgName.str(); |
|
1118 + std::string SV = Value.str(); |
|
1119 + SA.append(SV); |
|
1120 + |
|
1121 + // Check to see if this "option" is really a prefixed or |
|
1122 + // grouped argument. |
|
1123 + PrefixOrGroupHandler = |
|
1124 + HandlePrefixedOrGroupedOption(SA, SV, ErrorParsing, Opts); |
|
1125 + if (PrefixOrGroupHandler) |
|
1126 + Handler = PrefixOrGroupHandler; |
|
1127 + } |
|
1128 + } |
|
1129 |
|
1130 // Otherwise, look for the closest available option to report to the user |
|
1131 // in the upcoming error. |
|
1132 @@ -945,22 +1010,23 @@ |
|
1133 |
|
1134 if (!Handler) { |
|
1135 if (SinkOpts.empty()) { |
|
1136 - errs() << ProgramName << ": Unknown command line argument '" << argv[i] |
|
1137 - << "'. Try: '" << argv[0] << " -help'\n"; |
|
1138 + errs() << ProgramName.c_str() |
|
1139 + << ": Unknown command line argument '" << argv[i] |
|
1140 + << "'. Try: '" << argv[0] << " -help'\n"; |
|
1141 |
|
1142 if (NearestHandler) { |
|
1143 // If we know a near match, report it as well. |
|
1144 - errs() << ProgramName << ": Did you mean '-" << NearestHandlerString |
|
1145 - << "'?\n"; |
|
1146 + errs() << ProgramName.c_str() |
|
1147 + << ": Did you mean '-" << NearestHandlerString << "'?\n"; |
|
1148 } |
|
1149 |
|
1150 ErrorParsing = true; |
|
1151 } else { |
|
1152 - for (SmallVectorImpl<Option *>::iterator I = SinkOpts.begin(), |
|
1153 - E = SinkOpts.end(); |
|
1154 - I != E; ++I) |
|
1155 + for (std::vector<Option *>::iterator I = SinkOpts.begin(), |
|
1156 + E = SinkOpts.end(); I != E; ++I) |
|
1157 (*I)->addOccurrence(i, "", argv[i]); |
|
1158 } |
|
1159 + |
|
1160 continue; |
|
1161 } |
|
1162 |
|
1163 @@ -974,50 +1040,77 @@ |
|
1164 |
|
1165 // Check and handle positional arguments now... |
|
1166 if (NumPositionalRequired > PositionalVals.size()) { |
|
1167 - errs() << ProgramName |
|
1168 - << ": Not enough positional command line arguments specified!\n" |
|
1169 - << "Must specify at least " << NumPositionalRequired |
|
1170 - << " positional arguments: See: " << argv[0] << " -help\n"; |
|
1171 + errs() << ProgramName.c_str() |
|
1172 + << ": Not enough positional command line arguments specified!\n" |
|
1173 + << "Must specify at least " << NumPositionalRequired |
|
1174 + << " positional arguments: See: " << argv[0] << " -help\n"; |
|
1175 |
|
1176 ErrorParsing = true; |
|
1177 } else if (!HasUnlimitedPositionals && |
|
1178 PositionalVals.size() > PositionalOpts.size()) { |
|
1179 - errs() << ProgramName << ": Too many positional arguments specified!\n" |
|
1180 - << "Can specify at most " << PositionalOpts.size() |
|
1181 - << " positional arguments: See: " << argv[0] << " -help\n"; |
|
1182 + errs() << ProgramName.c_str() |
|
1183 + << ": Too many positional arguments specified!\n" |
|
1184 + << "Can specify at most " << PositionalOpts.size() |
|
1185 + << " positional arguments: See: " << argv[0] << " -help\n"; |
|
1186 ErrorParsing = true; |
|
1187 |
|
1188 } else if (!ConsumeAfterOpt) { |
|
1189 // Positional args have already been handled if ConsumeAfter is specified. |
|
1190 - unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size()); |
|
1191 + unsigned ValNo = 0; |
|
1192 + unsigned NumVals = static_cast<unsigned>(PositionalVals.size()); |
|
1193 for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) { |
|
1194 - if (RequiresValue(PositionalOpts[i])) { |
|
1195 - ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo].first, |
|
1196 + Option *PO = PositionalOpts[i]; |
|
1197 + if (RequiresValue(PO)) { |
|
1198 + ProvidePositionalOption(PO, PositionalVals[ValNo].first, |
|
1199 PositionalVals[ValNo].second); |
|
1200 ValNo++; |
|
1201 --NumPositionalRequired; // We fulfilled our duty... |
|
1202 } |
|
1203 |
|
1204 + enum llvm::cl::ValueExpected VE = PO->getValueExpectedFlag(); |
|
1205 + |
|
1206 + // If it's a positional argument, provide it. |
|
1207 + if ((NumVals - ValNo) > NumPositionalRequired) { |
|
1208 + if (VE == llvm::cl::ValuePositionalNoArgs) { |
|
1209 + ProvidePositionalOption(PO, PositionalVals[ValNo].first, |
|
1210 + PositionalVals[ValNo].second); |
|
1211 + ++ValNo; |
|
1212 + --NumPositionalRequired; |
|
1213 + continue; |
|
1214 + } else if (VE == llvm::cl::ValuePositionalWithArgs) { |
|
1215 + ProvidePositionalOptionWithArgs(PO, PositionalVals[ValNo].first, |
|
1216 + PositionalVals[ValNo].second, |
|
1217 + ValNo, |
|
1218 + NumPositionalRequired); |
|
1219 + continue; |
|
1220 + } |
|
1221 + } |
|
1222 + |
|
1223 // If we _can_ give this option more arguments, do so now, as long as we |
|
1224 // do not give it values that others need. 'Done' controls whether the |
|
1225 // option even _WANTS_ any more. |
|
1226 // |
|
1227 - bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required; |
|
1228 - while (NumVals - ValNo > NumPositionalRequired && !Done) { |
|
1229 - switch (PositionalOpts[i]->getNumOccurrencesFlag()) { |
|
1230 + bool Done = |
|
1231 + ((PO->getNumOccurrencesFlag() == cl::Required) && |
|
1232 + (VE != llvm::cl::ValuePositionalNoArgs)); |
|
1233 + |
|
1234 + while (((NumVals - ValNo) > NumPositionalRequired) && !Done) { |
|
1235 + switch (PO->getNumOccurrencesFlag()) { |
|
1236 case cl::Optional: |
|
1237 Done = true; // Optional arguments want _at most_ one value |
|
1238 // FALL THROUGH |
|
1239 + break; |
|
1240 case cl::ZeroOrMore: // Zero or more will take all they can get... |
|
1241 case cl::OneOrMore: // One or more will take all they can get... |
|
1242 - ProvidePositionalOption(PositionalOpts[i], |
|
1243 - PositionalVals[ValNo].first, |
|
1244 + ProvidePositionalOption(PO, PositionalVals[ValNo].first, |
|
1245 PositionalVals[ValNo].second); |
|
1246 ValNo++; |
|
1247 break; |
|
1248 default: |
|
1249 - llvm_unreachable("Internal error, unexpected NumOccurrences flag in " |
|
1250 - "positional argument processing!"); |
|
1251 + assert(0 && "Internal Compiler Error: " |
|
1252 + "unexpected NumOccurrences flag " |
|
1253 + "in positional argument processing!"); |
|
1254 + break; |
|
1255 } |
|
1256 } |
|
1257 } |
|
1258 @@ -1029,7 +1122,7 @@ |
|
1259 ErrorParsing |= ProvidePositionalOption(PositionalOpts[j], |
|
1260 PositionalVals[ValNo].first, |
|
1261 PositionalVals[ValNo].second); |
|
1262 - ValNo++; |
|
1263 + ++ValNo; |
|
1264 } |
|
1265 |
|
1266 // Handle the case where there is just one positional option, and it's |
|
1267 @@ -1041,7 +1134,7 @@ |
|
1268 ErrorParsing |= ProvidePositionalOption(PositionalOpts[1], |
|
1269 PositionalVals[ValNo].first, |
|
1270 PositionalVals[ValNo].second); |
|
1271 - ValNo++; |
|
1272 + ++ValNo; |
|
1273 } |
|
1274 |
|
1275 // Handle over all of the rest of the arguments to the |
|
1276 @@ -1061,7 +1154,7 @@ |
|
1277 Opt.second->error("must be specified at least once!"); |
|
1278 ErrorParsing = true; |
|
1279 } |
|
1280 - // Fall through |
|
1281 + break; |
|
1282 default: |
|
1283 break; |
|
1284 } |
|
1285 @@ -1095,7 +1188,7 @@ |
|
1286 if (ArgName.empty()) |
|
1287 errs() << HelpStr; // Be nice for positional arguments |
|
1288 else |
|
1289 - errs() << ProgramName << ": for the -" << ArgName; |
|
1290 + errs() << ProgramName.c_str() << ": for the -" << ArgName; |
|
1291 |
|
1292 errs() << " option: " << Message << "\n"; |
|
1293 return true; |
|
1294 @@ -1106,7 +1199,9 @@ |
|
1295 if (!MultiArg) |
|
1296 NumOccurrences++; // Increment the number of times we have been seen |
|
1297 |
|
1298 - switch (getNumOccurrencesFlag()) { |
|
1299 + llvm::cl::NumOccurrencesFlag NOF = getNumOccurrencesFlag(); |
|
1300 + |
|
1301 + switch (NOF) { |
|
1302 case Optional: |
|
1303 if (NumOccurrences > 1) |
|
1304 return error("may only occur zero or one times!", ArgName); |
|
1305 @@ -1121,7 +1216,11 @@ |
|
1306 break; |
|
1307 } |
|
1308 |
|
1309 - return handleOccurrence(pos, ArgName, Value); |
|
1310 + std::string SAN = ArgName; |
|
1311 + std::string SV = Value; |
|
1312 + |
|
1313 + bool R = handleOccurrence(pos, SAN.c_str(), SV.c_str()); |
|
1314 + return R; |
|
1315 } |
|
1316 |
|
1317 // getValueStr - Get the value description string, using "DefaultMsg" if nothing |
|
1318 @@ -1402,11 +1501,12 @@ |
|
1319 PRINT_OPT_DIFF(float) |
|
1320 PRINT_OPT_DIFF(char) |
|
1321 |
|
1322 -void parser<std::string>::printOptionDiff(const Option &O, StringRef V, |
|
1323 +void parser<std::string>::printOptionDiff(const Option &O, |
|
1324 + const std::string &V, |
|
1325 OptionValue<std::string> D, |
|
1326 size_t GlobalWidth) const { |
|
1327 printOptionName(O, GlobalWidth); |
|
1328 - outs() << "= " << V; |
|
1329 + outs() << "= " << V.c_str(); |
|
1330 size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0; |
|
1331 outs().indent(NumSpaces) << " (default: "; |
|
1332 if (D.hasValue()) |
|
1333 @@ -1427,20 +1527,22 @@ |
|
1334 // -help and -help-hidden option implementation |
|
1335 // |
|
1336 |
|
1337 -static int OptNameCompare(const void *LHS, const void *RHS) { |
|
1338 - typedef std::pair<const char *, Option *> pair_ty; |
|
1339 - |
|
1340 - return strcmp(((const pair_ty *)LHS)->first, ((const pair_ty *)RHS)->first); |
|
1341 -} |
|
1342 +template<typename Ty> |
|
1343 +struct OptNameCompare : public std::binary_function<Ty, Ty, bool> { |
|
1344 + inline bool operator()(const Ty& LHS, const Ty& RHS) const { |
|
1345 + return std::strcmp(LHS.first, RHS.first) <= 0; |
|
1346 + } |
|
1347 +}; |
|
1348 |
|
1349 // Copy Options into a vector so we can sort them as we like. |
|
1350 static void sortOpts(StringMap<Option *> &OptMap, |
|
1351 - SmallVectorImpl<std::pair<const char *, Option *>> &Opts, |
|
1352 + std::vector<std::pair<const char*, Option*> > &Opts, |
|
1353 bool ShowHidden) { |
|
1354 SmallPtrSet<Option *, 128> OptionSet; // Duplicate option detection. |
|
1355 |
|
1356 for (StringMap<Option *>::iterator I = OptMap.begin(), E = OptMap.end(); |
|
1357 I != E; ++I) { |
|
1358 + |
|
1359 // Ignore really-hidden options. |
|
1360 if (I->second->getOptionHiddenFlag() == ReallyHidden) |
|
1361 continue; |
|
1362 @@ -1453,12 +1555,13 @@ |
|
1363 if (!OptionSet.insert(I->second).second) |
|
1364 continue; |
|
1365 |
|
1366 - Opts.push_back( |
|
1367 - std::pair<const char *, Option *>(I->getKey().data(), I->second)); |
|
1368 + std::pair<const char*, Option*> KVP(I->getKey().data(), I->second); |
|
1369 + Opts.push_back(KVP); |
|
1370 } |
|
1371 |
|
1372 // Sort the options list alphabetically. |
|
1373 - qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare); |
|
1374 + OptNameCompare<std::pair<const char*, Option*> > ONC; |
|
1375 + std::sort(Opts.begin(), Opts.end(), ONC); |
|
1376 } |
|
1377 |
|
1378 namespace { |
|
1379 @@ -1466,8 +1569,9 @@ |
|
1380 class HelpPrinter { |
|
1381 protected: |
|
1382 const bool ShowHidden; |
|
1383 - typedef SmallVector<std::pair<const char *, Option *>, 128> |
|
1384 + typedef std::vector<std::pair<const char *, Option *> > |
|
1385 StrOptionPairVector; |
|
1386 + |
|
1387 // Print the options. Opts is assumed to be alphabetically sorted. |
|
1388 virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) { |
|
1389 for (size_t i = 0, e = Opts.size(); i != e; ++i) |
|
1390 @@ -1484,8 +1588,8 @@ |
|
1391 return; |
|
1392 |
|
1393 // Get all the options. |
|
1394 - SmallVector<Option *, 4> PositionalOpts; |
|
1395 - SmallVector<Option *, 4> SinkOpts; |
|
1396 + std::vector<Option *> PositionalOpts; |
|
1397 + std::vector<Option *> SinkOpts; |
|
1398 StringMap<Option *> OptMap; |
|
1399 GetOptionInfo(PositionalOpts, SinkOpts, OptMap); |
|
1400 |
|
1401 @@ -1495,7 +1599,7 @@ |
|
1402 if (ProgramOverview) |
|
1403 outs() << "OVERVIEW: " << ProgramOverview << "\n"; |
|
1404 |
|
1405 - outs() << "USAGE: " << ProgramName << " [options]"; |
|
1406 + outs() << "USAGE: " << ProgramName.c_str() << " [options]"; |
|
1407 |
|
1408 // Print out the positional options. |
|
1409 Option *CAOpt = nullptr; // The cl::ConsumeAfter option, if it exists... |
|
1410 @@ -1710,12 +1814,12 @@ |
|
1411 return; |
|
1412 |
|
1413 // Get all the options. |
|
1414 - SmallVector<Option *, 4> PositionalOpts; |
|
1415 - SmallVector<Option *, 4> SinkOpts; |
|
1416 + std::vector<Option *> PositionalOpts; |
|
1417 + std::vector<Option *> SinkOpts; |
|
1418 StringMap<Option *> OptMap; |
|
1419 GetOptionInfo(PositionalOpts, SinkOpts, OptMap); |
|
1420 |
|
1421 - SmallVector<std::pair<const char *, Option *>, 128> Opts; |
|
1422 + std::vector<std::pair<const char *, Option *> > Opts; |
|
1423 sortOpts(OptMap, Opts, /*ShowHidden*/ true); |
|
1424 |
|
1425 // Compute the maximum argument length... |
|
1426 @@ -1825,8 +1929,8 @@ |
|
1427 |
|
1428 void cl::getRegisteredOptions(StringMap<Option *> &Map) { |
|
1429 // Get all the options. |
|
1430 - SmallVector<Option *, 4> PositionalOpts; // NOT USED |
|
1431 - SmallVector<Option *, 4> SinkOpts; // NOT USED |
|
1432 + std::vector<Option *> PositionalOpts; // NOT USED |
|
1433 + std::vector<Option *> SinkOpts; // NOT USED |
|
1434 assert(Map.size() == 0 && "StringMap must be empty"); |
|
1435 GetOptionInfo(PositionalOpts, SinkOpts, Map); |
|
1436 return; |
|
1437 --- lib/Support/PluginLoader.cpp 2012-12-03 08:50:05.000000000 -0800 |
|
1438 +++ lib/Support/PluginLoader.cpp 2016-01-24 11:02:33.000000000 -0800 |
|
1439 @@ -34,6 +34,21 @@ |
|
1440 } |
|
1441 } |
|
1442 |
|
1443 +bool PluginLoader::operator==(const std::string &Filename) const { |
|
1444 + sys::SmartScopedLock<true> Lock(*PluginsLock); |
|
1445 + for (std::vector<std::string>::const_iterator I = Plugins->begin(), |
|
1446 + E = Plugins->end(); I != E; ++I) { |
|
1447 + if (*I == Filename) |
|
1448 + return true; |
|
1449 + } |
|
1450 + |
|
1451 + return false; |
|
1452 +} |
|
1453 + |
|
1454 +bool PluginLoader::operator!=(const std::string &Filename) const { |
|
1455 + return !this->operator==(Filename); |
|
1456 +} |
|
1457 + |
|
1458 unsigned PluginLoader::getNumPlugins() { |
|
1459 sys::SmartScopedLock<true> Lock(*PluginsLock); |
|
1460 return Plugins.isConstructed() ? Plugins->size() : 0; |
|
1461 --- include/llvm/Support/CommandLine.h 2015-01-13 11:14:20.000000000 -0800 |
|
1462 +++ include/llvm/Support/CommandLine.h 2016-01-19 11:56:32.087336770 -0800 |
|
1463 @@ -24,6 +24,7 @@ |
|
1464 #include "llvm/ADT/StringMap.h" |
|
1465 #include "llvm/ADT/Twine.h" |
|
1466 #include "llvm/Support/Compiler.h" |
|
1467 +#include "llvm/Support/raw_ostream.h" |
|
1468 #include <cassert> |
|
1469 #include <climits> |
|
1470 #include <cstdarg> |
|
1471 @@ -97,9 +98,11 @@ |
|
1472 |
|
1473 enum ValueExpected { // Is a value required for the option? |
|
1474 // zero reserved for the unspecified value |
|
1475 - ValueOptional = 0x01, // The value can appear... or not |
|
1476 - ValueRequired = 0x02, // The value is required to appear! |
|
1477 - ValueDisallowed = 0x03 // A value may not be specified (for flags) |
|
1478 + ValueOptional = 0x01, // The value can appear... or not |
|
1479 + ValueRequired = 0x02, // The value is required to appear! |
|
1480 + ValueDisallowed = 0x03, // A value may not be specified (for flags) |
|
1481 + ValuePositionalNoArgs = 0x04, // Positional Argument, no additional args |
|
1482 + ValuePositionalWithArgs = 0x05 // Positional Argument, with additional args |
|
1483 }; |
|
1484 |
|
1485 enum OptionHidden { // Control whether -help shows this option |
|
1486 @@ -137,6 +140,36 @@ |
|
1487 }; |
|
1488 |
|
1489 //===----------------------------------------------------------------------===// |
|
1490 +// Generic Filename Locations |
|
1491 +// |
|
1492 +struct GenericFilenameLocation { |
|
1493 + GenericFilenameLocation() : Value("") { } |
|
1494 + GenericFilenameLocation(const std::string &S) : Value(S) { } |
|
1495 + |
|
1496 + void operator=(const std::string &S) { |
|
1497 + if (!S.empty()) |
|
1498 + Value = S; |
|
1499 + } |
|
1500 + |
|
1501 + std::string Value; |
|
1502 +}; |
|
1503 + |
|
1504 +struct GenericFilenameLocations { |
|
1505 + GenericFilenameLocations() : Value() { } |
|
1506 + GenericFilenameLocations(const std::string &S) |
|
1507 + : Value() { |
|
1508 + Value.push_back(S); |
|
1509 + } |
|
1510 + |
|
1511 + void operator=(const std::string &S) { |
|
1512 + if (!S.empty()) |
|
1513 + Value.push_back(S); |
|
1514 + } |
|
1515 + |
|
1516 + std::vector<std::string> Value; |
|
1517 +}; |
|
1518 + |
|
1519 +//===----------------------------------------------------------------------===// |
|
1520 // Option Category class |
|
1521 // |
|
1522 class OptionCategory { |
|
1523 @@ -162,9 +195,15 @@ |
|
1524 // Option Base class |
|
1525 // |
|
1526 class alias; |
|
1527 + |
|
1528 class Option { |
|
1529 friend class alias; |
|
1530 |
|
1531 +protected: |
|
1532 + /// RegisteredOptionList - This is the list of the command line options |
|
1533 + /// that have statically constructed themselves. |
|
1534 + static Option *RegisteredOptionList; |
|
1535 + |
|
1536 // handleOccurrences - Overriden by subclasses to handle the value passed into |
|
1537 // an argument. Should return true if there was an error processing the |
|
1538 // argument and the program should exit. |
|
1539 @@ -182,13 +221,13 @@ |
|
1540 int NumOccurrences; // The number of times specified |
|
1541 // Occurrences, HiddenFlag, and Formatting are all enum types but to avoid |
|
1542 // problems with signed enums in bitfields. |
|
1543 - unsigned Occurrences : 3; // enum NumOccurrencesFlag |
|
1544 + unsigned Occurrences; // enum NumOccurrencesFlag |
|
1545 // not using the enum type for 'Value' because zero is an implementation |
|
1546 // detail representing the non-value |
|
1547 - unsigned Value : 2; |
|
1548 - unsigned HiddenFlag : 2; // enum OptionHidden |
|
1549 - unsigned Formatting : 2; // enum FormattingFlags |
|
1550 - unsigned Misc : 3; |
|
1551 + unsigned Value; |
|
1552 + unsigned HiddenFlag; // enum OptionHidden |
|
1553 + unsigned Formatting; // enum FormattingFlags |
|
1554 + unsigned Misc; |
|
1555 unsigned Position; // Position of last occurrence of the option |
|
1556 unsigned AdditionalVals; // Greater than 0 for multi-valued option. |
|
1557 Option *NextRegistered; // Singly linked list of registered options. |
|
1558 @@ -200,23 +239,28 @@ |
|
1559 OptionCategory *Category; // The Category this option belongs to |
|
1560 |
|
1561 inline enum NumOccurrencesFlag getNumOccurrencesFlag() const { |
|
1562 - return (enum NumOccurrencesFlag)Occurrences; |
|
1563 + return static_cast<enum NumOccurrencesFlag>(Occurrences); |
|
1564 } |
|
1565 + |
|
1566 inline enum ValueExpected getValueExpectedFlag() const { |
|
1567 - return Value ? ((enum ValueExpected)Value) : getValueExpectedFlagDefault(); |
|
1568 + return Value ? static_cast<enum ValueExpected>(Value) : |
|
1569 + static_cast<enum ValueExpected>(getValueExpectedFlagDefault()); |
|
1570 } |
|
1571 + |
|
1572 inline enum OptionHidden getOptionHiddenFlag() const { |
|
1573 - return (enum OptionHidden)HiddenFlag; |
|
1574 + return static_cast<enum OptionHidden>(HiddenFlag); |
|
1575 } |
|
1576 + |
|
1577 inline enum FormattingFlags getFormattingFlag() const { |
|
1578 - return (enum FormattingFlags)Formatting; |
|
1579 + return static_cast<enum FormattingFlags>(Formatting); |
|
1580 } |
|
1581 + |
|
1582 inline unsigned getMiscFlags() const { return Misc; } |
|
1583 inline unsigned getPosition() const { return Position; } |
|
1584 inline unsigned getNumAdditionalVals() const { return AdditionalVals; } |
|
1585 |
|
1586 // hasArgStr - Return true if the argstr != "" |
|
1587 - bool hasArgStr() const { return ArgStr[0] != 0; } |
|
1588 + bool hasArgStr() const { return ArgStr && *ArgStr != '\0'; } |
|
1589 |
|
1590 //-------------------------------------------------------------------------=== |
|
1591 // Accessor functions set by OptionModifiers |
|
1592 @@ -233,16 +277,78 @@ |
|
1593 void setCategory(OptionCategory &C) { Category = &C; } |
|
1594 |
|
1595 protected: |
|
1596 + Option() : NumOccurrences(0), Occurrences(0), Value(0), HiddenFlag(0), |
|
1597 + Formatting(0), Misc(0), Position(0), AdditionalVals(0), |
|
1598 + NextRegistered(0), ArgStr(""), HelpStr(""), ValueStr(""), |
|
1599 + Category(0) { } |
|
1600 explicit Option(enum NumOccurrencesFlag OccurrencesFlag, |
|
1601 enum OptionHidden Hidden) |
|
1602 - : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), |
|
1603 - HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), Position(0), |
|
1604 - AdditionalVals(0), NextRegistered(nullptr), ArgStr(""), HelpStr(""), |
|
1605 - ValueStr(""), Category(&GeneralCategory) {} |
|
1606 + : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), |
|
1607 + HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), Position(0), |
|
1608 + AdditionalVals(0), NextRegistered(nullptr), ArgStr(""), HelpStr(""), |
|
1609 + ValueStr(""), Category(&GeneralCategory) {} |
|
1610 |
|
1611 inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } |
|
1612 |
|
1613 public: |
|
1614 + Option(const Option &RHS) |
|
1615 + : NumOccurrences(RHS.NumOccurrences), Occurrences(RHS.Occurrences), |
|
1616 + Value(RHS.Value), HiddenFlag(RHS.HiddenFlag), |
|
1617 + Formatting(RHS.Formatting), Misc(RHS.Misc), |
|
1618 + Position(RHS.Position), AdditionalVals(RHS.AdditionalVals), |
|
1619 + NextRegistered(RHS.NextRegistered), ArgStr(RHS.ArgStr), |
|
1620 + HelpStr(RHS.HelpStr), ValueStr(RHS.ValueStr), |
|
1621 + Category(RHS.Category) { } |
|
1622 + |
|
1623 + Option(Option &&RHS) |
|
1624 + : NumOccurrences(RHS.NumOccurrences), Occurrences(RHS.Occurrences), |
|
1625 + Value(RHS.Value), HiddenFlag(RHS.HiddenFlag), |
|
1626 + Formatting(RHS.Formatting), Misc(RHS.Misc), |
|
1627 + Position(RHS.Position), AdditionalVals(RHS.AdditionalVals), |
|
1628 + NextRegistered(RHS.NextRegistered), ArgStr(RHS.ArgStr), |
|
1629 + HelpStr(RHS.HelpStr), ValueStr(RHS.ValueStr), |
|
1630 + Category(RHS.Category) { } |
|
1631 + |
|
1632 + Option &operator=(const Option &RHS) { |
|
1633 + if (this != &RHS) { |
|
1634 + NumOccurrences = RHS.NumOccurrences; |
|
1635 + Occurrences = RHS.Occurrences; |
|
1636 + Value = RHS.Value; |
|
1637 + HiddenFlag = RHS.HiddenFlag; |
|
1638 + Formatting = RHS.Formatting; |
|
1639 + Misc = RHS.Misc; |
|
1640 + Position = RHS.Position; |
|
1641 + AdditionalVals = RHS.AdditionalVals; |
|
1642 + NextRegistered = RHS.NextRegistered; |
|
1643 + ArgStr = RHS.ArgStr; |
|
1644 + HelpStr = RHS.HelpStr; |
|
1645 + ValueStr = RHS.ValueStr; |
|
1646 + Category = RHS.Category; |
|
1647 + } |
|
1648 + |
|
1649 + return *this; |
|
1650 + } |
|
1651 + |
|
1652 + const Option &operator=(Option &&RHS) { |
|
1653 + if (this != &RHS) { |
|
1654 + NumOccurrences = RHS.NumOccurrences; |
|
1655 + Occurrences = RHS.Occurrences; |
|
1656 + Value = RHS.Value; |
|
1657 + HiddenFlag = RHS.HiddenFlag; |
|
1658 + Formatting = RHS.Formatting; |
|
1659 + Misc = RHS.Misc; |
|
1660 + Position = RHS.Position; |
|
1661 + AdditionalVals = RHS.AdditionalVals; |
|
1662 + NextRegistered = RHS.NextRegistered; |
|
1663 + ArgStr = RHS.ArgStr; |
|
1664 + HelpStr = RHS.HelpStr; |
|
1665 + ValueStr = RHS.ValueStr; |
|
1666 + Category = RHS.Category; |
|
1667 + } |
|
1668 + |
|
1669 + return *this; |
|
1670 + } |
|
1671 + |
|
1672 // addArgument - Register this argument with the commandline system. |
|
1673 // |
|
1674 void addArgument(); |
|
1675 @@ -253,8 +359,20 @@ |
|
1676 /// For testing purposes only. |
|
1677 void removeArgument(); |
|
1678 |
|
1679 + static void registerOption(Option *O) { |
|
1680 + assert(O && "Invalid argument!"); |
|
1681 + |
|
1682 + O->NextRegistered = RegisteredOptionList; |
|
1683 + RegisteredOptionList = O; |
|
1684 + MarkOptionsChanged(); |
|
1685 + } |
|
1686 + |
|
1687 Option *getNextRegisteredOption() const { return NextRegistered; } |
|
1688 |
|
1689 + static Option *getRegisteredOptionList() { |
|
1690 + return Option::RegisteredOptionList; |
|
1691 + } |
|
1692 + |
|
1693 // Return the width of the option tag for printing... |
|
1694 virtual size_t getOptionWidth() const = 0; |
|
1695 |
|
1696 @@ -265,7 +383,7 @@ |
|
1697 |
|
1698 virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0; |
|
1699 |
|
1700 - virtual void getExtraOptionNames(SmallVectorImpl<const char *> &) {} |
|
1701 + virtual void getExtraOptionNames(std::vector<const char*> &V) { } |
|
1702 |
|
1703 // addOccurrence - Wrapper around handleOccurrence that enforces Flags. |
|
1704 // |
|
1705 @@ -277,7 +395,7 @@ |
|
1706 |
|
1707 public: |
|
1708 inline int getNumOccurrences() const { return NumOccurrences; } |
|
1709 - virtual ~Option() {} |
|
1710 + virtual ~Option() { } |
|
1711 }; |
|
1712 |
|
1713 //===----------------------------------------------------------------------===// |
|
1714 @@ -304,29 +422,39 @@ |
|
1715 // the default constructor for the argument type does not give you what you |
|
1716 // want. This is only valid on "opt" arguments, not on "list" arguments. |
|
1717 // |
|
1718 -template <class Ty> struct initializer { |
|
1719 +template <typename Ty> struct initializer { |
|
1720 const Ty &Init; |
|
1721 - initializer(const Ty &Val) : Init(Val) {} |
|
1722 |
|
1723 - template <class Opt> void apply(Opt &O) const { O.setInitialValue(Init); } |
|
1724 + initializer(const Ty &Val) : Init(Val) { } |
|
1725 + initializer(const initializer &RHS) : Init(RHS.Init) { } |
|
1726 + initializer(initializer &&RHS) : Init(RHS.Init) { } |
|
1727 + |
|
1728 + template <typename Opt> |
|
1729 + void apply(Opt &O) const { O.setInitialValue(Init); } |
|
1730 }; |
|
1731 |
|
1732 -template <class Ty> initializer<Ty> init(const Ty &Val) { |
|
1733 - return initializer<Ty>(Val); |
|
1734 +template<typename Ty> |
|
1735 +initializer<Ty> init(const Ty &Val) { |
|
1736 + llvm::cl::initializer<Ty> I(Val); |
|
1737 + return I; |
|
1738 } |
|
1739 |
|
1740 // location - Allow the user to specify which external variable they want to |
|
1741 // store the results of the command line argument processing into, if they don't |
|
1742 // want to store it in the option itself. |
|
1743 // |
|
1744 -template <class Ty> struct LocationClass { |
|
1745 +template <typename Ty> struct LocationClass { |
|
1746 Ty &Loc; |
|
1747 - LocationClass(Ty &L) : Loc(L) {} |
|
1748 |
|
1749 - template <class Opt> void apply(Opt &O) const { O.setLocation(O, Loc); } |
|
1750 + LocationClass(Ty &L) : Loc(L) { } |
|
1751 + LocationClass(const LocationClass &RHS) : Loc(RHS.Loc) { } |
|
1752 + LocationClass(LocationClass &&RHS) : Loc(RHS.Loc) { } |
|
1753 + |
|
1754 + template<typename Opt> |
|
1755 + void apply(Opt &O) const { O.setLocation(O, Loc); } |
|
1756 }; |
|
1757 |
|
1758 -template <class Ty> LocationClass<Ty> location(Ty &L) { |
|
1759 +template <typename Ty> LocationClass<Ty> location(Ty &L) { |
|
1760 return LocationClass<Ty>(L); |
|
1761 } |
|
1762 |
|
1763 @@ -334,17 +462,22 @@ |
|
1764 // to. |
|
1765 struct cat { |
|
1766 OptionCategory &Category; |
|
1767 - cat(OptionCategory &c) : Category(c) {} |
|
1768 |
|
1769 - template <class Opt> void apply(Opt &O) const { O.setCategory(Category); } |
|
1770 + cat(OptionCategory &c) : Category(c) { } |
|
1771 + cat(const cat &RHS) : Category(RHS.Category) { } |
|
1772 + virtual ~cat() { } |
|
1773 + |
|
1774 + template <typename Opt> |
|
1775 + void apply(Opt &O) const { O.setCategory(Category); } |
|
1776 }; |
|
1777 |
|
1778 //===----------------------------------------------------------------------===// |
|
1779 // OptionValue class |
|
1780 |
|
1781 // Support value comparison outside the template. |
|
1782 -struct GenericOptionValue { |
|
1783 - virtual ~GenericOptionValue() {} |
|
1784 +class GenericOptionValue { |
|
1785 +public: |
|
1786 + virtual ~GenericOptionValue() { } |
|
1787 virtual bool compare(const GenericOptionValue &V) const = 0; |
|
1788 |
|
1789 private: |
|
1790 @@ -458,57 +591,6 @@ |
|
1791 }; |
|
1792 |
|
1793 //===----------------------------------------------------------------------===// |
|
1794 -// Enum valued command line option |
|
1795 -// |
|
1796 -#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC |
|
1797 -#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC |
|
1798 -#define clEnumValEnd (reinterpret_cast<void *>(0)) |
|
1799 - |
|
1800 -// values - For custom data types, allow specifying a group of values together |
|
1801 -// as the values that go into the mapping that the option handler uses. Note |
|
1802 -// that the values list must always have a 0 at the end of the list to indicate |
|
1803 -// that the list has ended. |
|
1804 -// |
|
1805 -template <class DataType> class ValuesClass { |
|
1806 - // Use a vector instead of a map, because the lists should be short, |
|
1807 - // the overhead is less, and most importantly, it keeps them in the order |
|
1808 - // inserted so we can print our option out nicely. |
|
1809 - SmallVector<std::pair<const char *, std::pair<int, const char *>>, 4> Values; |
|
1810 - void processValues(va_list Vals); |
|
1811 - |
|
1812 -public: |
|
1813 - ValuesClass(const char *EnumName, DataType Val, const char *Desc, |
|
1814 - va_list ValueArgs) { |
|
1815 - // Insert the first value, which is required. |
|
1816 - Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc))); |
|
1817 - |
|
1818 - // Process the varargs portion of the values... |
|
1819 - while (const char *enumName = va_arg(ValueArgs, const char *)) { |
|
1820 - DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int)); |
|
1821 - const char *EnumDesc = va_arg(ValueArgs, const char *); |
|
1822 - Values.push_back(std::make_pair(enumName, // Add value to value map |
|
1823 - std::make_pair(EnumVal, EnumDesc))); |
|
1824 - } |
|
1825 - } |
|
1826 - |
|
1827 - template <class Opt> void apply(Opt &O) const { |
|
1828 - for (size_t i = 0, e = Values.size(); i != e; ++i) |
|
1829 - O.getParser().addLiteralOption(Values[i].first, Values[i].second.first, |
|
1830 - Values[i].second.second); |
|
1831 - } |
|
1832 -}; |
|
1833 - |
|
1834 -template <class DataType> |
|
1835 -ValuesClass<DataType> LLVM_END_WITH_NULL |
|
1836 -values(const char *Arg, DataType Val, const char *Desc, ...) { |
|
1837 - va_list ValueArgs; |
|
1838 - va_start(ValueArgs, Desc); |
|
1839 - ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs); |
|
1840 - va_end(ValueArgs); |
|
1841 - return Vals; |
|
1842 -} |
|
1843 - |
|
1844 -//===----------------------------------------------------------------------===// |
|
1845 // parser class - Parameterizable parser for different data types. By default, |
|
1846 // known data types (string, int, bool) have specialized parsers, that do what |
|
1847 // you would expect. The default parser, used for data types that are not |
|
1848 @@ -519,18 +601,23 @@ |
|
1849 // generic_parser_base - This class holds all the non-generic code that we do |
|
1850 // not need replicated for every instance of the generic parser. This also |
|
1851 // allows us to put stuff into CommandLine.cpp |
|
1852 +// Moved here for an obvious reason. |
|
1853 // |
|
1854 class generic_parser_base { |
|
1855 protected: |
|
1856 class GenericOptionInfo { |
|
1857 public: |
|
1858 GenericOptionInfo(const char *name, const char *helpStr) |
|
1859 - : Name(name), HelpStr(helpStr) {} |
|
1860 + : Name(name), HelpStr(helpStr) {} |
|
1861 + virtual ~GenericOptionInfo() { } |
|
1862 + |
|
1863 const char *Name; |
|
1864 const char *HelpStr; |
|
1865 }; |
|
1866 |
|
1867 public: |
|
1868 + generic_parser_base() : hasArgStr(false) { } |
|
1869 + |
|
1870 virtual ~generic_parser_base() {} // Base class should have virtual-dtor |
|
1871 |
|
1872 // getNumOptions - Virtual function implemented by generic subclass to |
|
1873 @@ -576,7 +663,7 @@ |
|
1874 hasArgStr = O.hasArgStr(); |
|
1875 } |
|
1876 |
|
1877 - void getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) { |
|
1878 + void getExtraOptionNames(std::vector<const char *> &OptionNames) { |
|
1879 // If there has been no argstr specified, that means that we need to add an |
|
1880 // argument for every possible option. This ensures that our options are |
|
1881 // vectored to us. |
|
1882 @@ -612,34 +699,48 @@ |
|
1883 bool hasArgStr; |
|
1884 }; |
|
1885 |
|
1886 + |
|
1887 // Default parser implementation - This implementation depends on having a |
|
1888 // mapping of recognized options to values of some sort. In addition to this, |
|
1889 // each entry in the mapping also tracks a help message that is printed with the |
|
1890 // command line option for -help. Because this is a simple mapping parser, the |
|
1891 // data type can be any unsupported type. |
|
1892 // |
|
1893 -template <class DataType> class parser : public generic_parser_base { |
|
1894 +template <typename DataType> |
|
1895 +class parser : public generic_parser_base { |
|
1896 protected: |
|
1897 class OptionInfo : public GenericOptionInfo { |
|
1898 public: |
|
1899 - OptionInfo(const char *name, DataType v, const char *helpStr) |
|
1900 - : GenericOptionInfo(name, helpStr), V(v) {} |
|
1901 + OptionInfo(const char *Name, DataType DT, const char *helpStr) |
|
1902 + : GenericOptionInfo(Name, helpStr), V(DT) {} |
|
1903 + ~OptionInfo() { } |
|
1904 + |
|
1905 OptionValue<DataType> V; |
|
1906 }; |
|
1907 - SmallVector<OptionInfo, 8> Values; |
|
1908 + |
|
1909 + std::vector<OptionInfo> Values; |
|
1910 |
|
1911 public: |
|
1912 typedef DataType parser_data_type; |
|
1913 |
|
1914 + parser<DataType>() : generic_parser_base(), Values() { } |
|
1915 + virtual ~parser<DataType>() { } |
|
1916 + |
|
1917 // Implement virtual functions needed by generic_parser_base |
|
1918 - unsigned getNumOptions() const override { return unsigned(Values.size()); } |
|
1919 - const char *getOption(unsigned N) const override { return Values[N].Name; } |
|
1920 - const char *getDescription(unsigned N) const override { |
|
1921 + virtual unsigned getNumOptions() const override { |
|
1922 + return static_cast<unsigned>(Values.size()); |
|
1923 + } |
|
1924 + |
|
1925 + virtual const char *getOption(unsigned N) const override { |
|
1926 + return Values[N].Name; |
|
1927 + } |
|
1928 + |
|
1929 + virtual const char *getDescription(unsigned N) const override { |
|
1930 return Values[N].HelpStr; |
|
1931 } |
|
1932 |
|
1933 // getOptionValue - Return the value of option name N. |
|
1934 - const GenericOptionValue &getOptionValue(unsigned N) const override { |
|
1935 + virtual const GenericOptionValue &getOptionValue(unsigned N) const override { |
|
1936 return Values[N].V; |
|
1937 } |
|
1938 |
|
1939 @@ -662,7 +763,7 @@ |
|
1940 |
|
1941 /// addLiteralOption - Add an entry to the mapping table. |
|
1942 /// |
|
1943 - template <class DT> |
|
1944 + template<typename DT> |
|
1945 void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) { |
|
1946 assert(findOption(Name) == Values.size() && "Option already exists!"); |
|
1947 OptionInfo X(Name, static_cast<DataType>(V), HelpStr); |
|
1948 @@ -670,6 +771,14 @@ |
|
1949 MarkOptionsChanged(); |
|
1950 } |
|
1951 |
|
1952 + void addLiteralOption(const char *Name, const DataType &V, |
|
1953 + const char *HelpStr) { |
|
1954 + assert(findOption(Name) == Values.size() && "Option already exists!"); |
|
1955 + OptionInfo X(Name, V, HelpStr); |
|
1956 + Values.push_back(X); |
|
1957 + MarkOptionsChanged(); |
|
1958 + } |
|
1959 + |
|
1960 /// removeLiteralOption - Remove the specified option. |
|
1961 /// |
|
1962 void removeLiteralOption(const char *Name) { |
|
1963 @@ -679,18 +788,95 @@ |
|
1964 } |
|
1965 }; |
|
1966 |
|
1967 +//===----------------------------------------------------------------------===// |
|
1968 +// Enum valued command line option |
|
1969 +// |
|
1970 +#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC |
|
1971 +#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC |
|
1972 +#define clEnumValEnd (reinterpret_cast<void *>(0)) |
|
1973 + |
|
1974 +// values - For custom data types, allow specifying a group of values together |
|
1975 +// as the values that go into the mapping that the option handler uses. Note |
|
1976 +// that the values list must always have a 0 at the end of the list to indicate |
|
1977 +// that the list has ended. |
|
1978 +// |
|
1979 +template <typename DataType> |
|
1980 +class ValuesClass { |
|
1981 + // Use a vector instead of a map, because the lists should be short, |
|
1982 + // the overhead is less, and most importantly, it keeps them in the order |
|
1983 + // inserted so we can print our option out nicely. |
|
1984 + std::vector<std::pair<const char*, std::pair<int, const char*> > > Values; |
|
1985 + void processValues(va_list Vals); |
|
1986 + |
|
1987 +public: |
|
1988 + ValuesClass(const char *EnumName, DataType Val, const char *Desc, |
|
1989 + va_list ValueArgs) : Values() { |
|
1990 + // Insert the first value, which is required. |
|
1991 + Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc))); |
|
1992 + |
|
1993 + // Process the varargs portion of the values... |
|
1994 + while (const char *enumName = va_arg(ValueArgs, const char *)) { |
|
1995 + DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int)); |
|
1996 + const char *EnumDesc = va_arg(ValueArgs, const char *); |
|
1997 + |
|
1998 + Values.push_back(std::make_pair(enumName, // Add value to value map |
|
1999 + std::make_pair(EnumVal, EnumDesc))); |
|
2000 + } |
|
2001 + } |
|
2002 + |
|
2003 + ValuesClass(const ValuesClass &RHS) |
|
2004 + : Values(RHS.Values) { } |
|
2005 + |
|
2006 + ValuesClass(ValuesClass &&RHS) |
|
2007 + : Values(RHS.Values) { } |
|
2008 + |
|
2009 + ValuesClass &operator=(const ValuesClass &RHS) { |
|
2010 + if (this != &RHS) |
|
2011 + Values.operator=(RHS.Values); |
|
2012 + |
|
2013 + return *this; |
|
2014 + } |
|
2015 + |
|
2016 + ValuesClass &operator=(ValuesClass &&RHS) { |
|
2017 + if (this != &RHS) |
|
2018 + Values.operator=(RHS.Values); |
|
2019 + |
|
2020 + return *this; |
|
2021 + } |
|
2022 + |
|
2023 + ~ValuesClass() { } |
|
2024 + |
|
2025 + template <typename Opt> void apply(Opt &O) const { |
|
2026 + for (size_t i = 0, e = Values.size(); i != e; ++i) { |
|
2027 + O.getParser().addLiteralOption(Values[i].first, Values[i].second.first, |
|
2028 + Values[i].second.second); |
|
2029 + } |
|
2030 + } |
|
2031 +}; |
|
2032 + |
|
2033 +template <class DataType> |
|
2034 +ValuesClass<DataType> LLVM_END_WITH_NULL |
|
2035 +values(const char *Arg, DataType Val, const char *Desc, ...) { |
|
2036 + va_list ValueArgs; |
|
2037 + va_start(ValueArgs, Desc); |
|
2038 + ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs); |
|
2039 + va_end(ValueArgs); |
|
2040 + return Vals; |
|
2041 +} |
|
2042 + |
|
2043 //-------------------------------------------------- |
|
2044 // basic_parser - Super class of parsers to provide boilerplate code |
|
2045 // |
|
2046 class basic_parser_impl { // non-template implementation of basic_parser<t> |
|
2047 public: |
|
2048 + basic_parser_impl() { } |
|
2049 virtual ~basic_parser_impl() {} |
|
2050 |
|
2051 enum ValueExpected getValueExpectedFlagDefault() const { |
|
2052 return ValueRequired; |
|
2053 } |
|
2054 |
|
2055 - void getExtraOptionNames(SmallVectorImpl<const char *> &) {} |
|
2056 + void getExtraOptionNames(std::vector<const char *> &V) { } |
|
2057 |
|
2058 void initialize(Option &) {} |
|
2059 |
|
2060 @@ -720,10 +906,46 @@ |
|
2061 // basic_parser - The real basic parser is just a template wrapper that provides |
|
2062 // a typedef for the provided data type. |
|
2063 // |
|
2064 -template <class DataType> class basic_parser : public basic_parser_impl { |
|
2065 +template <typename DataType> |
|
2066 +class basic_parser : public basic_parser_impl { |
|
2067 public: |
|
2068 + basic_parser<DataType>() : basic_parser_impl(), Values() { } |
|
2069 + ~basic_parser<DataType>() { } |
|
2070 + |
|
2071 + unsigned getNumOptions() const { |
|
2072 + return static_cast<unsigned>(Values.size()); |
|
2073 + } |
|
2074 + |
|
2075 + const char *getOption(unsigned I) { |
|
2076 + assert(I < static_cast<unsigned>(Values.size()) && |
|
2077 + "Index is out-of-range!"); |
|
2078 + return Values[I].Name; |
|
2079 + } |
|
2080 + |
|
2081 + const char *getDescription(unsigned I) { |
|
2082 + assert(I < static_cast<unsigned>(Values.size()) && |
|
2083 + "Index is out-of-range!"); |
|
2084 + return Values[I].Help; |
|
2085 + } |
|
2086 + |
|
2087 typedef DataType parser_data_type; |
|
2088 typedef OptionValue<DataType> OptVal; |
|
2089 + |
|
2090 +protected: |
|
2091 + template<typename SameDataType> |
|
2092 + class OptionInfo { |
|
2093 + public: |
|
2094 + OptionInfo(const char *NameStr, SameDataType DT, const char *HelpStr) |
|
2095 + : Name(NameStr), Help(HelpStr), V(DT) { } |
|
2096 + |
|
2097 + ~OptionInfo() { } |
|
2098 + |
|
2099 + const char *Name; |
|
2100 + const char *Help; |
|
2101 + OptionValue<SameDataType> V; |
|
2102 + }; |
|
2103 + |
|
2104 + std::vector<OptionInfo<DataType> > Values; |
|
2105 }; |
|
2106 |
|
2107 //-------------------------------------------------- |
|
2108 @@ -733,6 +955,9 @@ |
|
2109 const char *ArgStr; |
|
2110 |
|
2111 public: |
|
2112 + parser<bool>() : basic_parser<bool>() { } |
|
2113 + virtual ~parser<bool>() { } |
|
2114 + |
|
2115 // parse - Return true on error. |
|
2116 bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val); |
|
2117 |
|
2118 @@ -745,11 +970,17 @@ |
|
2119 // getValueName - Do not print =<value> at all. |
|
2120 const char *getValueName() const override { return nullptr; } |
|
2121 |
|
2122 + void addLiteralOption(const char *Name, bool V, const char *HelpStr) { |
|
2123 + OptionInfo<bool> OI(Name, V, HelpStr); |
|
2124 + Values.push_back(OI); |
|
2125 + MarkOptionsChanged(); |
|
2126 + } |
|
2127 + |
|
2128 void printOptionDiff(const Option &O, bool V, OptVal Default, |
|
2129 size_t GlobalWidth) const; |
|
2130 |
|
2131 // An out-of-line virtual method to provide a 'home' for this class. |
|
2132 - void anchor() override; |
|
2133 + virtual void anchor() override; |
|
2134 }; |
|
2135 |
|
2136 EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>); |
|
2137 @@ -758,6 +989,9 @@ |
|
2138 // parser<boolOrDefault> |
|
2139 template <> class parser<boolOrDefault> : public basic_parser<boolOrDefault> { |
|
2140 public: |
|
2141 + parser<boolOrDefault>() : basic_parser<boolOrDefault>() { } |
|
2142 + virtual ~parser<boolOrDefault>() { } |
|
2143 + |
|
2144 // parse - Return true on error. |
|
2145 bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val); |
|
2146 |
|
2147 @@ -772,7 +1006,7 @@ |
|
2148 size_t GlobalWidth) const; |
|
2149 |
|
2150 // An out-of-line virtual method to provide a 'home' for this class. |
|
2151 - void anchor() override; |
|
2152 + virtual void anchor() override; |
|
2153 }; |
|
2154 |
|
2155 EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>); |
|
2156 @@ -782,12 +1016,21 @@ |
|
2157 // |
|
2158 template <> class parser<int> : public basic_parser<int> { |
|
2159 public: |
|
2160 + parser<int>() : basic_parser<int>() { } |
|
2161 + virtual ~parser<int>() { } |
|
2162 + |
|
2163 // parse - Return true on error. |
|
2164 bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val); |
|
2165 |
|
2166 // getValueName - Overload in subclass to provide a better default value. |
|
2167 const char *getValueName() const override { return "int"; } |
|
2168 |
|
2169 + void addLiteralOption(const char *Name, int V, const char *HelpStr) { |
|
2170 + OptionInfo<int> OI(Name, V, HelpStr); |
|
2171 + Values.push_back(OI); |
|
2172 + MarkOptionsChanged(); |
|
2173 + } |
|
2174 + |
|
2175 void printOptionDiff(const Option &O, int V, OptVal Default, |
|
2176 size_t GlobalWidth) const; |
|
2177 |
|
2178 @@ -802,12 +1045,21 @@ |
|
2179 // |
|
2180 template <> class parser<unsigned> : public basic_parser<unsigned> { |
|
2181 public: |
|
2182 + parser<unsigned>() : basic_parser<unsigned>() { } |
|
2183 + virtual ~parser<unsigned>() { } |
|
2184 + |
|
2185 // parse - Return true on error. |
|
2186 bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val); |
|
2187 |
|
2188 // getValueName - Overload in subclass to provide a better default value. |
|
2189 const char *getValueName() const override { return "uint"; } |
|
2190 |
|
2191 + void addLiteralOption(const char *Name, unsigned V, const char *HelpStr) { |
|
2192 + OptionInfo<unsigned> OI(Name, V, HelpStr); |
|
2193 + Values.push_back(OI); |
|
2194 + MarkOptionsChanged(); |
|
2195 + } |
|
2196 + |
|
2197 void printOptionDiff(const Option &O, unsigned V, OptVal Default, |
|
2198 size_t GlobalWidth) const; |
|
2199 |
|
2200 @@ -823,6 +1075,9 @@ |
|
2201 template <> |
|
2202 class parser<unsigned long long> : public basic_parser<unsigned long long> { |
|
2203 public: |
|
2204 + parser<unsigned long long>() : basic_parser<unsigned long long>() { } |
|
2205 + virtual ~parser<unsigned long long>() { } |
|
2206 + |
|
2207 // parse - Return true on error. |
|
2208 bool parse(Option &O, StringRef ArgName, StringRef Arg, |
|
2209 unsigned long long &Val); |
|
2210 @@ -844,6 +1099,9 @@ |
|
2211 // |
|
2212 template <> class parser<double> : public basic_parser<double> { |
|
2213 public: |
|
2214 + parser<double>() : basic_parser<double>() { } |
|
2215 + virtual ~parser<double>() { } |
|
2216 + |
|
2217 // parse - Return true on error. |
|
2218 bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val); |
|
2219 |
|
2220 @@ -864,6 +1122,9 @@ |
|
2221 // |
|
2222 template <> class parser<float> : public basic_parser<float> { |
|
2223 public: |
|
2224 + parser<float>() : basic_parser<float>() { } |
|
2225 + virtual ~parser<float>() { } |
|
2226 + |
|
2227 // parse - Return true on error. |
|
2228 bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val); |
|
2229 |
|
2230 @@ -884,6 +1145,9 @@ |
|
2231 // |
|
2232 template <> class parser<std::string> : public basic_parser<std::string> { |
|
2233 public: |
|
2234 + parser<std::string>() : basic_parser<std::string>() { } |
|
2235 + virtual ~parser<std::string>() { } |
|
2236 + |
|
2237 // parse - Return true on error. |
|
2238 bool parse(Option &, StringRef, StringRef Arg, std::string &Value) { |
|
2239 Value = Arg.str(); |
|
2240 @@ -893,7 +1157,13 @@ |
|
2241 // getValueName - Overload in subclass to provide a better default value. |
|
2242 const char *getValueName() const override { return "string"; } |
|
2243 |
|
2244 - void printOptionDiff(const Option &O, StringRef V, OptVal Default, |
|
2245 + void addLiteralOption(const char *Name, int V, const char *HelpStr) { |
|
2246 + OptionInfo<std::string> OI(Name, std::to_string(V), HelpStr); |
|
2247 + Values.push_back(OI); |
|
2248 + MarkOptionsChanged(); |
|
2249 + } |
|
2250 + |
|
2251 + void printOptionDiff(const Option &O, const std::string &V, OptVal Default, |
|
2252 size_t GlobalWidth) const; |
|
2253 |
|
2254 // An out-of-line virtual method to provide a 'home' for this class. |
|
2255 @@ -907,6 +1177,9 @@ |
|
2256 // |
|
2257 template <> class parser<char> : public basic_parser<char> { |
|
2258 public: |
|
2259 + parser<char>() : basic_parser<char>() { } |
|
2260 + virtual ~parser<char>() { } |
|
2261 + |
|
2262 // parse - Return true on error. |
|
2263 bool parse(Option &, StringRef, StringRef Arg, char &Value) { |
|
2264 Value = Arg[0]; |
|
2265 @@ -916,6 +1189,12 @@ |
|
2266 // getValueName - Overload in subclass to provide a better default value. |
|
2267 const char *getValueName() const override { return "char"; } |
|
2268 |
|
2269 + void addLiteralOption(const char *Name, char V, const char *HelpStr) { |
|
2270 + OptionInfo<char> OI(Name, V, HelpStr); |
|
2271 + Values.push_back(OI); |
|
2272 + MarkOptionsChanged(); |
|
2273 + } |
|
2274 + |
|
2275 void printOptionDiff(const Option &O, char V, OptVal Default, |
|
2276 size_t GlobalWidth) const; |
|
2277 |
|
2278 @@ -976,8 +1255,9 @@ |
|
2279 // not correctly respond to the apply method). Because the syntax to use this |
|
2280 // is a pain, we have the 'apply' method below to handle the nastiness... |
|
2281 // |
|
2282 -template <class Mod> struct applicator { |
|
2283 - template <class Opt> static void opt(const Mod &M, Opt &O) { M.apply(O); } |
|
2284 +template <typename Mod> struct applicator { |
|
2285 + template <typename Opt> |
|
2286 + static void opt(const Mod &M, Opt &O) { M.apply(O); } |
|
2287 }; |
|
2288 |
|
2289 // Handle const char* as a special case... |
|
2290 @@ -1039,11 +1319,16 @@ |
|
2291 } |
|
2292 |
|
2293 public: |
|
2294 - opt_storage() : Location(nullptr) {} |
|
2295 + opt_storage() : Location(nullptr), Default() { } |
|
2296 + opt_storage(const opt_storage &RHS) |
|
2297 + : Location(RHS.Location), Default(RHS.Default) { } |
|
2298 + opt_storage(opt_storage &&RHS) |
|
2299 + : Location(RHS.Location), Default(RHS.Default) { } |
|
2300 |
|
2301 bool setLocation(Option &O, DataType &L) { |
|
2302 if (Location) |
|
2303 return O.error("cl::location(x) specified more than once!"); |
|
2304 + |
|
2305 Location = &L; |
|
2306 Default = L; |
|
2307 return false; |
|
2308 @@ -1077,8 +1362,47 @@ |
|
2309 template <class DataType> |
|
2310 class opt_storage<DataType, false, true> : public DataType { |
|
2311 public: |
|
2312 + opt_storage() : DataType(), Location(nullptr), Default() { } |
|
2313 + opt_storage(const opt_storage &RHS) |
|
2314 + : DataType(RHS), Location(RHS.Location), Default(RHS.Default) { } |
|
2315 + opt_storage(opt_storage &&RHS) |
|
2316 + : DataType(RHS), Location(RHS.Location), Default(RHS.Default) { } |
|
2317 + |
|
2318 + opt_storage<DataType, false, true> |
|
2319 + &operator=(const opt_storage<DataType, false, true> &RHS) { |
|
2320 + if (this != &RHS) { |
|
2321 + DataType::operator=(RHS); |
|
2322 + Location = RHS.Location; |
|
2323 + Default = RHS.Default; |
|
2324 + } |
|
2325 + |
|
2326 + return *this; |
|
2327 + } |
|
2328 + |
|
2329 + opt_storage<DataType, false, true> |
|
2330 + &operator=(opt_storage<DataType, false, true> &&RHS) { |
|
2331 + if (this != &RHS) { |
|
2332 + DataType::operator=(RHS); |
|
2333 + Location = RHS.Location; |
|
2334 + Default = RHS.Default; |
|
2335 + } |
|
2336 + |
|
2337 + return *this; |
|
2338 + } |
|
2339 + |
|
2340 + |
|
2341 + DataType *Location; |
|
2342 OptionValue<DataType> Default; |
|
2343 |
|
2344 + bool setLocation(Option &O, DataType &L) { |
|
2345 + if (Location) |
|
2346 + return O.error("cl::location(x) specified more than once!"); |
|
2347 + |
|
2348 + Location = &L; |
|
2349 + Default = L; |
|
2350 + return false; |
|
2351 + } |
|
2352 + |
|
2353 template <class T> void setValue(const T &V, bool initial = false) { |
|
2354 DataType::operator=(V); |
|
2355 if (initial) |
|
2356 @@ -1102,13 +1426,45 @@ |
|
2357 |
|
2358 // Make sure we initialize the value with the default constructor for the |
|
2359 // type. |
|
2360 - opt_storage() : Value(DataType()), Default(DataType()) {} |
|
2361 + opt_storage() : Value(DataType()), Default(DataType()) { } |
|
2362 + opt_storage(const opt_storage &RHS) |
|
2363 + : Value(RHS.Value), Default(RHS.Default) { } |
|
2364 + opt_storage(opt_storage &&RHS) |
|
2365 + : Value(RHS.Location), Default(RHS.Default) { } |
|
2366 + |
|
2367 + opt_storage<DataType, false, false> |
|
2368 + &operator=(const opt_storage<DataType, false, false> &RHS) { |
|
2369 + if (this != &RHS) { |
|
2370 + Value = RHS.Value; |
|
2371 + Default = RHS.Default; |
|
2372 + } |
|
2373 + |
|
2374 + return *this; |
|
2375 + } |
|
2376 + |
|
2377 + opt_storage<DataType, false, false> |
|
2378 + &operator=(opt_storage<DataType, false, false> &&RHS) { |
|
2379 + if (this != &RHS) { |
|
2380 + Value = RHS.Value; |
|
2381 + Default = RHS.Default; |
|
2382 + } |
|
2383 + |
|
2384 + return *this; |
|
2385 + } |
|
2386 + |
|
2387 + |
|
2388 + bool setLocation(Option &O, DataType &L) { |
|
2389 + Value = L; |
|
2390 + Default = Value; |
|
2391 + return false; |
|
2392 + } |
|
2393 |
|
2394 template <class T> void setValue(const T &V, bool initial = false) { |
|
2395 Value = V; |
|
2396 if (initial) |
|
2397 Default = V; |
|
2398 } |
|
2399 + |
|
2400 DataType &getValue() { return Value; } |
|
2401 DataType getValue() const { return Value; } |
|
2402 |
|
2403 @@ -1123,19 +1479,21 @@ |
|
2404 //===----------------------------------------------------------------------===// |
|
2405 // opt - A scalar command line option. |
|
2406 // |
|
2407 -template <class DataType, bool ExternalStorage = false, |
|
2408 - class ParserClass = parser<DataType>> |
|
2409 +template <typename DataType, bool ExternalStorage = false, |
|
2410 + typename ParserClass = parser<DataType> > |
|
2411 class opt : public Option, |
|
2412 public opt_storage<DataType, ExternalStorage, |
|
2413 std::is_class<DataType>::value> { |
|
2414 ParserClass Parser; |
|
2415 |
|
2416 - bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2417 - StringRef Arg) override { |
|
2418 +protected: |
|
2419 + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2420 + StringRef Arg) override { |
|
2421 typename ParserClass::parser_data_type Val = |
|
2422 typename ParserClass::parser_data_type(); |
|
2423 if (Parser.parse(*this, ArgName, Arg, Val)) |
|
2424 return true; // Parse error! |
|
2425 + |
|
2426 this->setValue(Val); |
|
2427 this->setPosition(pos); |
|
2428 return false; |
|
2429 @@ -1145,7 +1503,7 @@ |
|
2430 return Parser.getValueExpectedFlagDefault(); |
|
2431 } |
|
2432 void |
|
2433 - getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { |
|
2434 + getExtraOptionNames(std::vector<const char *> &OptionNames) override { |
|
2435 return Parser.getExtraOptionNames(OptionNames); |
|
2436 } |
|
2437 |
|
2438 @@ -1170,11 +1528,33 @@ |
|
2439 } |
|
2440 |
|
2441 public: |
|
2442 + opt() : Option(), opt_storage<DataType, ExternalStorage, |
|
2443 + std::is_class<DataType>::value>(), |
|
2444 + Parser() { } |
|
2445 + |
|
2446 + opt(const opt &RHS) : Option(RHS), |
|
2447 + opt_storage<DataType, ExternalStorage, |
|
2448 + std::is_class<DataType>::value>(RHS), |
|
2449 + Parser(RHS.Parser) { } |
|
2450 + |
|
2451 + ~opt() { } |
|
2452 + |
|
2453 // setInitialValue - Used by the cl::init modifier... |
|
2454 void setInitialValue(const DataType &V) { this->setValue(V, true); } |
|
2455 |
|
2456 ParserClass &getParser() { return Parser; } |
|
2457 |
|
2458 + bool setLocation(Option &O, DataType &L) { |
|
2459 + bool R = opt_storage<DataType, ExternalStorage, |
|
2460 + std::is_class<DataType>::value>::setLocation(O, L); |
|
2461 + return R; |
|
2462 + } |
|
2463 + |
|
2464 + void addArgument() { |
|
2465 + assert(!NextRegistered && "argument multiply registered!"); |
|
2466 + Option::registerOption(this); |
|
2467 + } |
|
2468 + |
|
2469 template <class T> DataType &operator=(const T &Val) { |
|
2470 this->setValue(Val); |
|
2471 return this->getValue(); |
|
2472 @@ -1271,6 +1651,23 @@ |
|
2473 apply(M7, this); |
|
2474 done(); |
|
2475 } |
|
2476 + // Nine options... |
|
2477 + template <class M0t, class M1t, class M2t, class M3t, class M4t, class M5t, |
|
2478 + class M6t, class M7t, class M8t> |
|
2479 + opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, const M4t &M4, |
|
2480 + const M5t &M5, const M6t &M6, const M7t &M7, const M8t &M8) |
|
2481 + : Option(Optional, NotHidden) { |
|
2482 + apply(M0, this); |
|
2483 + apply(M1, this); |
|
2484 + apply(M2, this); |
|
2485 + apply(M3, this); |
|
2486 + apply(M4, this); |
|
2487 + apply(M5, this); |
|
2488 + apply(M6, this); |
|
2489 + apply(M7, this); |
|
2490 + apply(M8, this); |
|
2491 + done(); |
|
2492 + } |
|
2493 }; |
|
2494 |
|
2495 EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>); |
|
2496 @@ -1291,10 +1688,12 @@ |
|
2497 |
|
2498 public: |
|
2499 list_storage() : Location(0) {} |
|
2500 + virtual ~list_storage() { } |
|
2501 |
|
2502 bool setLocation(Option &O, StorageClass &L) { |
|
2503 if (Location) |
|
2504 return O.error("cl::location(x) specified more than once!"); |
|
2505 + |
|
2506 Location = &L; |
|
2507 return false; |
|
2508 } |
|
2509 @@ -1312,9 +1711,38 @@ |
|
2510 // |
|
2511 template <class DataType> |
|
2512 class list_storage<DataType, bool> : public std::vector<DataType> { |
|
2513 +private: |
|
2514 + list_storage<DataType, bool>(list_storage<DataType, bool> &&RHS) LLVM_DELETED_FUNCTION; |
|
2515 + list_storage<DataType, bool> |
|
2516 + &&operator=(list_storage<DataType, bool> &&RHS) LLVM_DELETED_FUNCTION; |
|
2517 + |
|
2518 public: |
|
2519 + list_storage<DataType, bool>() : std::vector<DataType>() { } |
|
2520 + list_storage<DataType, bool>(const list_storage<DataType, bool> &RHS) |
|
2521 + : std::vector<DataType>(RHS) { } |
|
2522 + list_storage<DataType, bool> |
|
2523 + &operator=(const list_storage<DataType, bool> &RHS) { |
|
2524 + if (this != &RHS) |
|
2525 + std::vector<DataType>::operator=(RHS); |
|
2526 + |
|
2527 + return *this; |
|
2528 + } |
|
2529 + |
|
2530 + virtual ~list_storage<DataType, bool>() { } |
|
2531 + |
|
2532 template <class T> void addValue(const T &V) { |
|
2533 - std::vector<DataType>::push_back(V); |
|
2534 + T LV(V); |
|
2535 + this->push_back(LV); |
|
2536 + } |
|
2537 + |
|
2538 + void addValue(const DataType &V) { |
|
2539 + DataType LV(V); |
|
2540 + std::vector<DataType> &VEC = static_cast<std::vector<DataType>& >(*this); |
|
2541 + VEC.push_back(LV); |
|
2542 + } |
|
2543 + |
|
2544 + const std::vector<DataType> &getStorage() const { |
|
2545 + return static_cast<const std::vector<DataType>& >(*this); |
|
2546 } |
|
2547 }; |
|
2548 |
|
2549 @@ -1324,40 +1752,47 @@ |
|
2550 template <class DataType, class Storage = bool, |
|
2551 class ParserClass = parser<DataType>> |
|
2552 class list : public Option, public list_storage<DataType, Storage> { |
|
2553 + friend class Option; |
|
2554 + |
|
2555 std::vector<unsigned> Positions; |
|
2556 ParserClass Parser; |
|
2557 |
|
2558 - enum ValueExpected getValueExpectedFlagDefault() const override { |
|
2559 +protected: |
|
2560 + virtual enum ValueExpected getValueExpectedFlagDefault() const override { |
|
2561 return Parser.getValueExpectedFlagDefault(); |
|
2562 } |
|
2563 - void |
|
2564 - getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { |
|
2565 + |
|
2566 + virtual void |
|
2567 + getExtraOptionNames(std::vector<const char *> &OptionNames) override { |
|
2568 return Parser.getExtraOptionNames(OptionNames); |
|
2569 } |
|
2570 |
|
2571 - bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2572 - StringRef Arg) override { |
|
2573 + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2574 + StringRef Arg) override { |
|
2575 typename ParserClass::parser_data_type Val = |
|
2576 typename ParserClass::parser_data_type(); |
|
2577 + |
|
2578 if (Parser.parse(*this, ArgName, Arg, Val)) |
|
2579 return true; // Parse Error! |
|
2580 - list_storage<DataType, Storage>::addValue(Val); |
|
2581 + |
|
2582 + this->addValue(Val); |
|
2583 setPosition(pos); |
|
2584 Positions.push_back(pos); |
|
2585 return false; |
|
2586 } |
|
2587 |
|
2588 // Forward printing stuff to the parser... |
|
2589 - size_t getOptionWidth() const override { |
|
2590 + virtual size_t getOptionWidth() const override { |
|
2591 return Parser.getOptionWidth(*this); |
|
2592 } |
|
2593 - void printOptionInfo(size_t GlobalWidth) const override { |
|
2594 + |
|
2595 + virtual void printOptionInfo(size_t GlobalWidth) const override { |
|
2596 Parser.printOptionInfo(*this, GlobalWidth); |
|
2597 } |
|
2598 |
|
2599 // Unimplemented: list options don't currently store their default value. |
|
2600 - void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { |
|
2601 - } |
|
2602 + virtual void |
|
2603 + printOptionValue(size_t GlobalWidth, bool Force) const override { } |
|
2604 |
|
2605 void done() { |
|
2606 addArgument(); |
|
2607 @@ -1365,8 +1800,26 @@ |
|
2608 } |
|
2609 |
|
2610 public: |
|
2611 + list() : Option(), list_storage<DataType, Storage>(), |
|
2612 + Positions(), Parser(ParserClass()) { } |
|
2613 + |
|
2614 + list(const Option &O) |
|
2615 + : Option(O), list_storage<DataType, Storage>(), |
|
2616 + Positions(), Parser(ParserClass()) { } |
|
2617 + |
|
2618 + list(Option *O) |
|
2619 + : Option(*O), list_storage<DataType, Storage>(), |
|
2620 + Positions(), Parser(ParserClass()) { } |
|
2621 + |
|
2622 + ~list() { } |
|
2623 + |
|
2624 ParserClass &getParser() { return Parser; } |
|
2625 |
|
2626 + void addArgument() { |
|
2627 + assert(!NextRegistered && "argument multiply registered!"); |
|
2628 + Option::registerOption(this); |
|
2629 + } |
|
2630 + |
|
2631 unsigned getPosition(unsigned optnum) const { |
|
2632 assert(optnum < this->size() && "Invalid option index"); |
|
2633 return Positions[optnum]; |
|
2634 @@ -1500,6 +1953,7 @@ |
|
2635 bool setLocation(Option &O, unsigned &L) { |
|
2636 if (Location) |
|
2637 return O.error("cl::location(x) specified more than once!"); |
|
2638 + |
|
2639 Location = &L; |
|
2640 return false; |
|
2641 } |
|
2642 @@ -1551,12 +2005,12 @@ |
|
2643 return Parser.getValueExpectedFlagDefault(); |
|
2644 } |
|
2645 void |
|
2646 - getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { |
|
2647 + getExtraOptionNames(std::vector<const char *> &OptionNames) override { |
|
2648 return Parser.getExtraOptionNames(OptionNames); |
|
2649 } |
|
2650 |
|
2651 - bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2652 - StringRef Arg) override { |
|
2653 + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2654 + StringRef Arg) override { |
|
2655 typename ParserClass::parser_data_type Val = |
|
2656 typename ParserClass::parser_data_type(); |
|
2657 if (Parser.parse(*this, ArgName, Arg, Val)) |
|
2658 @@ -1690,14 +2144,17 @@ |
|
2659 |
|
2660 class alias : public Option { |
|
2661 Option *AliasFor; |
|
2662 - bool handleOccurrence(unsigned pos, StringRef /*ArgName*/, |
|
2663 - StringRef Arg) override { |
|
2664 + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, |
|
2665 + StringRef Arg) override { |
|
2666 + |
|
2667 return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg); |
|
2668 } |
|
2669 - bool addOccurrence(unsigned pos, StringRef /*ArgName*/, StringRef Value, |
|
2670 - bool MultiArg = false) override { |
|
2671 + |
|
2672 + virtual bool addOccurrence(unsigned pos, StringRef ArgName, StringRef Value, |
|
2673 + bool MultiArg = false) override { |
|
2674 return AliasFor->addOccurrence(pos, AliasFor->ArgStr, Value, MultiArg); |
|
2675 } |
|
2676 + |
|
2677 // Handle printing stuff... |
|
2678 size_t getOptionWidth() const override; |
|
2679 void printOptionInfo(size_t GlobalWidth) const override; |
|
2680 @@ -1847,7 +2304,7 @@ |
|
2681 /// lines and end of the response file to be marked with a nullptr string. |
|
2682 /// \param [out] NewArgv All parsed strings are appended to NewArgv. |
|
2683 void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, |
|
2684 - SmallVectorImpl<const char *> &NewArgv, |
|
2685 + std::vector<const char *> &NewArgv, |
|
2686 bool MarkEOLs = false); |
|
2687 |
|
2688 /// \brief Tokenizes a Windows command line which may contain quotes and escaped |
|
2689 @@ -1862,13 +2319,13 @@ |
|
2690 /// lines and end of the response file to be marked with a nullptr string. |
|
2691 /// \param [out] NewArgv All parsed strings are appended to NewArgv. |
|
2692 void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, |
|
2693 - SmallVectorImpl<const char *> &NewArgv, |
|
2694 + std::vector<const char *> &NewArgv, |
|
2695 bool MarkEOLs = false); |
|
2696 |
|
2697 /// \brief String tokenization function type. Should be compatible with either |
|
2698 /// Windows or Unix command line tokenizers. |
|
2699 typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver, |
|
2700 - SmallVectorImpl<const char *> &NewArgv, |
|
2701 + std::vector<const char *> &NewArgv, |
|
2702 bool MarkEOLs); |
|
2703 |
|
2704 /// \brief Expand response files on a command line recursively using the given |
|
2705 @@ -1886,7 +2343,7 @@ |
|
2706 /// with nullptrs in the Argv vector. |
|
2707 /// \return true if all @files were expanded successfully or there were none. |
|
2708 bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, |
|
2709 - SmallVectorImpl<const char *> &Argv, |
|
2710 + std::vector<const char *> &Argv, |
|
2711 bool MarkEOLs = false); |
|
2712 |
|
2713 } // End namespace cl |
|
2714 --- include/llvm/Support/FileSystem.h 2014-12-15 19:10:29.000000000 -0800 |
|
2715 +++ include/llvm/Support/FileSystem.h 2016-01-24 21:14:49.000000000 -0800 |
|
2716 @@ -680,10 +680,35 @@ |
|
2717 |
|
2718 public: |
|
2719 explicit directory_entry(const Twine &path, file_status st = file_status()) |
|
2720 - : Path(path.str()) |
|
2721 - , Status(st) {} |
|
2722 + : Path(path.str()), Status(st) { } |
|
2723 |
|
2724 - directory_entry() {} |
|
2725 + directory_entry() : Path(""), Status(file_status()) { } |
|
2726 + |
|
2727 + directory_entry(const directory_entry &rhs) |
|
2728 + : Path(rhs.Path), Status(rhs.Status) { } |
|
2729 + |
|
2730 + directory_entry(directory_entry &&rhs) |
|
2731 + : Path(rhs.Path), Status(rhs.Status) { } |
|
2732 + |
|
2733 + ~directory_entry() { } |
|
2734 + |
|
2735 + directory_entry &operator=(const directory_entry &rhs) { |
|
2736 + if (this != &rhs) { |
|
2737 + Path = rhs.Path; |
|
2738 + Status = rhs.Status; |
|
2739 + } |
|
2740 + |
|
2741 + return *this; |
|
2742 + } |
|
2743 + |
|
2744 + directory_entry &operator=(directory_entry &&rhs) { |
|
2745 + if (this != &rhs) { |
|
2746 + Path = rhs.Path; |
|
2747 + Status = rhs.Status; |
|
2748 + } |
|
2749 + |
|
2750 + return *this; |
|
2751 + } |
|
2752 |
|
2753 void assign(const Twine &path, file_status st = file_status()) { |
|
2754 Path = path.str(); |
|
2755 --- include/llvm/Support/PluginLoader.h 2007-12-29 11:59:42.000000000 -0800 |
|
2756 +++ include/llvm/Support/PluginLoader.h 2016-01-24 11:01:53.000000000 -0800 |
|
2757 @@ -22,6 +22,8 @@ |
|
2758 namespace llvm { |
|
2759 struct PluginLoader { |
|
2760 void operator=(const std::string &Filename); |
|
2761 + bool operator==(const std::string &Filename) const; |
|
2762 + bool operator!=(const std::string &Filename) const; |
|
2763 static unsigned getNumPlugins(); |
|
2764 static std::string& getPlugin(unsigned num); |
|
2765 }; |
|
2766 --- utils/TableGen/AsmMatcherEmitter.cpp 2015-01-03 00:16:29.000000000 -0800 |
|
2767 +++ utils/TableGen/AsmMatcherEmitter.cpp 2016-01-26 14:57:52.000000000 -0800 |
|
2768 @@ -121,7 +121,7 @@ |
|
2769 #define DEBUG_TYPE "asm-matcher-emitter" |
|
2770 |
|
2771 static cl::opt<std::string> |
|
2772 -MatchPrefix("match-prefix", cl::init(""), |
|
2773 +MatchPrefix("match-prefix", cl::init(std::string("")), |
|
2774 cl::desc("Only match instructions with the given prefix")); |
|
2775 |
|
2776 namespace { |
|
2777 --- tools/llc/llc.cpp 2014-12-11 23:52:06.000000000 -0800 |
|
2778 +++ tools/llc/llc.cpp 2016-01-26 14:44:02.000000000 -0800 |
|
2779 @@ -50,13 +50,14 @@ |
|
2780 // and back-end code generation options are specified with the target machine. |
|
2781 // |
|
2782 static cl::opt<std::string> |
|
2783 -InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); |
|
2784 +InputFilename(cl::Positional, cl::desc("<input bitcode>"), |
|
2785 + cl::init(std::string("-"))); |
|
2786 |
|
2787 static cl::opt<std::string> |
|
2788 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); |
|
2789 |
|
2790 static cl::opt<unsigned> |
|
2791 -TimeCompilations("time-compilations", cl::Hidden, cl::init(1u), |
|
2792 +TimeCompilations("time-compilations", cl::Hidden, cl::init(1U), |
|
2793 cl::value_desc("N"), |
|
2794 cl::desc("Repeat compilation N times for timing")); |
|
2795 |
|
2796 @@ -65,13 +66,15 @@ |
|
2797 cl::desc("Disable integrated assembler")); |
|
2798 |
|
2799 // Determine optimization level. |
|
2800 +// ORIGINAL: |
|
2801 static cl::opt<char> |
|
2802 OptLevel("O", |
|
2803 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " |
|
2804 "(default = '-O2')"), |
|
2805 cl::Prefix, |
|
2806 - cl::ZeroOrMore, |
|
2807 - cl::init(' ')); |
|
2808 + cl::Optional, |
|
2809 + cl::ValueRequired, |
|
2810 + cl::init('2')); |
|
2811 |
|
2812 static cl::opt<std::string> |
|
2813 TargetTriple("mtriple", cl::desc("Override target triple for module")); |
|
2814 --- tools/llvm-as/llvm-as.cpp 2014-08-25 11:16:47.000000000 -0700 |
|
2815 +++ tools/llvm-as/llvm-as.cpp 2016-01-26 15:07:18.000000000 -0800 |
|
2816 @@ -15,6 +15,8 @@ |
|
2817 // |
|
2818 //===----------------------------------------------------------------------===// |
|
2819 |
|
2820 +#include "llvm/Support/CommandLine.h" |
|
2821 + |
|
2822 #include "llvm/IR/LLVMContext.h" |
|
2823 #include "llvm/AsmParser/Parser.h" |
|
2824 #include "llvm/Bitcode/ReaderWriter.h" |
|
2825 @@ -28,11 +30,21 @@ |
|
2826 #include "llvm/Support/SourceMgr.h" |
|
2827 #include "llvm/Support/SystemUtils.h" |
|
2828 #include "llvm/Support/ToolOutputFile.h" |
|
2829 -#include <memory> |
|
2830 using namespace llvm; |
|
2831 |
|
2832 +#include <memory> |
|
2833 +#include <string> |
|
2834 + |
|
2835 +static cl::opt<std::string> |
|
2836 +HiddenOption("h", cl::Hidden, cl::desc("hidden option"), |
|
2837 + cl::init("")); |
|
2838 + |
|
2839 static cl::opt<std::string> |
|
2840 -InputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-")); |
|
2841 +InputFilename(cl::Positional, cl::desc("<input file>"), |
|
2842 + cl::NotHidden, |
|
2843 + cl::Optional, |
|
2844 + cl::init(std::string("-")), |
|
2845 + cl::ValuePositionalNoArgs); |
|
2846 |
|
2847 static cl::opt<std::string> |
|
2848 OutputFilename("o", cl::desc("Override output filename"), |
|
2849 --- tools/llvm-dis/llvm-dis.cpp 2015-01-09 16:07:30.000000000 -0800 |
|
2850 +++ tools/llvm-dis/llvm-dis.cpp 2016-02-01 12:08:04.531107200 -0800 |
|
2851 @@ -38,7 +38,8 @@ |
|
2852 using namespace llvm; |
|
2853 |
|
2854 static cl::opt<std::string> |
|
2855 -InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); |
|
2856 +InputFilename(cl::Positional, cl::desc("<input bitcode>"), |
|
2857 + cl::init(std::string("-"))); |
|
2858 |
|
2859 static cl::opt<std::string> |
|
2860 OutputFilename("o", cl::desc("Override output filename"), |
|
2861 --- tools/bugpoint/OptimizerDriver.cpp 2014-11-07 13:30:36.000000000 -0800 |
|
2862 +++ tools/bugpoint/OptimizerDriver.cpp 2016-01-26 15:51:53.000000000 -0800 |
|
2863 @@ -46,7 +46,7 @@ |
|
2864 // ChildOutput - This option captures the name of the child output file that |
|
2865 // is set up by the parent bugpoint process |
|
2866 cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden); |
|
2867 - cl::opt<std::string> OptCmd("opt-command", cl::init(""), |
|
2868 + cl::opt<std::string> OptCmd("opt-command", cl::init(std::string("")), |
|
2869 cl::desc("Path to opt. (default: search path " |
|
2870 "for 'opt'.)")); |
|
2871 } |
|
2872 --- tools/opt/opt.cpp 2014-12-11 23:52:14.000000000 -0800 |
|
2873 +++ tools/opt/opt.cpp 2016-01-26 14:43:37.000000000 -0800 |
|
2874 @@ -72,7 +72,7 @@ |
|
2875 // |
|
2876 static cl::opt<std::string> |
|
2877 InputFilename(cl::Positional, cl::desc("<input bitcode file>"), |
|
2878 - cl::init("-"), cl::value_desc("filename")); |
|
2879 + cl::init(std::string("-")), cl::value_desc("filename")); |
|
2880 |
|
2881 static cl::opt<std::string> |
|
2882 OutputFilename("o", cl::desc("Override output filename"), |
|
2883 @@ -175,7 +175,7 @@ |
|
2884 static cl::opt<std::string> |
|
2885 DefaultDataLayout("default-data-layout", |
|
2886 cl::desc("data layout string to use if not specified by module"), |
|
2887 - cl::value_desc("layout-string"), cl::init("")); |
|
2888 + cl::value_desc("layout-string"), cl::init(std::string(""))); |
|
2889 |
|
2890 |
|
2891 |
|
2892 --- unittests/Support/CommandLineTest.cpp 2014-08-22 12:29:17.000000000 -0700 |
|
2893 +++ unittests/Support/CommandLineTest.cpp 2016-01-27 11:20:39.000000000 -0800 |
|
2894 @@ -7,12 +7,17 @@ |
|
2895 // |
|
2896 //===----------------------------------------------------------------------===// |
|
2897 |
|
2898 +#ifndef SKIP_ENVIRONMENT_TESTS |
|
2899 +#define SKIP_ENVIRONMENT_TESTS 1 |
|
2900 +#endif |
|
2901 + |
|
2902 #include "llvm/ADT/STLExtras.h" |
|
2903 #include "llvm/Config/config.h" |
|
2904 #include "llvm/Support/CommandLine.h" |
|
2905 #include "gtest/gtest.h" |
|
2906 #include <stdlib.h> |
|
2907 #include <string> |
|
2908 +#include <vector> |
|
2909 |
|
2910 using namespace llvm; |
|
2911 |
|
2912 @@ -47,21 +52,23 @@ |
|
2913 typedef cl::opt<T> Base; |
|
2914 public: |
|
2915 // One option... |
|
2916 - template<class M0t> |
|
2917 - explicit StackOption(const M0t &M0) : Base(M0) {} |
|
2918 + template<typename T0> |
|
2919 + explicit StackOption(const T0 &M0) : cl::opt<T>(M0) { } |
|
2920 |
|
2921 // Two options... |
|
2922 - template<class M0t, class M1t> |
|
2923 - StackOption(const M0t &M0, const M1t &M1) : Base(M0, M1) {} |
|
2924 + template<typename T0, typename T1> |
|
2925 + explicit StackOption(const T0 &M0, const T1 &M1) : cl::opt<T>(M0, M1) { } |
|
2926 |
|
2927 // Three options... |
|
2928 - template<class M0t, class M1t, class M2t> |
|
2929 - StackOption(const M0t &M0, const M1t &M1, const M2t &M2) : Base(M0, M1, M2) {} |
|
2930 + template<typename T0, typename T1, typename T2> |
|
2931 + explicit StackOption(const T0 &M0, const T1 &M1, const T2 &M2) |
|
2932 + : cl::opt<T>(M0, M1, M2) { } |
|
2933 |
|
2934 // Four options... |
|
2935 - template<class M0t, class M1t, class M2t, class M3t> |
|
2936 - StackOption(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) |
|
2937 - : Base(M0, M1, M2, M3) {} |
|
2938 + template<typename T0, typename T1, typename T2, typename T3> |
|
2939 + explicit StackOption(const T0 &M0, const T1 &M1, |
|
2940 + const T2 &M2, const T3 &M3) |
|
2941 + : cl::opt<T>(M0, M1, M2, M3) { } |
|
2942 |
|
2943 ~StackOption() { |
|
2944 this->removeArgument(); |
|
2945 @@ -112,7 +119,7 @@ |
|
2946 |
|
2947 const char test_env_var[] = "LLVM_TEST_COMMAND_LINE_FLAGS"; |
|
2948 |
|
2949 -cl::opt<std::string> EnvironmentTestOption("env-test-opt"); |
|
2950 +static cl::opt<std::string> EnvironmentTestOption("env-test-opt"); |
|
2951 TEST(CommandLineTest, ParseEnvironment) { |
|
2952 TempEnvVar TEV(test_env_var, "-env-test-opt=hello"); |
|
2953 EXPECT_EQ("", EnvironmentTestOption); |
|
2954 @@ -153,12 +160,13 @@ |
|
2955 }; |
|
2956 |
|
2957 typedef void ParserFunction(StringRef Source, llvm::cl::StringSaver &Saver, |
|
2958 - SmallVectorImpl<const char *> &NewArgv, |
|
2959 + std::vector<const char*> &NewArgv, |
|
2960 bool MarkEOLs); |
|
2961 |
|
2962 void testCommandLineTokenizer(ParserFunction *parse, const char *Input, |
|
2963 - const char *const Output[], size_t OutputSize) { |
|
2964 - SmallVector<const char *, 0> Actual; |
|
2965 + std::vector<const char*> &Output, |
|
2966 + size_t OutputSize) { |
|
2967 + std::vector<const char*> Actual; |
|
2968 StrDupSaver Saver; |
|
2969 parse(Input, Saver, Actual, /*MarkEOLs=*/false); |
|
2970 EXPECT_EQ(OutputSize, Actual.size()); |
|
2971 @@ -175,7 +183,12 @@ |
|
2972 const char *const Output[] = { "foo bar", "foo bar", "foo bar", "foo\\bar", |
|
2973 "foobarbaz", "C:\\src\\foo.cpp", |
|
2974 "C:\\src\\foo.cpp" }; |
|
2975 - testCommandLineTokenizer(cl::TokenizeGNUCommandLine, Input, Output, |
|
2976 + |
|
2977 + std::vector<const char*> OutputVector; |
|
2978 + for (unsigned I = 0; I < array_lengthof(Output); ++I) |
|
2979 + OutputVector.push_back(Output[I]); |
|
2980 + |
|
2981 + testCommandLineTokenizer(cl::TokenizeGNUCommandLine, Input, OutputVector, |
|
2982 array_lengthof(Output)); |
|
2983 } |
|
2984 |
|
2985 @@ -184,10 +197,17 @@ |
|
2986 "\"st \\\"u\" \\v"; |
|
2987 const char *const Output[] = { "a\\b", "c\\\\d", "e\\f g", "h\"i", "j\\\"k", |
|
2988 "lmn", "o", "pqr", "st \"u", "\\v" }; |
|
2989 - testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input, Output, |
|
2990 + |
|
2991 + std::vector<const char*> OutputVector; |
|
2992 + for (unsigned I = 0; I < array_lengthof(Output); ++I) |
|
2993 + OutputVector.push_back(Output[I]); |
|
2994 + |
|
2995 + testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input, OutputVector, |
|
2996 array_lengthof(Output)); |
|
2997 } |
|
2998 |
|
2999 +#ifndef ALIAS_WITH_ARGUMENT_TESTS_ARE_BROKEN |
|
3000 +// This test case is 100% broken. |
|
3001 TEST(CommandLineTest, AliasesWithArguments) { |
|
3002 static const size_t ARGC = 3; |
|
3003 const char *const Inputs[][ARGC] = { |
|
3004 @@ -201,7 +221,6 @@ |
|
3005 StackOption<std::string> Actual("actual"); |
|
3006 StackOption<bool> Extra("extra"); |
|
3007 StackOption<std::string> Input(cl::Positional); |
|
3008 - |
|
3009 cl::alias Alias("alias", llvm::cl::aliasopt(Actual)); |
|
3010 |
|
3011 cl::ParseCommandLineOptions(ARGC, Inputs[i]); |
|
3012 @@ -211,6 +230,7 @@ |
|
3013 Alias.removeArgument(); |
|
3014 } |
|
3015 } |
|
3016 +#endif |
|
3017 |
|
3018 void testAliasRequired(int argc, const char *const *argv) { |
|
3019 StackOption<std::string> Option("option", cl::Required); |
|
3020 --- utils/FileCheck/FileCheck.cpp 2014-11-18 18:56:00.000000000 -0800 |
|
3021 +++ utils/FileCheck/FileCheck.cpp 2016-02-01 13:52:04.699904440 -0800 |
|
3022 @@ -40,7 +40,8 @@ |
|
3023 |
|
3024 static cl::opt<std::string> |
|
3025 InputFilename("input-file", cl::desc("File to check (defaults to stdin)"), |
|
3026 - cl::init("-"), cl::value_desc("filename")); |
|
3027 + cl::value_desc("filename"), |
|
3028 + cl::init(std::string("-"))); |
|
3029 |
|
3030 static cl::list<std::string> |
|
3031 CheckPrefixes("check-prefix", |
|
3032 --- include/llvm/LinkAllPasses.h 2015-01-14 03:23:27.000000000 -0800 |
|
3033 +++ include/llvm/LinkAllPasses.h 2016-02-01 09:24:47.493918163 -0800 |
|
3034 @@ -15,6 +15,7 @@ |
|
3035 #ifndef LLVM_LINKALLPASSES_H |
|
3036 #define LLVM_LINKALLPASSES_H |
|
3037 |
|
3038 +#include "llvm/Analysis/AliasAnalysis.h" |
|
3039 #include "llvm/Analysis/AliasSetTracker.h" |
|
3040 #include "llvm/Analysis/CallPrinter.h" |
|
3041 #include "llvm/Analysis/DomPrinter.h" |
|
3042 @@ -35,10 +36,12 @@ |
|
3043 #include "llvm/Transforms/Utils/SymbolRewriter.h" |
|
3044 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" |
|
3045 #include "llvm/Transforms/Vectorize.h" |
|
3046 + |
|
3047 #include <cstdlib> |
|
3048 |
|
3049 namespace { |
|
3050 struct ForcePassLinking { |
|
3051 + __attribute__((used, noinline)) |
|
3052 ForcePassLinking() { |
|
3053 // We must reference the passes in such a way that compilers will not |
|
3054 // delete it all as dead code, even with whole program optimization, |
|
3055 @@ -47,6 +50,8 @@ |
|
3056 if (std::getenv("bar") != (char*) -1) |
|
3057 return; |
|
3058 |
|
3059 + asm(""); |
|
3060 + |
|
3061 (void) llvm::createAAEvalPass(); |
|
3062 (void) llvm::createAggressiveDCEPass(); |
|
3063 (void) llvm::createAliasAnalysisCounterPass(); |
|
3064 @@ -148,9 +153,13 @@ |
|
3065 (void) llvm::createMetaRenamerPass(); |
|
3066 (void) llvm::createFunctionAttrsPass(); |
|
3067 (void) llvm::createMergeFunctionsPass(); |
|
3068 - (void) llvm::createPrintModulePass(*(llvm::raw_ostream*)nullptr); |
|
3069 - (void) llvm::createPrintFunctionPass(*(llvm::raw_ostream*)nullptr); |
|
3070 - (void) llvm::createPrintBasicBlockPass(*(llvm::raw_ostream*)nullptr); |
|
3071 + |
|
3072 + std::string S; |
|
3073 + llvm::raw_string_ostream RSO(S); |
|
3074 + |
|
3075 + (void) llvm::createPrintModulePass(RSO); |
|
3076 + (void) llvm::createPrintFunctionPass(RSO); |
|
3077 + (void) llvm::createPrintBasicBlockPass(RSO); |
|
3078 (void) llvm::createModuleDebugInfoPrinterPass(); |
|
3079 (void) llvm::createPartialInliningPass(); |
|
3080 (void) llvm::createLintPass(); |
|
3081 @@ -167,13 +176,20 @@ |
|
3082 (void) llvm::createSeparateConstOffsetFromGEPPass(); |
|
3083 (void) llvm::createRewriteSymbolsPass(); |
|
3084 |
|
3085 - (void)new llvm::IntervalPartition(); |
|
3086 - (void)new llvm::ScalarEvolution(); |
|
3087 - ((llvm::Function*)nullptr)->viewCFGOnly(); |
|
3088 + llvm::IntervalPartition *LIP = new llvm::IntervalPartition(); |
|
3089 + (void) LIP; |
|
3090 + |
|
3091 + llvm::ScalarEvolution *LSE = new llvm::ScalarEvolution(); |
|
3092 + (void) LSE; |
|
3093 + |
|
3094 + llvm::Function *F = |
|
3095 + llvm::Function::Create(nullptr, llvm::GlobalValue::ExternalLinkage); |
|
3096 + F->viewCFGOnly(); |
|
3097 + |
|
3098 llvm::RGPassManager RGM; |
|
3099 - ((llvm::RegionPass*)nullptr)->runOnRegion((llvm::Region*)nullptr, RGM); |
|
3100 - llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)nullptr); |
|
3101 - X.add(nullptr, 0, llvm::AAMDNodes()); // for -print-alias-sets |
|
3102 + llvm::AliasAnalysis LAA; |
|
3103 + llvm::AliasSetTracker LAST(LAA); |
|
3104 + LAST.add(nullptr, 0, llvm::AAMDNodes()); // for -print-alias-sets |
|
3105 } |
|
3106 } ForcePassLinking; // Force link by creating a global definition. |
|
3107 } |
|