diff options
Diffstat (limited to 'llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp new file mode 100644 index 000000000000..265237ee21dc --- /dev/null +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp @@ -0,0 +1,579 @@ +//===-- LVOptions.cpp -----------------------------------------------------===// +// +// 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 implements the LVOptions class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/LogicalView/Core/LVOptions.h" +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Support/Errc.h" + +using namespace llvm; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "Options" + +//===----------------------------------------------------------------------===// +// Options extracted from the command line. +//===----------------------------------------------------------------------===// +static LVOptions Options; +LVOptions *LVOptions::getOptions() { return &Options; } +void LVOptions::setOptions(LVOptions *CmdOptions) { Options = *CmdOptions; } + +void LVOptions::resolveDependencies() { + // Attributes that are classified as standard options. + auto StandardAttributes = [&]() { + // Set the 'standard' attribute to indicate its associated attributes. + setAttributeStandard(); + + setAttributeBase(); + setAttributeCoverage(); + setAttributeDirectories(); + setAttributeDiscriminator(); + setAttributeFilename(); + setAttributeFiles(); + setAttributeFormat(); + setAttributeLevel(); + setAttributeProducer(); + setAttributePublics(); + setAttributeRange(); + setAttributeReference(); + setAttributeZero(); + }; + + // Attributes that are classified as extended options. + auto ExtendedAttributes = [&]() { + // Set the 'extended' attribute to indicate its associated attributes. + setAttributeExtended(); + + setAttributeArgument(); + setAttributeDiscarded(); + setAttributeEncoded(); + setAttributeGaps(); + setAttributeGenerated(); + setAttributeGlobal(); + setAttributeInserted(); + setAttributeLinkage(); + setAttributeLocal(); + setAttributeLocation(); + setAttributeOffset(); + setAttributePathname(); + setAttributeQualified(); + setAttributeQualifier(); + setAttributeRegister(); + setAttributeSubrange(); + setAttributeSystem(); + setAttributeTypename(); + }; + + // '--Attribute=standard' settings. + if (getAttributeStandard()) + StandardAttributes(); + + // '--Attribute=extended' settings. + if (getAttributeExtended()) + ExtendedAttributes(); + + // '--Attribute=all' settings. + if (getAttributeAll()) { + StandardAttributes(); + ExtendedAttributes(); + } + + // '--attribute=pathname' supersedes '--attribute=filename'. + if (getAttributePathname()) + resetAttributeFilename(); + + // Assume '--output=text' as default + if (!getOutputText() && !getOutputJson()) + setOutputText(); + + // '--output=all' settings. + if (getOutputAll()) { + setOutputJson(); + setOutputSplit(); + setOutputText(); + } + + // A view split folder was specified. + if (getOutputFolder().length()) + setOutputSplit(); + + // Always use the full pathname with splitted output. + if (getOutputSplit()) + setAttributePathname(); + + // '--print=elements' settings. + if (getPrintElements()) { + setPrintInstructions(); + setPrintLines(); + setPrintScopes(); + setPrintSymbols(); + setPrintTypes(); + } + + // '--print=all' settings. + if (getPrintAll()) { + setPrintInstructions(); + setPrintLines(); + setPrintScopes(); + setPrintSizes(); + setPrintSymbols(); + setPrintSummary(); + setPrintTypes(); + setPrintWarnings(); + } + + // '--warning=all' settings. + if (getWarningAll()) { + setWarningCoverages(); + setWarningLines(); + setWarningLocations(); + setWarningRanges(); + } + + // '--internal=all' settings. + if (getInternalAll()) { + setInternalCmdline(); + setInternalID(); + setInternalIntegrity(); + setInternalNone(); + setInternalTag(); + } + + // '--compare=all' settings. + if (getCompareAll()) { + setCompareLines(); + setCompareScopes(); + setCompareSymbols(); + setCompareTypes(); + } + + // Compare the scopes if a request for compare symbols, types, lines. + if (getCompareLines() || getCompareSymbols() || getCompareTypes()) + setCompareScopes(); + + // Generic request for comparison. + if (getCompareScopes()) + setCompareExecute(); + + // Print any logical line (debug or instruction). + if (getPrintInstructions() || getPrintLines()) + setPrintAnyLine(); + + // Print any logical element (line, scope, symbol or type). + if (getPrintAnyLine() || getPrintScopes() || getPrintSymbols() || + getPrintTypes()) + setPrintAnyElement(); + + // Print 'sizes' or 'summary'. + if (getPrintSizes() && getPrintSummary()) + setPrintSizesSummary(); + + // Generic request for printing. + if (getPrintAll() || getPrintAnyElement() || getPrintSizesSummary() || + getPrintWarnings()) + setPrintExecute(); + + // '--reports=all' settings. + if (getReportAll()) { + setReportChildren(); + setReportList(); + setReportParents(); + setReportView(); + } + + // '--report=view' is a shortcut for '--report=parents,children'. + if (getReportView()) { + setReportChildren(); + setReportParents(); + } + + // The report will include: Parents or Children. + if (getReportParents() || getReportChildren() || getReportView()) + setReportAnyView(); + + // The report will include: List or Parents or Children. + if (getReportList() || getReportAnyView()) + setReportExecute(); + + // If a view or element comparison has been requested, the following options + // must be set, in order to get a correct compare: + // 1) Sort the CUs, to get a fast compare. + // 2) Encode template instantiations, so the names include template + // parameter information. + // 3) Include qualified types. + // 4) Include any inserted abstract references. + // 5) For added/missing elements add the '+' or '-' tags. + if (getCompareExecute()) { + resetPrintExecute(); + setComparePrint(); + setSortMode(LVSortMode::Line); + setAttributeAdded(); + setAttributeArgument(); + setAttributeEncoded(); + setAttributeInserted(); + setAttributeMissing(); + setAttributeQualified(); + } + + // Enable formatting for printing (indentation, print children). + setPrintFormatting(); + + // These attributes are dependent on the capture of location information. + if (getAttributeCoverage() || getAttributeGaps() || getAttributeRegister()) + setAttributeLocation(); + + // Location information is only relevant when printing symbols. + if (!getPrintSymbols()) { + resetAttributeCoverage(); + resetAttributeGaps(); + resetAttributeLocation(); + resetAttributeRegister(); + } + + // Quick check for printing any element source information. + if (getAttributeFilename() || getAttributePathname()) + setAttributeAnySource(); + + // Quick check for printing any location information. + if (getAttributeLocation() || getAttributeRange()) + setAttributeAnyLocation(); + + if (getAttributeRange() || getPrintAnyLine()) + setGeneralCollectRanges(); + + calculateIndentationSize(); + + // Print collected command line options. + LLVM_DEBUG({ dump(); }); +} + +void LVOptions::calculateIndentationSize() { +#ifndef NDEBUG + if (getInternalID()) { + std::string String = hexSquareString(0); + IndentationSize += String.length(); + } +#endif + if (getCompareExecute() && (getAttributeAdded() || getAttributeMissing())) + ++IndentationSize; + if (getAttributeOffset()) { + std::string String = hexSquareString(0); + IndentationSize += String.length(); + } + if (getAttributeLevel()) { + std::stringstream Stream; + Stream.str(std::string()); + Stream << "[" << std::setfill('0') << std::setw(3) << 0 << "]"; + IndentationSize += Stream.tellp(); + } + if (getAttributeGlobal()) + ++IndentationSize; +} + +// Print the current values for all the options, after the dependencies +// has been resolved. +void LVOptions::print(raw_ostream &OS) const { + // --attribute + OS << "** Attributes **\n" + << "All: " << getAttributeAll() << ", " + << "Argument: " << getAttributeArgument() << ", " + << "Base: " << getAttributeBase() << ", " + << "Coverage: " << getAttributeCoverage() << "\n" + << "Directories: " << getAttributeDirectories() << ", " + << "Discarded: " << getAttributeDiscarded() << ", " + << "Discriminator: " << getAttributeDiscriminator() << ", " + << "Encoded: " << getAttributeEncoded() << "\n" + << "Extended: " << getAttributeExtended() << ", " + << "Filename: " << getAttributeFilename() << ", " + << "Files: " << getAttributeFiles() << ", " + << "Format: " << getAttributeFormat() << "\n" + << "Gaps: " << getAttributeGaps() << ", " + << "Generated: " << getAttributeGenerated() << ", " + << "Global: " << getAttributeGlobal() << ", " + << "Inserted: " << getAttributeInserted() << "\n" + << "Level: " << getAttributeLevel() << ", " + << "Linkage: " << getAttributeLinkage() << ", " + << "Local: " << getAttributeLocal() << ", " + << "Location: " << getAttributeLocation() << "\n" + << "Offset: " << getAttributeOffset() << ", " + << "Pathname: " << getAttributePathname() << ", " + << "Producer: " << getAttributeProducer() << ", " + << "Publics: " << getAttributePublics() << "\n" + << "Qualified: " << getAttributeQualified() << ", " + << "Qualifier: " << getAttributeQualifier() << ", " + << "Range: " << getAttributeRange() << ", " + << "Reference: " << getAttributeReference() << "\n" + << "Register: " << getAttributeRegister() << ", " + << "Standard: " << getAttributeStandard() << ", " + << "Subrange: " << getAttributeSubrange() << ", " + << "System: " << getAttributeSystem() << "\n" + << "Typename: " << getAttributeTypename() << ", " + << "Underlying: " << getAttributeUnderlying() << ", " + << "Zero: " << getAttributeZero() << "\n"; + OS << "Added: " << getAttributeAdded() << ", " + << "AnyLocation: " << getAttributeAnyLocation() << ", " + << "AnySource: " << getAttributeAnySource() << ", " + << "Missing: " << getAttributeMissing() << "\n" + << "\n"; + + // --compare + OS << "** Compare **\n" + << "All: " << getCompareAll() << ", " + << "Lines: " << getCompareLines() << ", " + << "Scopes: " << getCompareScopes() << ", " + << "Symbols: " << getCompareSymbols() << ", " + << "Types: " << getCompareTypes() << "\n"; + OS << "Context: " << getCompareContext() << ", " + << "Execute: " << getCompareExecute() << ", " + << "Print: " << getComparePrint() << "\n" + << "\n"; + + // --print + OS << "** Print **\n" + << "All: " << getPrintAll() << ", " + << "Elements: " << getPrintElements() << ", " + << "Instructions: " << getPrintInstructions() << ", " + << "Lines: " << getPrintLines() << "\n" + << "Scopes: " << getPrintScopes() << ", " + << "Sizes: " << getPrintSizes() << ", " + << "Summary: " << getPrintSummary() << ", " + << "Symbols: " << getPrintSymbols() << "\n" + << "Types: " << getPrintTypes() << ", " + << "Warnings: " << getPrintWarnings() << "\n"; + OS << "AnyElemeny: " << getPrintAnyElement() << ", " + << "AnyLine: " << getPrintAnyLine() << ", " + << "Execute: " << getPrintExecute() << ", " + << "Formatting: " << getPrintFormatting() << "\n" + << "Offset: " << getPrintOffset() << ", " + << "SizesSummary: " << getPrintSizesSummary() << "\n" + << "\n"; + + // --report + OS << "** Report **\n" + << "All: " << getReportAll() << ", " + << "Children: " << getReportChildren() << ", " + << "List: " << getReportList() << ", " + << "Parents: " << getReportParents() << ", " + << "View: " << getReportView() << "\n"; + OS << "AnyView: " << getReportAnyView() << ", " + << "Execute: " << getReportExecute() << "\n" + << "\n"; + + // --select + OS << "** Select **\n" + << "IgnoreCase: " << getSelectIgnoreCase() << ", " + << "UseRegex: " << getSelectUseRegex() << ", " + << "Execute: " << getSelectExecute() << ", " + << "GenericKind: " << getSelectGenericKind() << "\n" + << "GenericPattern: " << getSelectGenericPattern() << ", " + << "OffsetPattern: " << getSelectOffsetPattern() << "\n" + << "\n"; + + // --warning + OS << "** Warning **\n" + << "All: " << getWarningAll() << ", " + << "Coverage: " << getWarningCoverages() << ", " + << "Lines: " << getWarningLines() << ", " + << "Locations: " << getWarningLocations() << ", " + << "Ranges: " << getWarningRanges() << "\n" + << "\n"; + + // --internal + OS << "** Internal **\n" + << "All: " << Options.getInternalAll() << ", " + << "Cmdline: " << Options.getInternalCmdline() << ", " + << "ID: " << Options.getInternalID() << ", " + << "Integrity: " << Options.getInternalIntegrity() << ", " + << "None: " << Options.getInternalNone() << "\n" + << "Tag: " << Options.getInternalTag() << "\n" + << "\n"; +} + +//===----------------------------------------------------------------------===// +// Logical element selection using patterns. +//===----------------------------------------------------------------------===// +LVPatterns *LVPatterns::getPatterns() { + static LVPatterns Patterns; + return &Patterns; +} + +Error LVPatterns::createMatchEntry(LVMatchInfo &Filters, StringRef Pattern, + bool IgnoreCase, bool UseRegex) { + LVMatch Match; + // Process pattern as regular expression. + if (UseRegex) { + Match.Pattern = std::string(Pattern); + if (Pattern.size()) { + Match.RE = std::make_shared<Regex>(Pattern, IgnoreCase ? Regex::IgnoreCase + : Regex::NoFlags); + std::string Error; + if (!Match.RE->isValid(Error)) + return createStringError(errc::invalid_argument, + "Error in regular expression: %s", + Error.c_str()); + + Match.Mode = LVMatchMode::Regex; + Filters.push_back(Match); + return Error::success(); + } + } + + // Process pattern as an exact string match, depending on the case. + Match.Pattern = std::string(Pattern); + if (Match.Pattern.size()) { + Match.Mode = IgnoreCase ? LVMatchMode::NoCase : LVMatchMode::Match; + Filters.push_back(Match); + } + + return Error::success(); +} + +void LVPatterns::addGenericPatterns(StringSet<> &Patterns) { + addPatterns(Patterns, GenericMatchInfo); + if (GenericMatchInfo.size()) { + options().setSelectGenericPattern(); + options().setSelectExecute(); + } +} + +void LVPatterns::addOffsetPatterns(const LVOffsetSet &Patterns) { + for (const LVOffset &Entry : Patterns) + OffsetMatchInfo.push_back(Entry); + if (OffsetMatchInfo.size()) { + options().setSelectOffsetPattern(); + options().setSelectExecute(); + } +} + +void LVPatterns::addPatterns(StringSet<> &Patterns, LVMatchInfo &Filters) { + bool IgnoreCase = options().getSelectIgnoreCase(); + bool UseRegex = options().getSelectUseRegex(); + for (const StringSet<>::value_type &Entry : Patterns) { + StringRef Pattern = Entry.first(); + if (Error Err = createMatchEntry(Filters, Pattern, IgnoreCase, UseRegex)) + consumeError(std::move(Err)); + } + + LLVM_DEBUG({ + dbgs() << "\nPattern Information:\n"; + for (LVMatch &Match : Filters) + dbgs() << "Mode: " + << (Match.Mode == LVMatchMode::Match ? "Match" : "Regex") + << " Pattern: '" << Match.Pattern << "'\n"; + }); +} + +void LVPatterns::addElement(LVElement *Element) { + // Mark any element that matches a given pattern. + Element->setIsMatched(); + options().setSelectExecute(); + if (options().getReportList()) + getReaderCompileUnit()->addMatched(Element); + if (options().getReportAnyView()) { + getReaderCompileUnit()->addMatched(Element->getIsScope() + ? static_cast<LVScope *>(Element) + : Element->getParentScope()); + // Mark element as matched. + if (!Element->getIsScope()) + Element->setHasPattern(); + } +} + +void LVPatterns::updateReportOptions() { + if (ElementRequest.size() || LineRequest.size() || ScopeRequest.size() || + SymbolRequest.size() || TypeRequest.size()) { + options().setSelectGenericKind(); + options().setSelectExecute(); + } + + // If we have selected requests and there are no specified report options, + // assume the 'details' option. + if (options().getSelectExecute() && !options().getReportExecute()) { + options().setReportExecute(); + options().setReportList(); + } +} + +// Match a general pattern. +bool LVPatterns::matchPattern(StringRef Input, const LVMatchInfo &MatchInfo) { + bool Matched = false; + // Do not match an empty 'Input'. + if (Input.empty()) + return Matched; + // Traverse all match specifications. + for (const LVMatch &Match : MatchInfo) { + switch (Match.Mode) { + case LVMatchMode::Match: + Matched = Input.equals(Match.Pattern); + break; + case LVMatchMode::NoCase: + Matched = Input.equals_insensitive(Match.Pattern); + break; + case LVMatchMode::Regex: + Matched = Match.RE->match(Input); + break; + default: + break; + } + // Return if we have a match. + if (Matched) + return true; + } + return Matched; +} + +bool LVPatterns::printElement(const LVLine *Line) const { + return (options().getPrintLines() && Line->getIsLineDebug()) || + (options().getPrintInstructions() && Line->getIsLineAssembler()); +} + +bool LVPatterns::printObject(const LVLocation *Location) const { + if (options().getAttributeAll()) + return true; + bool DoPrint = options().getAttributeAnyLocation(); + // Consider the case of filler locations. + if (DoPrint && Location && Location->getIsGapEntry()) + DoPrint = options().getAttributeGaps(); + return DoPrint; +} + +bool LVPatterns::printElement(const LVScope *Scope) const { + // A scope will be printed depending on the following rules: + // - Request to print scopes. + // - Request to print any of its children. + // - If the scope is Root or CompileUnit: + // Request to print summary, sizes or warnings. + return options().getPrintScopes() || + (options().getPrintSymbols() && Scope->getHasSymbols()) || + (options().getPrintAnyLine() && Scope->getHasLines()) || + (options().getPrintTypes() && Scope->getHasTypes()) || + ((options().getPrintSizesSummary() || options().getPrintWarnings()) && + (Scope->getIsRoot() || Scope->getIsCompileUnit())); +} + +bool LVPatterns::printElement(const LVSymbol *Symbol) const { + // Print compiler generated symbols only if command line option. + if (Symbol->getIsArtificial()) + return options().getAttributeGenerated() && options().getPrintSymbols(); + return options().getPrintSymbols(); +} + +bool LVPatterns::printElement(const LVType *Type) const { + // Print array subranges only if print types is requested. + if (Type->getIsSubrange()) + return options().getAttributeSubrange() && options().getPrintTypes(); + return options().getPrintTypes(); +} + +void LVPatterns::print(raw_ostream &OS) const { + OS << "LVPatterns\n"; + LLVM_DEBUG(dbgs() << "Print Patterns\n"); +} |