aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp')
-rw-r--r--llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp579
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");
+}