xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-debuginfo-analyzer/Options.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===-- options.cpp - Command line options for llvm-debuginfo-analyzer----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This handles the command line options for llvm-debuginfo-analyzer.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Options.h"
14 #include "llvm/DebugInfo/LogicalView/Core/LVOptions.h"
15 #include "llvm/DebugInfo/LogicalView/Core/LVSort.h"
16 #include "llvm/Support/CommandLine.h"
17 
18 using namespace llvm;
19 using namespace llvm::logicalview;
20 using namespace llvm::logicalview::cmdline;
21 
22 /// @}
23 /// Command line options.
24 /// @{
25 
26 OffsetParser::OffsetParser(cl::Option &O) : parser<unsigned long long>(O) {}
27 OffsetParser::~OffsetParser() = default;
28 
29 bool OffsetParser::parse(cl::Option &O, StringRef ArgName, StringRef Arg,
30                          unsigned long long &Val) {
31   char *End;
32   std::string Argument(Arg);
33   Val = strtoull(Argument.c_str(), &End, 0);
34   if (*End)
35     // Print an error message if unrecognized character.
36     return O.error("'" + Arg + "' unrecognized character.");
37   return false;
38 }
39 
40 LVOptions cmdline::ReaderOptions;
41 
42 //===----------------------------------------------------------------------===//
43 // Specific options
44 //===----------------------------------------------------------------------===//
45 cl::list<std::string>
46     cmdline::InputFilenames(cl::desc("<input object files or .dSYM bundles>"),
47                             cl::Positional, cl::ZeroOrMore);
48 
49 //===----------------------------------------------------------------------===//
50 // '--attribute' options
51 //===----------------------------------------------------------------------===//
52 cl::OptionCategory
53     cmdline::AttributeCategory("Attribute Options",
54                                "These control extra attributes that are "
55                                "added when the element is printed.");
56 
57 // --attribute=<value>[,<value>,...]
58 cl::list<LVAttributeKind> cmdline::AttributeOptions(
59     "attribute", cl::cat(AttributeCategory), cl::desc("Element attributes."),
60     cl::Hidden, cl::CommaSeparated,
61     values(clEnumValN(LVAttributeKind::All, "all", "Include all attributes."),
62            clEnumValN(LVAttributeKind::Argument, "argument",
63                       "Template parameters replaced by its arguments."),
64            clEnumValN(LVAttributeKind::Base, "base",
65                       "Base types (int, bool, etc.)."),
66            clEnumValN(LVAttributeKind::Coverage, "coverage",
67                       "Symbol location coverage."),
68            clEnumValN(LVAttributeKind::Directories, "directories",
69                       "Directories referenced in the debug information."),
70            clEnumValN(LVAttributeKind::Discarded, "discarded",
71                       "Discarded elements by the linker."),
72            clEnumValN(LVAttributeKind::Discriminator, "discriminator",
73                       "Discriminators for inlined function instances."),
74            clEnumValN(LVAttributeKind::Encoded, "encoded",
75                       "Template arguments encoded in the template name."),
76            clEnumValN(LVAttributeKind::Extended, "extended",
77                       "Advanced attributes alias."),
78            clEnumValN(LVAttributeKind::Filename, "filename",
79                       "Filename where the element is defined."),
80            clEnumValN(LVAttributeKind::Files, "files",
81                       "Files referenced in the debug information."),
82            clEnumValN(LVAttributeKind::Format, "format",
83                       "Object file format name."),
84            clEnumValN(LVAttributeKind::Gaps, "gaps",
85                       "Missing debug location (gaps)."),
86            clEnumValN(LVAttributeKind::Generated, "generated",
87                       "Compiler generated elements."),
88            clEnumValN(LVAttributeKind::Global, "global",
89                       "Element referenced across Compile Units."),
90            clEnumValN(LVAttributeKind::Inserted, "inserted",
91                       "Generated inlined abstract references."),
92            clEnumValN(LVAttributeKind::Language, "language",
93                       "Source language name."),
94            clEnumValN(LVAttributeKind::Level, "level",
95                       "Lexical scope level (File=0, Compile Unit=1)."),
96            clEnumValN(LVAttributeKind::Linkage, "linkage", "Linkage name."),
97            clEnumValN(LVAttributeKind::Local, "local",
98                       "Element referenced only in the Compile Unit."),
99            clEnumValN(LVAttributeKind::Location, "location",
100                       "Element debug location."),
101            clEnumValN(LVAttributeKind::Offset, "offset",
102                       "Debug information offset."),
103            clEnumValN(LVAttributeKind::Pathname, "pathname",
104                       "Pathname where the element is defined."),
105            clEnumValN(LVAttributeKind::Producer, "producer",
106                       "Toolchain identification name."),
107            clEnumValN(LVAttributeKind::Publics, "publics",
108                       "Function names that are public."),
109            clEnumValN(LVAttributeKind::Qualified, "qualified",
110                       "The element type include parents in its name."),
111            clEnumValN(LVAttributeKind::Qualifier, "qualifier",
112                       "Line qualifiers (Newstatement, BasicBlock, etc.)."),
113            clEnumValN(LVAttributeKind::Range, "range",
114                       "Debug location ranges."),
115            clEnumValN(LVAttributeKind::Reference, "reference",
116                       "Element declaration and definition references."),
117            clEnumValN(LVAttributeKind::Register, "register",
118                       "Processor register names."),
119            clEnumValN(LVAttributeKind::Size, "size", "Type sizes."),
120            clEnumValN(LVAttributeKind::Standard, "standard",
121                       "Basic attributes alias."),
122            clEnumValN(LVAttributeKind::Subrange, "subrange",
123                       "Subrange encoding information for arrays."),
124            clEnumValN(LVAttributeKind::System, "system",
125                       "Display PDB's MS system elements."),
126            clEnumValN(LVAttributeKind::Typename, "typename",
127                       "Include Parameters in templates."),
128            clEnumValN(LVAttributeKind::Underlying, "underlying",
129                       "Underlying type for type definitions."),
130            clEnumValN(LVAttributeKind::Zero, "zero", "Zero line numbers.")));
131 
132 //===----------------------------------------------------------------------===//
133 // '--compare' options
134 //===----------------------------------------------------------------------===//
135 cl::OptionCategory
136     cmdline::CompareCategory("Compare Options",
137                              "These control the view comparison.");
138 
139 // --compare-context
140 static cl::opt<bool, true>
141     CompareContext("compare-context", cl::cat(CompareCategory),
142                    cl::desc("Add the view as compare context."), cl::Hidden,
143                    cl::ZeroOrMore, cl::location(ReaderOptions.Compare.Context),
144                    cl::init(false));
145 
146 // --compare=<value>[,<value>,...]
147 cl::list<LVCompareKind> cmdline::CompareElements(
148     "compare", cl::cat(CompareCategory), cl::desc("Elements to compare."),
149     cl::Hidden, cl::CommaSeparated,
150     values(clEnumValN(LVCompareKind::All, "all", "Compare all elements."),
151            clEnumValN(LVCompareKind::Lines, "lines", "Lines."),
152            clEnumValN(LVCompareKind::Scopes, "scopes", "Scopes."),
153            clEnumValN(LVCompareKind::Symbols, "symbols", "Symbols."),
154            clEnumValN(LVCompareKind::Types, "types", "Types.")));
155 
156 //===----------------------------------------------------------------------===//
157 // '--output' options
158 //===----------------------------------------------------------------------===//
159 cl::OptionCategory
160     cmdline::OutputCategory("Output Options",
161                             "These control the output generated.");
162 
163 // --output-file=<filename>
164 cl::opt<std::string>
165     cmdline::OutputFilename("output-file", cl::cat(OutputCategory),
166                             cl::desc("Redirect output to the specified file."),
167                             cl::Hidden, cl::value_desc("filename"),
168                             cl::init("-"));
169 
170 // --output-folder=<path>
171 static cl::opt<std::string, true>
172     OutputFolder("output-folder", cl::cat(OutputCategory),
173                  cl::desc("Folder name for view splitting."),
174                  cl::value_desc("pathname"), cl::Hidden, cl::ZeroOrMore,
175                  cl::location(ReaderOptions.Output.Folder));
176 
177 // --output-level=<level>
178 static cl::opt<unsigned, true>
179     OutputLevel("output-level", cl::cat(OutputCategory),
180                 cl::desc("Only print to a depth of N elements."),
181                 cl::value_desc("N"), cl::Hidden, cl::ZeroOrMore,
182                 cl::location(ReaderOptions.Output.Level), cl::init(-1U));
183 
184 // --ouput=<value>[,<value>,...]
185 cl::list<LVOutputKind> cmdline::OutputOptions(
186     "output", cl::cat(OutputCategory), cl::desc("Outputs for view."),
187     cl::Hidden, cl::CommaSeparated,
188     values(clEnumValN(LVOutputKind::All, "all", "All outputs."),
189            clEnumValN(LVOutputKind::Split, "split",
190                       "Split the output by Compile Units."),
191            clEnumValN(LVOutputKind::Text, "text",
192                       "Use a free form text output."),
193            clEnumValN(LVOutputKind::Json, "json",
194                       "Use JSON as the output format.")));
195 
196 // --output-sort
197 static cl::opt<LVSortMode, true> OutputSort(
198     "output-sort", cl::cat(OutputCategory),
199     cl::desc("Primary key when ordering logical view (default: line)."),
200     cl::Hidden, cl::ZeroOrMore,
201     values(clEnumValN(LVSortMode::Kind, "kind", "Sort by element kind."),
202            clEnumValN(LVSortMode::Line, "line", "Sort by element line number."),
203            clEnumValN(LVSortMode::Name, "name", "Sort by element name."),
204            clEnumValN(LVSortMode::Offset, "offset", "Sort by element offset.")),
205     cl::location(ReaderOptions.Output.SortMode), cl::init(LVSortMode::Line));
206 
207 //===----------------------------------------------------------------------===//
208 // '--print' options
209 //===----------------------------------------------------------------------===//
210 cl::OptionCategory
211     cmdline::PrintCategory("Print Options",
212                            "These control which elements are printed.");
213 
214 // --print=<value>[,<value>,...]
215 cl::list<LVPrintKind> cmdline::PrintOptions(
216     "print", cl::cat(PrintCategory), cl::desc("Element to print."),
217     cl::CommaSeparated,
218     values(clEnumValN(LVPrintKind::All, "all", "All elements."),
219            clEnumValN(LVPrintKind::Elements, "elements",
220                       "Instructions, lines, scopes, symbols and types."),
221            clEnumValN(LVPrintKind::Instructions, "instructions",
222                       "Assembler instructions."),
223            clEnumValN(LVPrintKind::Lines, "lines",
224                       "Lines referenced in the debug information."),
225            clEnumValN(LVPrintKind::Scopes, "scopes",
226                       "A lexical block (Function, Class, etc.)."),
227            clEnumValN(LVPrintKind::Sizes, "sizes",
228                       "Scope contributions to the debug information."),
229            clEnumValN(LVPrintKind::Summary, "summary",
230                       "Summary of elements missing/added/matched/printed."),
231            clEnumValN(LVPrintKind::Symbols, "symbols",
232                       "Symbols (Variable, Members, etc.)."),
233            clEnumValN(LVPrintKind::Types, "types",
234                       "Types (Pointer, Reference, etc.)."),
235            clEnumValN(LVPrintKind::Warnings, "warnings",
236                       "Warnings detected.")));
237 
238 //===----------------------------------------------------------------------===//
239 // '--report' options
240 //===----------------------------------------------------------------------===//
241 cl::OptionCategory
242     cmdline::ReportCategory("Report Options",
243                             "These control how the elements are printed.");
244 
245 // --report=<value>[,<value>,...]
246 cl::list<LVReportKind> cmdline::ReportOptions(
247     "report", cl::cat(ReportCategory),
248     cl::desc("Reports layout used for print, compare and select."), cl::Hidden,
249     cl::CommaSeparated,
250     values(clEnumValN(LVReportKind::All, "all", "Generate all reports."),
251            clEnumValN(LVReportKind::Children, "children",
252                       "Selected elements are displayed in a tree view "
253                       "(Include children)"),
254            clEnumValN(LVReportKind::List, "list",
255                       "Selected elements are displayed in a tabular format."),
256            clEnumValN(LVReportKind::Parents, "parents",
257                       "Selected elements are displayed in a tree view. "
258                       "(Include parents)"),
259            clEnumValN(LVReportKind::View, "view",
260                       "Selected elements are displayed in a tree view "
261                       "(Include parents and children.")));
262 
263 //===----------------------------------------------------------------------===//
264 // '--select' options
265 //===----------------------------------------------------------------------===//
266 cl::OptionCategory
267     cmdline::SelectCategory("Select Options",
268                             "These control which elements are selected.");
269 
270 // --select-nocase
271 static cl::opt<bool, true>
272     SelectIgnoreCase("select-nocase", cl::cat(SelectCategory),
273                      cl::desc("Ignore case distinctions when searching."),
274                      cl::Hidden, cl::ZeroOrMore,
275                      cl::location(ReaderOptions.Select.IgnoreCase),
276                      cl::init(false));
277 
278 // --select-regex
279 static cl::opt<bool, true> SelectUseRegex(
280     "select-regex", cl::cat(SelectCategory),
281     cl::desc("Treat any <pattern> strings as regular expressions when "
282              "selecting instead of just as an exact string match."),
283     cl::Hidden, cl::ZeroOrMore, cl::location(ReaderOptions.Select.UseRegex),
284     cl::init(false));
285 
286 // --select=<pattern>
287 cl::list<std::string> cmdline::SelectPatterns(
288     "select", cl::cat(SelectCategory),
289     cl::desc("Search elements matching the given pattern."), cl::Hidden,
290     cl::value_desc("pattern"), cl::CommaSeparated);
291 
292 // --select-offsets=<value>[,<value>,...]
293 OffsetOptionList cmdline::SelectOffsets("select-offsets",
294                                         cl::cat(SelectCategory),
295                                         cl::desc("Offset element to print."),
296                                         cl::Hidden, cl::value_desc("offset"),
297                                         cl::CommaSeparated, cl::ZeroOrMore);
298 
299 // --select-elements=<value>[,<value>,...]
300 cl::list<LVElementKind> cmdline::SelectElements(
301     "select-elements", cl::cat(SelectCategory),
302     cl::desc("Conditions to use when printing elements."), cl::Hidden,
303     cl::CommaSeparated,
304     values(clEnumValN(LVElementKind::Discarded, "Discarded",
305                       "Discarded elements by the linker."),
306            clEnumValN(LVElementKind::Global, "Global",
307                       "Element referenced across Compile Units."),
308            clEnumValN(LVElementKind::Optimized, "Optimized",
309                       "Generated inlined abstract references.")));
310 
311 // --select-lines=<value>[,<value>,...]
312 cl::list<LVLineKind> cmdline::SelectLines(
313     "select-lines", cl::cat(SelectCategory),
314     cl::desc("Line kind to use when printing lines."), cl::Hidden,
315     cl::CommaSeparated,
316     values(
317         clEnumValN(LVLineKind::IsAlwaysStepInto, "AlwaysStepInto",
318                    "Always Step Into."),
319         clEnumValN(LVLineKind::IsBasicBlock, "BasicBlock", "Basic block."),
320         clEnumValN(LVLineKind::IsDiscriminator, "Discriminator",
321                    "Discriminator."),
322         clEnumValN(LVLineKind::IsEndSequence, "EndSequence", "End sequence."),
323         clEnumValN(LVLineKind::IsEpilogueBegin, "EpilogueBegin.",
324                    "Epilogue begin."),
325         clEnumValN(LVLineKind::IsLineDebug, "LineDebug", "Debug line."),
326         clEnumValN(LVLineKind::IsLineAssembler, "LineAssembler",
327                    "Assembler line."),
328         clEnumValN(LVLineKind::IsNeverStepInto, "NeverStepInto",
329                    "Never Step Into."),
330         clEnumValN(LVLineKind::IsNewStatement, "NewStatement",
331                    "New statement."),
332         clEnumValN(LVLineKind::IsPrologueEnd, "PrologueEnd", "Prologue end.")));
333 
334 // --select-scopes=<value>[,<value>,...]
335 cl::list<LVScopeKind> cmdline::SelectScopes(
336     "select-scopes", cl::cat(SelectCategory),
337     cl::desc("Scope kind to use when printing scopes."), cl::Hidden,
338     cl::CommaSeparated,
339     values(
340         clEnumValN(LVScopeKind::IsAggregate, "Aggregate",
341                    "Class, Structure or Union."),
342         clEnumValN(LVScopeKind::IsArray, "Array", "Array."),
343         clEnumValN(LVScopeKind::IsBlock, "Block", "Lexical block."),
344         clEnumValN(LVScopeKind::IsCallSite, "CallSite", "Call site block."),
345         clEnumValN(LVScopeKind::IsCatchBlock, "CatchBlock",
346                    "Exception catch block."),
347         clEnumValN(LVScopeKind::IsClass, "Class", "Class."),
348         clEnumValN(LVScopeKind::IsCompileUnit, "CompileUnit", "Compile unit."),
349         clEnumValN(LVScopeKind::IsEntryPoint, "EntryPoint",
350                    "Function entry point."),
351         clEnumValN(LVScopeKind::IsEnumeration, "Enumeration", "Enumeration."),
352         clEnumValN(LVScopeKind::IsFunction, "Function", "Function."),
353         clEnumValN(LVScopeKind::IsFunctionType, "FunctionType",
354                    "Function type."),
355         clEnumValN(LVScopeKind::IsInlinedFunction, "InlinedFunction",
356                    "Inlined function."),
357         clEnumValN(LVScopeKind::IsLabel, "Label", "Label."),
358         clEnumValN(LVScopeKind::IsLexicalBlock, "LexicalBlock",
359                    "Lexical block."),
360         clEnumValN(LVScopeKind::IsModule, "Module", "Module."),
361         clEnumValN(LVScopeKind::IsNamespace, "Namespace", "Namespace."),
362         clEnumValN(LVScopeKind::IsRoot, "Root", "Root."),
363         clEnumValN(LVScopeKind::IsStructure, "Structure", "Structure."),
364         clEnumValN(LVScopeKind::IsSubprogram, "Subprogram", "Subprogram."),
365         clEnumValN(LVScopeKind::IsTemplate, "Template", "Template."),
366         clEnumValN(LVScopeKind::IsTemplateAlias, "TemplateAlias",
367                    "Template alias."),
368         clEnumValN(LVScopeKind::IsTemplatePack, "TemplatePack",
369                    "Template pack."),
370         clEnumValN(LVScopeKind::IsTryBlock, "TryBlock", "Exception try block."),
371         clEnumValN(LVScopeKind::IsUnion, "Union", "Union.")));
372 
373 // --select-symbols=<value>[,<value>,...]
374 cl::list<LVSymbolKind> cmdline::SelectSymbols(
375     "select-symbols", cl::cat(SelectCategory),
376     cl::desc("Symbol kind to use when printing symbols."), cl::Hidden,
377     cl::CommaSeparated,
378     values(clEnumValN(LVSymbolKind::IsCallSiteParameter, "CallSiteParameter",
379                       "Call site parameter."),
380            clEnumValN(LVSymbolKind::IsConstant, "Constant", "Constant."),
381            clEnumValN(LVSymbolKind::IsInheritance, "Inheritance",
382                       "Inheritance."),
383            clEnumValN(LVSymbolKind::IsMember, "Member", "Member."),
384            clEnumValN(LVSymbolKind::IsParameter, "Parameter", "Parameter."),
385            clEnumValN(LVSymbolKind::IsUnspecified, "Unspecified",
386                       "Unspecified parameter."),
387            clEnumValN(LVSymbolKind::IsVariable, "Variable", "Variable.")));
388 
389 // --select-types=<value>[,<value>,...]
390 cl::list<LVTypeKind> cmdline::SelectTypes(
391     "select-types", cl::cat(SelectCategory),
392     cl::desc("Type kind to use when printing types."), cl::Hidden,
393     cl::CommaSeparated,
394     values(
395         clEnumValN(LVTypeKind::IsBase, "Base", "Base Type (int, bool, etc.)."),
396         clEnumValN(LVTypeKind::IsConst, "Const", "Constant specifier."),
397         clEnumValN(LVTypeKind::IsEnumerator, "Enumerator", "Enumerator."),
398         clEnumValN(LVTypeKind::IsImport, "Import", "Import."),
399         clEnumValN(LVTypeKind::IsImportDeclaration, "ImportDeclaration",
400                    "Import declaration."),
401         clEnumValN(LVTypeKind::IsImportModule, "ImportModule",
402                    "Import module."),
403         clEnumValN(LVTypeKind::IsPointer, "Pointer", "Pointer."),
404         clEnumValN(LVTypeKind::IsPointerMember, "PointerMember",
405                    "Pointer to member."),
406         clEnumValN(LVTypeKind::IsReference, "Reference", "Reference type."),
407         clEnumValN(LVTypeKind::IsRestrict, "Restrict", "Restrict specifier."),
408         clEnumValN(LVTypeKind::IsRvalueReference, "RvalueReference",
409                    "Rvalue reference."),
410         clEnumValN(LVTypeKind::IsSubrange, "Subrange", "Array subrange."),
411         clEnumValN(LVTypeKind::IsTemplateParam, "TemplateParam",
412                    "Template Parameter."),
413         clEnumValN(LVTypeKind::IsTemplateTemplateParam, "TemplateTemplateParam",
414                    "Template template parameter."),
415         clEnumValN(LVTypeKind::IsTemplateTypeParam, "TemplateTypeParam",
416                    "Template type parameter."),
417         clEnumValN(LVTypeKind::IsTemplateValueParam, "TemplateValueParam",
418                    "Template value parameter."),
419         clEnumValN(LVTypeKind::IsTypedef, "Typedef", "Type definition."),
420         clEnumValN(LVTypeKind::IsUnspecified, "Unspecified",
421                    "Unspecified type."),
422         clEnumValN(LVTypeKind::IsVolatile, "Volatile", "Volatile specifier.")));
423 
424 //===----------------------------------------------------------------------===//
425 // '--warning' options
426 //===----------------------------------------------------------------------===//
427 cl::OptionCategory
428     cmdline::WarningCategory("Warning Options",
429                              "These control the generated warnings.");
430 
431 // --warning=<value>[,<value>,...]
432 cl::list<LVWarningKind> cmdline::WarningOptions(
433     "warning", cl::cat(WarningCategory), cl::desc("Warnings to generate."),
434     cl::Hidden, cl::CommaSeparated,
435     values(
436         clEnumValN(LVWarningKind::All, "all", "All warnings."),
437         clEnumValN(LVWarningKind::Coverages, "coverages",
438                    "Invalid symbol coverages values."),
439         clEnumValN(LVWarningKind::Lines, "lines", "Debug lines that are zero."),
440         clEnumValN(LVWarningKind::Locations, "locations",
441                    "Invalid symbol locations."),
442         clEnumValN(LVWarningKind::Ranges, "ranges", "Invalid code ranges.")));
443 
444 //===----------------------------------------------------------------------===//
445 // '--internal' options
446 //===----------------------------------------------------------------------===//
447 cl::OptionCategory
448     cmdline::InternalCategory("Internal Options",
449                               "Internal traces and extra debugging code.");
450 
451 // --internal=<value>[,<value>,...]
452 cl::list<LVInternalKind> cmdline::InternalOptions(
453     "internal", cl::cat(InternalCategory), cl::desc("Traces to enable."),
454     cl::Hidden, cl::CommaSeparated,
455     values(
456         clEnumValN(LVInternalKind::All, "all", "Enable all traces."),
457         clEnumValN(LVInternalKind::Cmdline, "cmdline", "Print command line."),
458         clEnumValN(LVInternalKind::ID, "id", "Print unique element ID"),
459         clEnumValN(LVInternalKind::Integrity, "integrity",
460                    "Check elements integrity."),
461         clEnumValN(LVInternalKind::None, "none", "Ignore element line number."),
462         clEnumValN(LVInternalKind::Tag, "tag", "Debug information tags.")));
463 
464 /// @}
465 
466 // Copy local options into a globally accessible data structure.
467 void llvm::logicalview::cmdline::propagateOptions() {
468   // Traverse list of options and update the given set (Using case and Regex).
469   auto UpdatePattern = [&](auto &List, auto &Set, bool IgnoreCase,
470                            bool UseRegex) {
471     if (!List.empty())
472       for (std::string &Pattern : List)
473         Set.insert((IgnoreCase && !UseRegex) ? StringRef(Pattern).lower()
474                                              : Pattern);
475   };
476 
477   // Handle --select.
478   UpdatePattern(SelectPatterns, ReaderOptions.Select.Generic,
479                 ReaderOptions.Select.IgnoreCase, ReaderOptions.Select.UseRegex);
480 
481   // Traverse list of options and update the given set.
482   auto UpdateSet = [&](auto &List, auto &Set) {
483     std::copy(List.begin(), List.end(), std::inserter(Set, Set.begin()));
484   };
485 
486   // Handle options sets.
487   UpdateSet(AttributeOptions, ReaderOptions.Attribute.Kinds);
488   UpdateSet(PrintOptions, ReaderOptions.Print.Kinds);
489   UpdateSet(OutputOptions, ReaderOptions.Output.Kinds);
490   UpdateSet(ReportOptions, ReaderOptions.Report.Kinds);
491   UpdateSet(WarningOptions, ReaderOptions.Warning.Kinds);
492   UpdateSet(InternalOptions, ReaderOptions.Internal.Kinds);
493 
494   UpdateSet(SelectElements, ReaderOptions.Select.Elements);
495   UpdateSet(SelectLines, ReaderOptions.Select.Lines);
496   UpdateSet(SelectScopes, ReaderOptions.Select.Scopes);
497   UpdateSet(SelectSymbols, ReaderOptions.Select.Symbols);
498   UpdateSet(SelectTypes, ReaderOptions.Select.Types);
499   UpdateSet(SelectOffsets, ReaderOptions.Select.Offsets);
500   UpdateSet(CompareElements, ReaderOptions.Compare.Elements);
501 
502   // Resolve any options dependencies (ie. --print=all should set other
503   // print options, etc.).
504   ReaderOptions.resolveDependencies();
505 }
506