581 lines · cpp
1//===-- LVOptions.cpp -----------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This implements the LVOptions class.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/DebugInfo/LogicalView/Core/LVOptions.h"14#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"15#include "llvm/Support/Errc.h"16 17using namespace llvm;18using namespace llvm::logicalview;19 20#define DEBUG_TYPE "Options"21 22//===----------------------------------------------------------------------===//23// Options extracted from the command line.24//===----------------------------------------------------------------------===//25static LVOptions Options;26LVOptions *LVOptions::getOptions() { return &Options; }27void LVOptions::setOptions(LVOptions *CmdOptions) { Options = *CmdOptions; }28 29void LVOptions::resolveDependencies() {30 // Attributes that are classified as standard options.31 auto StandardAttributes = [&]() {32 // Set the 'standard' attribute to indicate its associated attributes.33 setAttributeStandard();34 35 setAttributeBase();36 setAttributeCoverage();37 setAttributeDirectories();38 setAttributeDiscriminator();39 setAttributeFilename();40 setAttributeFiles();41 setAttributeFormat();42 setAttributeLanguage();43 setAttributeLevel();44 setAttributeProducer();45 setAttributePublics();46 setAttributeRange();47 setAttributeReference();48 setAttributeZero();49 };50 51 // Attributes that are classified as extended options.52 auto ExtendedAttributes = [&]() {53 // Set the 'extended' attribute to indicate its associated attributes.54 setAttributeExtended();55 56 setAttributeArgument();57 setAttributeDiscarded();58 setAttributeEncoded();59 setAttributeGaps();60 setAttributeGenerated();61 setAttributeGlobal();62 setAttributeInserted();63 setAttributeLinkage();64 setAttributeLocal();65 setAttributeLocation();66 setAttributeOffset();67 setAttributePathname();68 setAttributeQualified();69 setAttributeQualifier();70 setAttributeRegister();71 setAttributeSize();72 setAttributeSubrange();73 setAttributeSystem();74 setAttributeTypename();75 };76 77 // '--Attribute=standard' settings.78 if (getAttributeStandard())79 StandardAttributes();80 81 // '--Attribute=extended' settings.82 if (getAttributeExtended())83 ExtendedAttributes();84 85 // '--Attribute=all' settings.86 if (getAttributeAll()) {87 StandardAttributes();88 ExtendedAttributes();89 }90 91 // '--attribute=pathname' supersedes '--attribute=filename'.92 if (getAttributePathname())93 resetAttributeFilename();94 95 // Assume '--output=text' as default96 if (!getOutputText() && !getOutputJson())97 setOutputText();98 99 // '--output=all' settings.100 if (getOutputAll()) {101 setOutputJson();102 setOutputSplit();103 setOutputText();104 }105 106 // A view split folder was specified.107 if (getOutputFolder().length())108 setOutputSplit();109 110 // Always use the full pathname with splitted output.111 if (getOutputSplit())112 setAttributePathname();113 114 // '--print=elements' settings.115 if (getPrintElements()) {116 setPrintInstructions();117 setPrintLines();118 setPrintScopes();119 setPrintSymbols();120 setPrintTypes();121 }122 123 // '--print=all' settings.124 if (getPrintAll()) {125 setPrintInstructions();126 setPrintLines();127 setPrintScopes();128 setPrintSizes();129 setPrintSymbols();130 setPrintSummary();131 setPrintTypes();132 setPrintWarnings();133 }134 135 // '--warning=all' settings.136 if (getWarningAll()) {137 setWarningCoverages();138 setWarningLines();139 setWarningLocations();140 setWarningRanges();141 }142 143 // '--internal=all' settings.144 if (getInternalAll()) {145 setInternalCmdline();146 setInternalID();147 setInternalIntegrity();148 setInternalNone();149 setInternalTag();150 }151 152 // '--compare=all' settings.153 if (getCompareAll()) {154 setCompareLines();155 setCompareScopes();156 setCompareSymbols();157 setCompareTypes();158 }159 160 // Compare the scopes if a request for compare symbols, types, lines.161 if (getCompareLines() || getCompareSymbols() || getCompareTypes())162 setCompareScopes();163 164 // Generic request for comparison.165 if (getCompareScopes())166 setCompareExecute();167 168 // Print any logical line (debug or instruction).169 if (getPrintInstructions() || getPrintLines())170 setPrintAnyLine();171 172 // Print any logical element (line, scope, symbol or type).173 if (getPrintAnyLine() || getPrintScopes() || getPrintSymbols() ||174 getPrintTypes())175 setPrintAnyElement();176 177 // Print 'sizes' or 'summary'.178 if (getPrintSizes() && getPrintSummary())179 setPrintSizesSummary();180 181 // Generic request for printing.182 if (getPrintAll() || getPrintAnyElement() || getPrintSizesSummary() ||183 getPrintWarnings())184 setPrintExecute();185 186 // '--reports=all' settings.187 if (getReportAll()) {188 setReportChildren();189 setReportList();190 setReportParents();191 setReportView();192 }193 194 // '--report=view' is a shortcut for '--report=parents,children'.195 if (getReportView()) {196 setReportChildren();197 setReportParents();198 }199 200 // The report will include: Parents or Children.201 if (getReportParents() || getReportChildren() || getReportView())202 setReportAnyView();203 204 // The report will include: List or Parents or Children.205 if (getReportList() || getReportAnyView())206 setReportExecute();207 208 // If a view or element comparison has been requested, the following options209 // must be set, in order to get a correct compare:210 // 1) Sort the CUs, to get a fast compare.211 // 2) Encode template instantiations, so the names include template212 // parameter information.213 // 3) Include qualified types and their sizes.214 // 4) Include any inserted abstract references.215 // 5) For added/missing elements add the '+' or '-' tags.216 if (getCompareExecute()) {217 resetPrintExecute();218 setComparePrint();219 setSortMode(LVSortMode::Line);220 setAttributeAdded();221 setAttributeArgument();222 setAttributeEncoded();223 setAttributeInserted();224 setAttributeMissing();225 setAttributeQualified();226 setAttributeSize();227 }228 229 // Enable formatting for printing (indentation, print children).230 setPrintFormatting();231 232 // These attributes are dependent on the capture of location information.233 if (getAttributeCoverage() || getAttributeGaps() || getAttributeRegister())234 setAttributeLocation();235 236 // Location information is only relevant when printing symbols.237 if (!getPrintSymbols()) {238 resetAttributeCoverage();239 resetAttributeGaps();240 resetAttributeLocation();241 resetAttributeRegister();242 }243 244 // Quick check for printing any element source information.245 if (getAttributeFilename() || getAttributePathname())246 setAttributeAnySource();247 248 // Quick check for printing any location information.249 if (getAttributeLocation() || getAttributeRange())250 setAttributeAnyLocation();251 252 if (getAttributeRange() || getPrintAnyLine())253 setGeneralCollectRanges();254 255 calculateIndentationSize();256 257 // Print collected command line options.258 LLVM_DEBUG({ dump(); });259}260 261void LVOptions::calculateIndentationSize() {262 if (getInternalID()) {263 std::string String = hexSquareString(0);264 IndentationSize += String.length();265 }266 if (getCompareExecute() && (getAttributeAdded() || getAttributeMissing()))267 ++IndentationSize;268 if (getAttributeOffset()) {269 std::string String = hexSquareString(0);270 IndentationSize += String.length();271 }272 if (getAttributeLevel()) {273 std::stringstream Stream;274 Stream.str(std::string());275 Stream << "[" << std::setfill('0') << std::setw(3) << 0 << "]";276 IndentationSize += Stream.tellp();277 }278 if (getAttributeGlobal())279 ++IndentationSize;280}281 282// Print the current values for all the options, after the dependencies283// has been resolved.284void LVOptions::print(raw_ostream &OS) const {285 // --attribute286 OS << "** Attributes **\n"287 << "All: " << getAttributeAll() << ", "288 << "Argument: " << getAttributeArgument() << ", "289 << "Base: " << getAttributeBase() << ", "290 << "Coverage: " << getAttributeCoverage() << "\n"291 << "Directories: " << getAttributeDirectories() << ", "292 << "Discarded: " << getAttributeDiscarded() << ", "293 << "Discriminator: " << getAttributeDiscriminator() << ", "294 << "Encoded: " << getAttributeEncoded() << "\n"295 << "Extended: " << getAttributeExtended() << ", "296 << "Filename: " << getAttributeFilename() << ", "297 << "Files: " << getAttributeFiles() << ", "298 << "Format: " << getAttributeFormat() << "\n"299 << "Gaps: " << getAttributeGaps() << ", "300 << "Generated: " << getAttributeGenerated() << ", "301 << "Global: " << getAttributeGlobal() << ", "302 << "Inserted: " << getAttributeInserted() << "\n"303 << "Level: " << getAttributeLevel() << ", "304 << "Linkage: " << getAttributeLinkage() << ", "305 << "Local: " << getAttributeLocal() << ", "306 << "Location: " << getAttributeLocation() << "\n"307 << "Offset: " << getAttributeOffset() << ", "308 << "Pathname: " << getAttributePathname() << ", "309 << "Producer: " << getAttributeProducer() << ", "310 << "Publics: " << getAttributePublics() << "\n"311 << "Qualified: " << getAttributeQualified() << ", "312 << "Qualifier: " << getAttributeQualifier() << ", "313 << "Range: " << getAttributeRange() << ", "314 << "Reference: " << getAttributeReference() << "\n"315 << "Register: " << getAttributeRegister() << ", "316 << "Size: " << getAttributeSize() << ", "317 << "Standard: " << getAttributeStandard() << ", "318 << "Subrange: " << getAttributeSubrange() << "\n"319 << "System: " << getAttributeSystem() << ", "320 << "Typename: " << getAttributeTypename() << ", "321 << "Underlying: " << getAttributeUnderlying() << ", "322 << "Zero: " << getAttributeZero() << "\n";323 OS << "Added: " << getAttributeAdded() << ", "324 << "AnyLocation: " << getAttributeAnyLocation() << ", "325 << "AnySource: " << getAttributeAnySource() << ", "326 << "Missing: " << getAttributeMissing() << "\n"327 << "\n";328 329 // --compare330 OS << "** Compare **\n"331 << "All: " << getCompareAll() << ", "332 << "Lines: " << getCompareLines() << ", "333 << "Scopes: " << getCompareScopes() << ", "334 << "Symbols: " << getCompareSymbols() << ", "335 << "Types: " << getCompareTypes() << "\n";336 OS << "Context: " << getCompareContext() << ", "337 << "Execute: " << getCompareExecute() << ", "338 << "Print: " << getComparePrint() << "\n"339 << "\n";340 341 // --print342 OS << "** Print **\n"343 << "All: " << getPrintAll() << ", "344 << "Elements: " << getPrintElements() << ", "345 << "Instructions: " << getPrintInstructions() << ", "346 << "Lines: " << getPrintLines() << "\n"347 << "Scopes: " << getPrintScopes() << ", "348 << "Sizes: " << getPrintSizes() << ", "349 << "Summary: " << getPrintSummary() << ", "350 << "Symbols: " << getPrintSymbols() << "\n"351 << "Types: " << getPrintTypes() << ", "352 << "Warnings: " << getPrintWarnings() << "\n";353 OS << "AnyElemeny: " << getPrintAnyElement() << ", "354 << "AnyLine: " << getPrintAnyLine() << ", "355 << "Execute: " << getPrintExecute() << ", "356 << "Formatting: " << getPrintFormatting() << "\n"357 << "Offset: " << getPrintOffset() << ", "358 << "SizesSummary: " << getPrintSizesSummary() << "\n"359 << "\n";360 361 // --report362 OS << "** Report **\n"363 << "All: " << getReportAll() << ", "364 << "Children: " << getReportChildren() << ", "365 << "List: " << getReportList() << ", "366 << "Parents: " << getReportParents() << ", "367 << "View: " << getReportView() << "\n";368 OS << "AnyView: " << getReportAnyView() << ", "369 << "Execute: " << getReportExecute() << "\n"370 << "\n";371 372 // --select373 OS << "** Select **\n"374 << "IgnoreCase: " << getSelectIgnoreCase() << ", "375 << "UseRegex: " << getSelectUseRegex() << ", "376 << "Execute: " << getSelectExecute() << ", "377 << "GenericKind: " << getSelectGenericKind() << "\n"378 << "GenericPattern: " << getSelectGenericPattern() << ", "379 << "OffsetPattern: " << getSelectOffsetPattern() << "\n"380 << "\n";381 382 // --warning383 OS << "** Warning **\n"384 << "All: " << getWarningAll() << ", "385 << "Coverage: " << getWarningCoverages() << ", "386 << "Lines: " << getWarningLines() << ", "387 << "Locations: " << getWarningLocations() << ", "388 << "Ranges: " << getWarningRanges() << "\n"389 << "\n";390 391 // --internal392 OS << "** Internal **\n"393 << "All: " << Options.getInternalAll() << ", "394 << "Cmdline: " << Options.getInternalCmdline() << ", "395 << "ID: " << Options.getInternalID() << ", "396 << "Integrity: " << Options.getInternalIntegrity() << ", "397 << "None: " << Options.getInternalNone() << "\n"398 << "Tag: " << Options.getInternalTag() << "\n"399 << "\n";400}401 402//===----------------------------------------------------------------------===//403// Logical element selection using patterns.404//===----------------------------------------------------------------------===//405LVPatterns *LVPatterns::getPatterns() {406 static LVPatterns Patterns;407 return &Patterns;408}409 410Error LVPatterns::createMatchEntry(LVMatchInfo &Filters, StringRef Pattern,411 bool IgnoreCase, bool UseRegex) {412 LVMatch Match;413 // Process pattern as regular expression.414 if (UseRegex) {415 Match.Pattern = std::string(Pattern);416 if (Pattern.size()) {417 Match.RE = std::make_shared<Regex>(Pattern, IgnoreCase ? Regex::IgnoreCase418 : Regex::NoFlags);419 std::string Error;420 if (!Match.RE->isValid(Error))421 return createStringError(errc::invalid_argument,422 "Error in regular expression: %s",423 Error.c_str());424 425 Match.Mode = LVMatchMode::Regex;426 Filters.push_back(Match);427 return Error::success();428 }429 }430 431 // Process pattern as an exact string match, depending on the case.432 Match.Pattern = std::string(Pattern);433 if (Match.Pattern.size()) {434 Match.Mode = IgnoreCase ? LVMatchMode::NoCase : LVMatchMode::Match;435 Filters.push_back(Match);436 }437 438 return Error::success();439}440 441void LVPatterns::addGenericPatterns(StringSet<> &Patterns) {442 addPatterns(Patterns, GenericMatchInfo);443 if (GenericMatchInfo.size()) {444 options().setSelectGenericPattern();445 options().setSelectExecute();446 }447}448 449void LVPatterns::addOffsetPatterns(const LVOffsetSet &Patterns) {450 llvm::append_range(OffsetMatchInfo, Patterns);451 if (OffsetMatchInfo.size()) {452 options().setSelectOffsetPattern();453 options().setSelectExecute();454 }455}456 457void LVPatterns::addPatterns(StringSet<> &Patterns, LVMatchInfo &Filters) {458 bool IgnoreCase = options().getSelectIgnoreCase();459 bool UseRegex = options().getSelectUseRegex();460 for (const StringSet<>::value_type &Entry : Patterns) {461 StringRef Pattern = Entry.first();462 if (Error Err = createMatchEntry(Filters, Pattern, IgnoreCase, UseRegex))463 consumeError(std::move(Err));464 }465 466 LLVM_DEBUG({467 dbgs() << "\nPattern Information:\n";468 for (LVMatch &Match : Filters)469 dbgs() << "Mode: "470 << (Match.Mode == LVMatchMode::Match ? "Match" : "Regex")471 << " Pattern: '" << Match.Pattern << "'\n";472 });473}474 475void LVPatterns::addElement(LVElement *Element) {476 // Mark any element that matches a given pattern.477 Element->setIsMatched();478 options().setSelectExecute();479 if (options().getReportList())480 getReaderCompileUnit()->addMatched(Element);481 if (options().getReportAnyView()) {482 getReaderCompileUnit()->addMatched(Element->getIsScope()483 ? static_cast<LVScope *>(Element)484 : Element->getParentScope());485 // Mark element as matched.486 if (!Element->getIsScope())487 Element->setHasPattern();488 }489}490 491void LVPatterns::updateReportOptions() {492 if (ElementRequest.size() || LineRequest.size() || ScopeRequest.size() ||493 SymbolRequest.size() || TypeRequest.size()) {494 options().setSelectGenericKind();495 options().setSelectExecute();496 }497 498 // If we have selected requests and there are no specified report options,499 // assume the 'details' option.500 if (options().getSelectExecute() && !options().getReportExecute()) {501 options().setReportExecute();502 options().setReportList();503 }504}505 506// Match a general pattern.507bool LVPatterns::matchPattern(StringRef Input, const LVMatchInfo &MatchInfo) {508 bool Matched = false;509 // Do not match an empty 'Input'.510 if (Input.empty())511 return Matched;512 // Traverse all match specifications.513 for (const LVMatch &Match : MatchInfo) {514 switch (Match.Mode) {515 case LVMatchMode::Match:516 Matched = Input == Match.Pattern;517 break;518 case LVMatchMode::NoCase:519 Matched = Input.equals_insensitive(Match.Pattern);520 break;521 case LVMatchMode::Regex:522 Matched = Match.RE->match(Input);523 break;524 default:525 break;526 }527 // Return if we have a match.528 if (Matched)529 return true;530 }531 return Matched;532}533 534bool LVPatterns::printElement(const LVLine *Line) const {535 return (options().getPrintLines() && Line->getIsLineDebug()) ||536 (options().getPrintInstructions() && Line->getIsLineAssembler());537}538 539bool LVPatterns::printObject(const LVLocation *Location) const {540 if (options().getAttributeAll())541 return true;542 bool DoPrint = options().getAttributeAnyLocation();543 // Consider the case of filler locations.544 if (DoPrint && Location && Location->getIsGapEntry())545 DoPrint = options().getAttributeGaps();546 return DoPrint;547}548 549bool LVPatterns::printElement(const LVScope *Scope) const {550 // A scope will be printed depending on the following rules:551 // - Request to print scopes.552 // - Request to print any of its children.553 // - If the scope is Root or CompileUnit:554 // Request to print summary, sizes or warnings.555 return options().getPrintScopes() ||556 (options().getPrintSymbols() && Scope->getHasSymbols()) ||557 (options().getPrintAnyLine() && Scope->getHasLines()) ||558 (options().getPrintTypes() && Scope->getHasTypes()) ||559 ((options().getPrintSizesSummary() || options().getPrintWarnings()) &&560 (Scope->getIsRoot() || Scope->getIsCompileUnit()));561}562 563bool LVPatterns::printElement(const LVSymbol *Symbol) const {564 // Print compiler generated symbols only if command line option.565 if (Symbol->getIsArtificial())566 return options().getAttributeGenerated() && options().getPrintSymbols();567 return options().getPrintSymbols();568}569 570bool LVPatterns::printElement(const LVType *Type) const {571 // Print array subranges only if print types is requested.572 if (Type->getIsSubrange())573 return options().getAttributeSubrange() && options().getPrintTypes();574 return options().getPrintTypes();575}576 577void LVPatterns::print(raw_ostream &OS) const {578 OS << "LVPatterns\n";579 LLVM_DEBUG(dbgs() << "Print Patterns\n");580}581