Files
RedBear-OS/local/recipes/dev/libclc/source/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
T
vasilito cb424d7448 build: static patch-sanity linter (shift-left the malformed-patch class)
verify-patch-sanity.py validates every active recipe .patch has internally-
consistent hunk line counts — catching the 'malformed patch at line N' failure
at commit/CI/preflight time instead of hours into a cook. This cycle hit that
class three times (qtwaylandscanner, sddm, xwayland), each only discovered when
cookbook tried to apply the patch.

Running it across the repo found 29 latent malformed patches (validated against
GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22').
They were harmless only because they sit in vendored recipes (baked, not re-
applied) — but would fail on any version-bump re-derivation. --fix recounts the
hunk headers (body untouched) and repaired all 29.

Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test
(test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats
(empty placeholders, bare-@@ git hunks).
2026-08-01 05:13:02 +03:00

506 lines
25 KiB
C++

//===-- options.cpp - Command line options for llvm-debuginfo-analyzer----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This handles the command line options for llvm-debuginfo-analyzer.
//
//===----------------------------------------------------------------------===//
#include "Options.h"
#include "llvm/DebugInfo/LogicalView/Core/LVOptions.h"
#include "llvm/DebugInfo/LogicalView/Core/LVSort.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
using namespace llvm::logicalview;
using namespace llvm::logicalview::cmdline;
/// @}
/// Command line options.
/// @{
OffsetParser::OffsetParser(cl::Option &O) : parser<unsigned long long>(O) {}
OffsetParser::~OffsetParser() = default;
bool OffsetParser::parse(cl::Option &O, StringRef ArgName, StringRef Arg,
unsigned long long &Val) {
char *End;
std::string Argument(Arg);
Val = strtoull(Argument.c_str(), &End, 0);
if (*End)
// Print an error message if unrecognized character.
return O.error("'" + Arg + "' unrecognized character.");
return false;
}
LVOptions cmdline::ReaderOptions;
//===----------------------------------------------------------------------===//
// Specific options
//===----------------------------------------------------------------------===//
cl::list<std::string>
cmdline::InputFilenames(cl::desc("<input object files or .dSYM bundles>"),
cl::Positional, cl::ZeroOrMore);
//===----------------------------------------------------------------------===//
// '--attribute' options
//===----------------------------------------------------------------------===//
cl::OptionCategory
cmdline::AttributeCategory("Attribute Options",
"These control extra attributes that are "
"added when the element is printed.");
// --attribute=<value>[,<value>,...]
cl::list<LVAttributeKind> cmdline::AttributeOptions(
"attribute", cl::cat(AttributeCategory), cl::desc("Element attributes."),
cl::Hidden, cl::CommaSeparated,
values(clEnumValN(LVAttributeKind::All, "all", "Include all attributes."),
clEnumValN(LVAttributeKind::Argument, "argument",
"Template parameters replaced by its arguments."),
clEnumValN(LVAttributeKind::Base, "base",
"Base types (int, bool, etc.)."),
clEnumValN(LVAttributeKind::Coverage, "coverage",
"Symbol location coverage."),
clEnumValN(LVAttributeKind::Directories, "directories",
"Directories referenced in the debug information."),
clEnumValN(LVAttributeKind::Discarded, "discarded",
"Discarded elements by the linker."),
clEnumValN(LVAttributeKind::Discriminator, "discriminator",
"Discriminators for inlined function instances."),
clEnumValN(LVAttributeKind::Encoded, "encoded",
"Template arguments encoded in the template name."),
clEnumValN(LVAttributeKind::Extended, "extended",
"Advanced attributes alias."),
clEnumValN(LVAttributeKind::Filename, "filename",
"Filename where the element is defined."),
clEnumValN(LVAttributeKind::Files, "files",
"Files referenced in the debug information."),
clEnumValN(LVAttributeKind::Format, "format",
"Object file format name."),
clEnumValN(LVAttributeKind::Gaps, "gaps",
"Missing debug location (gaps)."),
clEnumValN(LVAttributeKind::Generated, "generated",
"Compiler generated elements."),
clEnumValN(LVAttributeKind::Global, "global",
"Element referenced across Compile Units."),
clEnumValN(LVAttributeKind::Inserted, "inserted",
"Generated inlined abstract references."),
clEnumValN(LVAttributeKind::Language, "language",
"Source language name."),
clEnumValN(LVAttributeKind::Level, "level",
"Lexical scope level (File=0, Compile Unit=1)."),
clEnumValN(LVAttributeKind::Linkage, "linkage", "Linkage name."),
clEnumValN(LVAttributeKind::Local, "local",
"Element referenced only in the Compile Unit."),
clEnumValN(LVAttributeKind::Location, "location",
"Element debug location."),
clEnumValN(LVAttributeKind::Offset, "offset",
"Debug information offset."),
clEnumValN(LVAttributeKind::Pathname, "pathname",
"Pathname where the element is defined."),
clEnumValN(LVAttributeKind::Producer, "producer",
"Toolchain identification name."),
clEnumValN(LVAttributeKind::Publics, "publics",
"Function names that are public."),
clEnumValN(LVAttributeKind::Qualified, "qualified",
"The element type include parents in its name."),
clEnumValN(LVAttributeKind::Qualifier, "qualifier",
"Line qualifiers (Newstatement, BasicBlock, etc.)."),
clEnumValN(LVAttributeKind::Range, "range",
"Debug location ranges."),
clEnumValN(LVAttributeKind::Reference, "reference",
"Element declaration and definition references."),
clEnumValN(LVAttributeKind::Register, "register",
"Processor register names."),
clEnumValN(LVAttributeKind::Size, "size", "Type sizes."),
clEnumValN(LVAttributeKind::Standard, "standard",
"Basic attributes alias."),
clEnumValN(LVAttributeKind::Subrange, "subrange",
"Subrange encoding information for arrays."),
clEnumValN(LVAttributeKind::System, "system",
"Display PDB's MS system elements."),
clEnumValN(LVAttributeKind::Typename, "typename",
"Include Parameters in templates."),
clEnumValN(LVAttributeKind::Underlying, "underlying",
"Underlying type for type definitions."),
clEnumValN(LVAttributeKind::Zero, "zero", "Zero line numbers.")));
//===----------------------------------------------------------------------===//
// '--compare' options
//===----------------------------------------------------------------------===//
cl::OptionCategory
cmdline::CompareCategory("Compare Options",
"These control the view comparison.");
// --compare-context
static cl::opt<bool, true>
CompareContext("compare-context", cl::cat(CompareCategory),
cl::desc("Add the view as compare context."), cl::Hidden,
cl::ZeroOrMore, cl::location(ReaderOptions.Compare.Context),
cl::init(false));
// --compare=<value>[,<value>,...]
cl::list<LVCompareKind> cmdline::CompareElements(
"compare", cl::cat(CompareCategory), cl::desc("Elements to compare."),
cl::Hidden, cl::CommaSeparated,
values(clEnumValN(LVCompareKind::All, "all", "Compare all elements."),
clEnumValN(LVCompareKind::Lines, "lines", "Lines."),
clEnumValN(LVCompareKind::Scopes, "scopes", "Scopes."),
clEnumValN(LVCompareKind::Symbols, "symbols", "Symbols."),
clEnumValN(LVCompareKind::Types, "types", "Types.")));
//===----------------------------------------------------------------------===//
// '--output' options
//===----------------------------------------------------------------------===//
cl::OptionCategory
cmdline::OutputCategory("Output Options",
"These control the output generated.");
// --output-file=<filename>
cl::opt<std::string>
cmdline::OutputFilename("output-file", cl::cat(OutputCategory),
cl::desc("Redirect output to the specified file."),
cl::Hidden, cl::value_desc("filename"),
cl::init("-"));
// --output-folder=<path>
static cl::opt<std::string, true>
OutputFolder("output-folder", cl::cat(OutputCategory),
cl::desc("Folder name for view splitting."),
cl::value_desc("pathname"), cl::Hidden, cl::ZeroOrMore,
cl::location(ReaderOptions.Output.Folder));
// --output-level=<level>
static cl::opt<unsigned, true>
OutputLevel("output-level", cl::cat(OutputCategory),
cl::desc("Only print to a depth of N elements."),
cl::value_desc("N"), cl::Hidden, cl::ZeroOrMore,
cl::location(ReaderOptions.Output.Level), cl::init(-1U));
// --ouput=<value>[,<value>,...]
cl::list<LVOutputKind> cmdline::OutputOptions(
"output", cl::cat(OutputCategory), cl::desc("Outputs for view."),
cl::Hidden, cl::CommaSeparated,
values(clEnumValN(LVOutputKind::All, "all", "All outputs."),
clEnumValN(LVOutputKind::Split, "split",
"Split the output by Compile Units."),
clEnumValN(LVOutputKind::Text, "text",
"Use a free form text output."),
clEnumValN(LVOutputKind::Json, "json",
"Use JSON as the output format.")));
// --output-sort
static cl::opt<LVSortMode, true> OutputSort(
"output-sort", cl::cat(OutputCategory),
cl::desc("Primary key when ordering logical view (default: line)."),
cl::Hidden, cl::ZeroOrMore,
values(clEnumValN(LVSortMode::Kind, "kind", "Sort by element kind."),
clEnumValN(LVSortMode::Line, "line", "Sort by element line number."),
clEnumValN(LVSortMode::Name, "name", "Sort by element name."),
clEnumValN(LVSortMode::Offset, "offset", "Sort by element offset.")),
cl::location(ReaderOptions.Output.SortMode), cl::init(LVSortMode::Line));
//===----------------------------------------------------------------------===//
// '--print' options
//===----------------------------------------------------------------------===//
cl::OptionCategory
cmdline::PrintCategory("Print Options",
"These control which elements are printed.");
// --print=<value>[,<value>,...]
cl::list<LVPrintKind> cmdline::PrintOptions(
"print", cl::cat(PrintCategory), cl::desc("Element to print."),
cl::CommaSeparated,
values(clEnumValN(LVPrintKind::All, "all", "All elements."),
clEnumValN(LVPrintKind::Elements, "elements",
"Instructions, lines, scopes, symbols and types."),
clEnumValN(LVPrintKind::Instructions, "instructions",
"Assembler instructions."),
clEnumValN(LVPrintKind::Lines, "lines",
"Lines referenced in the debug information."),
clEnumValN(LVPrintKind::Scopes, "scopes",
"A lexical block (Function, Class, etc.)."),
clEnumValN(LVPrintKind::Sizes, "sizes",
"Scope contributions to the debug information."),
clEnumValN(LVPrintKind::Summary, "summary",
"Summary of elements missing/added/matched/printed."),
clEnumValN(LVPrintKind::Symbols, "symbols",
"Symbols (Variable, Members, etc.)."),
clEnumValN(LVPrintKind::Types, "types",
"Types (Pointer, Reference, etc.)."),
clEnumValN(LVPrintKind::Warnings, "warnings",
"Warnings detected.")));
//===----------------------------------------------------------------------===//
// '--report' options
//===----------------------------------------------------------------------===//
cl::OptionCategory
cmdline::ReportCategory("Report Options",
"These control how the elements are printed.");
// --report=<value>[,<value>,...]
cl::list<LVReportKind> cmdline::ReportOptions(
"report", cl::cat(ReportCategory),
cl::desc("Reports layout used for print, compare and select."), cl::Hidden,
cl::CommaSeparated,
values(clEnumValN(LVReportKind::All, "all", "Generate all reports."),
clEnumValN(LVReportKind::Children, "children",
"Selected elements are displayed in a tree view "
"(Include children)"),
clEnumValN(LVReportKind::List, "list",
"Selected elements are displayed in a tabular format."),
clEnumValN(LVReportKind::Parents, "parents",
"Selected elements are displayed in a tree view. "
"(Include parents)"),
clEnumValN(LVReportKind::View, "view",
"Selected elements are displayed in a tree view "
"(Include parents and children.")));
//===----------------------------------------------------------------------===//
// '--select' options
//===----------------------------------------------------------------------===//
cl::OptionCategory
cmdline::SelectCategory("Select Options",
"These control which elements are selected.");
// --select-nocase
static cl::opt<bool, true>
SelectIgnoreCase("select-nocase", cl::cat(SelectCategory),
cl::desc("Ignore case distinctions when searching."),
cl::Hidden, cl::ZeroOrMore,
cl::location(ReaderOptions.Select.IgnoreCase),
cl::init(false));
// --select-regex
static cl::opt<bool, true> SelectUseRegex(
"select-regex", cl::cat(SelectCategory),
cl::desc("Treat any <pattern> strings as regular expressions when "
"selecting instead of just as an exact string match."),
cl::Hidden, cl::ZeroOrMore, cl::location(ReaderOptions.Select.UseRegex),
cl::init(false));
// --select=<pattern>
cl::list<std::string> cmdline::SelectPatterns(
"select", cl::cat(SelectCategory),
cl::desc("Search elements matching the given pattern."), cl::Hidden,
cl::value_desc("pattern"), cl::CommaSeparated);
// --select-offsets=<value>[,<value>,...]
OffsetOptionList cmdline::SelectOffsets("select-offsets",
cl::cat(SelectCategory),
cl::desc("Offset element to print."),
cl::Hidden, cl::value_desc("offset"),
cl::CommaSeparated, cl::ZeroOrMore);
// --select-elements=<value>[,<value>,...]
cl::list<LVElementKind> cmdline::SelectElements(
"select-elements", cl::cat(SelectCategory),
cl::desc("Conditions to use when printing elements."), cl::Hidden,
cl::CommaSeparated,
values(clEnumValN(LVElementKind::Discarded, "Discarded",
"Discarded elements by the linker."),
clEnumValN(LVElementKind::Global, "Global",
"Element referenced across Compile Units."),
clEnumValN(LVElementKind::Optimized, "Optimized",
"Generated inlined abstract references.")));
// --select-lines=<value>[,<value>,...]
cl::list<LVLineKind> cmdline::SelectLines(
"select-lines", cl::cat(SelectCategory),
cl::desc("Line kind to use when printing lines."), cl::Hidden,
cl::CommaSeparated,
values(
clEnumValN(LVLineKind::IsAlwaysStepInto, "AlwaysStepInto",
"Always Step Into."),
clEnumValN(LVLineKind::IsBasicBlock, "BasicBlock", "Basic block."),
clEnumValN(LVLineKind::IsDiscriminator, "Discriminator",
"Discriminator."),
clEnumValN(LVLineKind::IsEndSequence, "EndSequence", "End sequence."),
clEnumValN(LVLineKind::IsEpilogueBegin, "EpilogueBegin.",
"Epilogue begin."),
clEnumValN(LVLineKind::IsLineDebug, "LineDebug", "Debug line."),
clEnumValN(LVLineKind::IsLineAssembler, "LineAssembler",
"Assembler line."),
clEnumValN(LVLineKind::IsNeverStepInto, "NeverStepInto",
"Never Step Into."),
clEnumValN(LVLineKind::IsNewStatement, "NewStatement",
"New statement."),
clEnumValN(LVLineKind::IsPrologueEnd, "PrologueEnd", "Prologue end.")));
// --select-scopes=<value>[,<value>,...]
cl::list<LVScopeKind> cmdline::SelectScopes(
"select-scopes", cl::cat(SelectCategory),
cl::desc("Scope kind to use when printing scopes."), cl::Hidden,
cl::CommaSeparated,
values(
clEnumValN(LVScopeKind::IsAggregate, "Aggregate",
"Class, Structure or Union."),
clEnumValN(LVScopeKind::IsArray, "Array", "Array."),
clEnumValN(LVScopeKind::IsBlock, "Block", "Lexical block."),
clEnumValN(LVScopeKind::IsCallSite, "CallSite", "Call site block."),
clEnumValN(LVScopeKind::IsCatchBlock, "CatchBlock",
"Exception catch block."),
clEnumValN(LVScopeKind::IsClass, "Class", "Class."),
clEnumValN(LVScopeKind::IsCompileUnit, "CompileUnit", "Compile unit."),
clEnumValN(LVScopeKind::IsEntryPoint, "EntryPoint",
"Function entry point."),
clEnumValN(LVScopeKind::IsEnumeration, "Enumeration", "Enumeration."),
clEnumValN(LVScopeKind::IsFunction, "Function", "Function."),
clEnumValN(LVScopeKind::IsFunctionType, "FunctionType",
"Function type."),
clEnumValN(LVScopeKind::IsInlinedFunction, "InlinedFunction",
"Inlined function."),
clEnumValN(LVScopeKind::IsLabel, "Label", "Label."),
clEnumValN(LVScopeKind::IsLexicalBlock, "LexicalBlock",
"Lexical block."),
clEnumValN(LVScopeKind::IsModule, "Module", "Module."),
clEnumValN(LVScopeKind::IsNamespace, "Namespace", "Namespace."),
clEnumValN(LVScopeKind::IsRoot, "Root", "Root."),
clEnumValN(LVScopeKind::IsStructure, "Structure", "Structure."),
clEnumValN(LVScopeKind::IsSubprogram, "Subprogram", "Subprogram."),
clEnumValN(LVScopeKind::IsTemplate, "Template", "Template."),
clEnumValN(LVScopeKind::IsTemplateAlias, "TemplateAlias",
"Template alias."),
clEnumValN(LVScopeKind::IsTemplatePack, "TemplatePack",
"Template pack."),
clEnumValN(LVScopeKind::IsTryBlock, "TryBlock", "Exception try block."),
clEnumValN(LVScopeKind::IsUnion, "Union", "Union.")));
// --select-symbols=<value>[,<value>,...]
cl::list<LVSymbolKind> cmdline::SelectSymbols(
"select-symbols", cl::cat(SelectCategory),
cl::desc("Symbol kind to use when printing symbols."), cl::Hidden,
cl::CommaSeparated,
values(clEnumValN(LVSymbolKind::IsCallSiteParameter, "CallSiteParameter",
"Call site parameter."),
clEnumValN(LVSymbolKind::IsConstant, "Constant", "Constant."),
clEnumValN(LVSymbolKind::IsInheritance, "Inheritance",
"Inheritance."),
clEnumValN(LVSymbolKind::IsMember, "Member", "Member."),
clEnumValN(LVSymbolKind::IsParameter, "Parameter", "Parameter."),
clEnumValN(LVSymbolKind::IsUnspecified, "Unspecified",
"Unspecified parameter."),
clEnumValN(LVSymbolKind::IsVariable, "Variable", "Variable.")));
// --select-types=<value>[,<value>,...]
cl::list<LVTypeKind> cmdline::SelectTypes(
"select-types", cl::cat(SelectCategory),
cl::desc("Type kind to use when printing types."), cl::Hidden,
cl::CommaSeparated,
values(
clEnumValN(LVTypeKind::IsBase, "Base", "Base Type (int, bool, etc.)."),
clEnumValN(LVTypeKind::IsConst, "Const", "Constant specifier."),
clEnumValN(LVTypeKind::IsEnumerator, "Enumerator", "Enumerator."),
clEnumValN(LVTypeKind::IsImport, "Import", "Import."),
clEnumValN(LVTypeKind::IsImportDeclaration, "ImportDeclaration",
"Import declaration."),
clEnumValN(LVTypeKind::IsImportModule, "ImportModule",
"Import module."),
clEnumValN(LVTypeKind::IsPointer, "Pointer", "Pointer."),
clEnumValN(LVTypeKind::IsPointerMember, "PointerMember",
"Pointer to member."),
clEnumValN(LVTypeKind::IsReference, "Reference", "Reference type."),
clEnumValN(LVTypeKind::IsRestrict, "Restrict", "Restrict specifier."),
clEnumValN(LVTypeKind::IsRvalueReference, "RvalueReference",
"Rvalue reference."),
clEnumValN(LVTypeKind::IsSubrange, "Subrange", "Array subrange."),
clEnumValN(LVTypeKind::IsTemplateParam, "TemplateParam",
"Template Parameter."),
clEnumValN(LVTypeKind::IsTemplateTemplateParam, "TemplateTemplateParam",
"Template template parameter."),
clEnumValN(LVTypeKind::IsTemplateTypeParam, "TemplateTypeParam",
"Template type parameter."),
clEnumValN(LVTypeKind::IsTemplateValueParam, "TemplateValueParam",
"Template value parameter."),
clEnumValN(LVTypeKind::IsTypedef, "Typedef", "Type definition."),
clEnumValN(LVTypeKind::IsUnspecified, "Unspecified",
"Unspecified type."),
clEnumValN(LVTypeKind::IsVolatile, "Volatile", "Volatile specifier.")));
//===----------------------------------------------------------------------===//
// '--warning' options
//===----------------------------------------------------------------------===//
cl::OptionCategory
cmdline::WarningCategory("Warning Options",
"These control the generated warnings.");
// --warning=<value>[,<value>,...]
cl::list<LVWarningKind> cmdline::WarningOptions(
"warning", cl::cat(WarningCategory), cl::desc("Warnings to generate."),
cl::Hidden, cl::CommaSeparated,
values(
clEnumValN(LVWarningKind::All, "all", "All warnings."),
clEnumValN(LVWarningKind::Coverages, "coverages",
"Invalid symbol coverages values."),
clEnumValN(LVWarningKind::Lines, "lines", "Debug lines that are zero."),
clEnumValN(LVWarningKind::Locations, "locations",
"Invalid symbol locations."),
clEnumValN(LVWarningKind::Ranges, "ranges", "Invalid code ranges.")));
//===----------------------------------------------------------------------===//
// '--internal' options
//===----------------------------------------------------------------------===//
cl::OptionCategory
cmdline::InternalCategory("Internal Options",
"Internal traces and extra debugging code.");
// --internal=<value>[,<value>,...]
cl::list<LVInternalKind> cmdline::InternalOptions(
"internal", cl::cat(InternalCategory), cl::desc("Traces to enable."),
cl::Hidden, cl::CommaSeparated,
values(
clEnumValN(LVInternalKind::All, "all", "Enable all traces."),
clEnumValN(LVInternalKind::Cmdline, "cmdline", "Print command line."),
clEnumValN(LVInternalKind::ID, "id", "Print unique element ID"),
clEnumValN(LVInternalKind::Integrity, "integrity",
"Check elements integrity."),
clEnumValN(LVInternalKind::None, "none", "Ignore element line number."),
clEnumValN(LVInternalKind::Tag, "tag", "Debug information tags.")));
/// @}
// Copy local options into a globally accessible data structure.
void llvm::logicalview::cmdline::propagateOptions() {
// Traverse list of options and update the given set (Using case and Regex).
auto UpdatePattern = [&](auto &List, auto &Set, bool IgnoreCase,
bool UseRegex) {
if (!List.empty())
for (std::string &Pattern : List)
Set.insert((IgnoreCase && !UseRegex) ? StringRef(Pattern).lower()
: Pattern);
};
// Handle --select.
UpdatePattern(SelectPatterns, ReaderOptions.Select.Generic,
ReaderOptions.Select.IgnoreCase, ReaderOptions.Select.UseRegex);
// Traverse list of options and update the given set.
auto UpdateSet = [&](auto &List, auto &Set) {
std::copy(List.begin(), List.end(), std::inserter(Set, Set.begin()));
};
// Handle options sets.
UpdateSet(AttributeOptions, ReaderOptions.Attribute.Kinds);
UpdateSet(PrintOptions, ReaderOptions.Print.Kinds);
UpdateSet(OutputOptions, ReaderOptions.Output.Kinds);
UpdateSet(ReportOptions, ReaderOptions.Report.Kinds);
UpdateSet(WarningOptions, ReaderOptions.Warning.Kinds);
UpdateSet(InternalOptions, ReaderOptions.Internal.Kinds);
UpdateSet(SelectElements, ReaderOptions.Select.Elements);
UpdateSet(SelectLines, ReaderOptions.Select.Lines);
UpdateSet(SelectScopes, ReaderOptions.Select.Scopes);
UpdateSet(SelectSymbols, ReaderOptions.Select.Symbols);
UpdateSet(SelectTypes, ReaderOptions.Select.Types);
UpdateSet(SelectOffsets, ReaderOptions.Select.Offsets);
UpdateSet(CompareElements, ReaderOptions.Compare.Elements);
// Resolve any options dependencies (ie. --print=all should set other
// print options, etc.).
ReaderOptions.resolveDependencies();
}