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