diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-09-10 18:53:34 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-09-10 18:53:34 +0000 |
commit | 5bf671d658572f2de62bde5767e63873cb5fc708 (patch) | |
tree | fa9bace9652920533dec17d1e227c3fb3929fa8b | |
parent | e3fb157234c40dfa2746dbb08edd8730cc4b78c4 (diff) |
Vendor import of llvm-project branch release/15.x llvmorg-15.0.0-9-g1c73596d3454.vendor/llvm-project/llvmorg-15.0.0-9-g1c73596d3454
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 5 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h | 30 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp | 302 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 11 | ||||
-rw-r--r-- | llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp | 28 |
7 files changed, 336 insertions, 64 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 5991cf23d5dc..cf6549e2a5bd 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2329,25 +2329,6 @@ private: !PrevToken->MatchingParen) return TT_PointerOrReference; - // For "} &&" - if (PrevToken->is(tok::r_brace) && Tok.is(tok::ampamp)) { - const FormatToken *MatchingLBrace = PrevToken->MatchingParen; - - // We check whether there is a TemplateCloser(">") to indicate it's a - // template or not. If it's not a template, "&&" is likely a reference - // operator. - // struct {} &&ref = {}; - if (!MatchingLBrace) - return TT_PointerOrReference; - FormatToken *BeforeLBrace = MatchingLBrace->getPreviousNonComment(); - if (!BeforeLBrace || BeforeLBrace->isNot(TT_TemplateCloser)) - return TT_PointerOrReference; - - // If it is a template, "&&" is a binary operator. - // enable_if<>{} && ... - return TT_BinaryOperator; - } - if (PrevToken->Tok.isLiteral() || PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true, tok::kw_false, tok::r_brace)) { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0e24237faae5..83081bbf0aa0 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17600,6 +17600,11 @@ static void RemoveNestedImmediateInvocation( DRSet.erase(E); return E; } + ExprResult TransformLambdaExpr(LambdaExpr *E) { + // Do not rebuild lambdas to avoid creating a new type. + // Lambdas have already been processed inside their eval context. + return E; + } bool AlwaysRebuild() { return false; } bool ReplacingOriginal() { return true; } bool AllowSkippingCXXConstructExpr() { diff --git a/llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h b/llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h index 26686143af95..a54f8f5d2db8 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h @@ -26,11 +26,14 @@ namespace llvm { namespace symbolize { +class LLVMSymbolizer; + /// Filter to convert parsed log symbolizer markup elements into human-readable /// text. class MarkupFilter { public: - MarkupFilter(raw_ostream &OS, Optional<bool> ColorsEnabled = llvm::None); + MarkupFilter(raw_ostream &OS, LLVMSymbolizer &Symbolizer, + Optional<bool> ColorsEnabled = llvm::None); /// Filters a line containing symbolizer markup and writes the human-readable /// results to the output stream. @@ -57,6 +60,7 @@ private: uint64_t ModuleRelativeAddr; bool contains(uint64_t Addr) const; + uint64_t getModuleRelativeAddr(uint64_t Addr) const; }; // An informational module line currently being constructed. As many mmap @@ -67,6 +71,15 @@ private: SmallVector<const MMap *> MMaps = {}; }; + // The semantics of a possible program counter value. + enum class PCType { + // The address is a return address and must be adjusted to point to the call + // itself. + ReturnAddress, + // The address is the precise location in the code and needs no adjustment. + PreciseCode, + }; + bool tryContextualElement(const MarkupNode &Node, const SmallVector<MarkupNode> &DeferredNodes); bool tryMMap(const MarkupNode &Element, @@ -83,6 +96,9 @@ private: bool tryPresentation(const MarkupNode &Node); bool trySymbol(const MarkupNode &Node); + bool tryPC(const MarkupNode &Node); + bool tryBackTrace(const MarkupNode &Node); + bool tryData(const MarkupNode &Node); bool trySGR(const MarkupNode &Node); @@ -91,6 +107,9 @@ private: void restoreColor(); void resetColor(); + void printRawElement(const MarkupNode &Element); + void printValue(Twine Value); + Optional<Module> parseModule(const MarkupNode &Element) const; Optional<MMap> parseMMap(const MarkupNode &Element) const; @@ -99,19 +118,26 @@ private: Optional<uint64_t> parseSize(StringRef Str) const; Optional<SmallVector<uint8_t>> parseBuildID(StringRef Str) const; Optional<std::string> parseMode(StringRef Str) const; + Optional<PCType> parsePCType(StringRef Str) const; + Optional<uint64_t> parseFrameNumber(StringRef Str) const; bool checkTag(const MarkupNode &Node) const; bool checkNumFields(const MarkupNode &Element, size_t Size) const; bool checkNumFieldsAtLeast(const MarkupNode &Element, size_t Size) const; + bool checkNumFieldsAtMost(const MarkupNode &Element, size_t Size) const; void reportTypeError(StringRef Str, StringRef TypeName) const; void reportLocation(StringRef::iterator Loc) const; - const MMap *overlappingMMap(const MMap &Map) const; + const MMap *getOverlappingMMap(const MMap &Map) const; + const MMap *getContainingMMap(uint64_t Addr) const; + + uint64_t adjustAddr(uint64_t Addr, PCType Type) const; StringRef lineEnding() const; raw_ostream &OS; + LLVMSymbolizer &Symbolizer; const bool ColorsEnabled; MarkupParser Parser; diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 42a141e8876b..a7f9382478d4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7163,9 +7163,8 @@ static SDValue extractShiftForRotate(SelectionDAG &DAG, SDValue OppShift, SDValue ExtractFrom, SDValue &Mask, const SDLoc &DL) { assert(OppShift && ExtractFrom && "Empty SDValue"); - assert( - (OppShift.getOpcode() == ISD::SHL || OppShift.getOpcode() == ISD::SRL) && - "Existing shift must be valid as a rotate half"); + if (OppShift.getOpcode() != ISD::SHL && OppShift.getOpcode() != ISD::SRL) + return SDValue(); ExtractFrom = stripConstantMask(DAG, ExtractFrom, Mask); diff --git a/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp b/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp index 91a51485026e..d96c0c85d5bd 100644 --- a/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp +++ b/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp @@ -20,11 +20,14 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/Symbolize/Markup.h" +#include "llvm/DebugInfo/Symbolize/Symbolize.h" #include "llvm/Debuginfod/Debuginfod.h" #include "llvm/Demangle/Demangle.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" +#include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" @@ -32,9 +35,11 @@ using namespace llvm; using namespace llvm::symbolize; -MarkupFilter::MarkupFilter(raw_ostream &OS, Optional<bool> ColorsEnabled) - : OS(OS), ColorsEnabled(ColorsEnabled.value_or( - WithColor::defaultAutoDetectFunction()(OS))) {} +MarkupFilter::MarkupFilter(raw_ostream &OS, LLVMSymbolizer &Symbolizer, + Optional<bool> ColorsEnabled) + : OS(OS), Symbolizer(Symbolizer), + ColorsEnabled( + ColorsEnabled.value_or(WithColor::defaultAutoDetectFunction()(OS))) {} void MarkupFilter::filter(StringRef Line) { this->Line = Line; @@ -94,10 +99,10 @@ bool MarkupFilter::tryMMap(const MarkupNode &Node, if (!ParsedMMap) return true; - if (const MMap *M = overlappingMMap(*ParsedMMap)) { + if (const MMap *M = getOverlappingMMap(*ParsedMMap)) { WithColor::error(errs()) - << formatv("overlapping mmap: #{0:x} [{1:x},{2:x})\n", M->Mod->ID, - M->Addr, M->Addr + M->Size); + << formatv("overlapping mmap: #{0:x} [{1:x}-{2:x}]\n", M->Mod->ID, + M->Addr, M->Addr + M->Size - 1); reportLocation(Node.Fields[0].begin()); return true; } @@ -160,18 +165,17 @@ bool MarkupFilter::tryModule(const MarkupNode &Node, filterNode(Node); beginModuleInfoLine(&Module); OS << "; BuildID="; - highlightValue(); - OS << toHex(Module.BuildID, /*LowerCase=*/true); - highlight(); + printValue(toHex(Module.BuildID, /*LowerCase=*/true)); return true; } void MarkupFilter::beginModuleInfoLine(const Module *M) { highlight(); OS << "[[[ELF module"; - highlightValue(); - OS << formatv(" #{0:x} \"{1}\"", M->ID, M->Name); - highlight(); + printValue(formatv(" #{0:x} ", M->ID)); + OS << '"'; + printValue(M->Name); + OS << '"'; MIL = ModuleInfoLine{M}; } @@ -182,14 +186,13 @@ void MarkupFilter::endAnyModuleInfoLine() { return A->Addr < B->Addr; }); for (const MMap *M : MIL->MMaps) { - OS << (M == MIL->MMaps.front() ? ' ' : '-'); - highlightValue(); - OS << formatv("{0:x}", M->Addr); - highlight(); - OS << '('; - highlightValue(); - OS << M->Mode; - highlight(); + OS << (M == MIL->MMaps.front() ? ' ' : ','); + OS << '['; + printValue(formatv("{0:x}", M->Addr)); + OS << '-'; + printValue(formatv("{0:x}", M->Addr + M->Size - 1)); + OS << "]("; + printValue(M->Mode); OS << ')'; } OS << "]]]" << lineEnding(); @@ -210,7 +213,13 @@ void MarkupFilter::filterNode(const MarkupNode &Node) { } bool MarkupFilter::tryPresentation(const MarkupNode &Node) { - return trySymbol(Node); + if (trySymbol(Node)) + return true; + if (tryPC(Node)) + return true; + if (tryBackTrace(Node)) + return true; + return tryData(Node); } bool MarkupFilter::trySymbol(const MarkupNode &Node) { @@ -225,6 +234,172 @@ bool MarkupFilter::trySymbol(const MarkupNode &Node) { return true; } +bool MarkupFilter::tryPC(const MarkupNode &Node) { + if (Node.Tag != "pc") + return false; + if (!checkNumFieldsAtLeast(Node, 1)) + return true; + if (!checkNumFieldsAtMost(Node, 2)) + return true; + + Optional<uint64_t> Addr = parseAddr(Node.Fields[0]); + if (!Addr) + return true; + + // PC addresses that aren't part of a backtrace are assumed to be precise code + // locations. + PCType Type = PCType::PreciseCode; + if (Node.Fields.size() == 2) { + Optional<PCType> ParsedType = parsePCType(Node.Fields[1]); + if (!ParsedType) + return true; + Type = *ParsedType; + } + *Addr = adjustAddr(*Addr, Type); + + const MMap *MMap = getContainingMMap(*Addr); + if (!MMap) { + WithColor::error() << "no mmap covers address\n"; + reportLocation(Node.Fields[0].begin()); + printRawElement(Node); + return true; + } + + Expected<DILineInfo> LI = Symbolizer.symbolizeCode( + MMap->Mod->BuildID, {MMap->getModuleRelativeAddr(*Addr)}); + if (!LI) { + WithColor::defaultErrorHandler(LI.takeError()); + printRawElement(Node); + return true; + } + if (!*LI) { + printRawElement(Node); + return true; + } + + highlight(); + printValue(LI->FunctionName); + OS << '['; + printValue(LI->FileName); + OS << ':'; + printValue(Twine(LI->Line)); + OS << ']'; + restoreColor(); + return true; +} + +bool MarkupFilter::tryBackTrace(const MarkupNode &Node) { + if (Node.Tag != "bt") + return false; + if (!checkNumFieldsAtLeast(Node, 2)) + return true; + if (!checkNumFieldsAtMost(Node, 3)) + return true; + + Optional<uint64_t> FrameNumber = parseFrameNumber(Node.Fields[0]); + if (!FrameNumber) + return true; + + Optional<uint64_t> Addr = parseAddr(Node.Fields[1]); + if (!Addr) + return true; + + // Backtrace addresses are assumed to be return addresses by default. + PCType Type = PCType::ReturnAddress; + if (Node.Fields.size() == 3) { + Optional<PCType> ParsedType = parsePCType(Node.Fields[2]); + if (!ParsedType) + return true; + Type = *ParsedType; + } + *Addr = adjustAddr(*Addr, Type); + + const MMap *MMap = getContainingMMap(*Addr); + if (!MMap) { + WithColor::error() << "no mmap covers address\n"; + reportLocation(Node.Fields[0].begin()); + printRawElement(Node); + return true; + } + uint64_t MRA = MMap->getModuleRelativeAddr(*Addr); + + Expected<DIInliningInfo> II = + Symbolizer.symbolizeInlinedCode(MMap->Mod->BuildID, {MRA}); + if (!II) { + WithColor::defaultErrorHandler(II.takeError()); + printRawElement(Node); + return true; + } + + highlight(); + for (unsigned I = 0, E = II->getNumberOfFrames(); I != E; ++I) { + auto Header = formatv("{0, +6}", formatv("#{0}", FrameNumber)).sstr<16>(); + // Don't highlight the # sign as a value. + size_t NumberIdx = Header.find("#") + 1; + OS << Header.substr(0, NumberIdx); + printValue(Header.substr(NumberIdx)); + if (I == E - 1) { + OS << " "; + } else { + OS << '.'; + printValue(formatv("{0, -2}", I + 1)); + } + printValue(formatv(" {0:x16} ", *Addr)); + + DILineInfo LI = II->getFrame(I); + if (LI) { + printValue(LI.FunctionName); + OS << ' '; + printValue(LI.FileName); + OS << ':'; + printValue(Twine(LI.Line)); + OS << ':'; + printValue(Twine(LI.Column)); + OS << ' '; + } + OS << '('; + printValue(MMap->Mod->Name); + OS << "+"; + printValue(formatv("{0:x}", MRA)); + OS << ')'; + if (I != E - 1) + OS << lineEnding(); + } + restoreColor(); + return true; +} + +bool MarkupFilter::tryData(const MarkupNode &Node) { + if (Node.Tag != "data") + return false; + if (!checkNumFields(Node, 1)) + return true; + Optional<uint64_t> Addr = parseAddr(Node.Fields[0]); + if (!Addr) + return true; + + const MMap *MMap = getContainingMMap(*Addr); + if (!MMap) { + WithColor::error() << "no mmap covers address\n"; + reportLocation(Node.Fields[0].begin()); + printRawElement(Node); + return true; + } + + Expected<DIGlobal> Symbol = Symbolizer.symbolizeData( + MMap->Mod->BuildID, {MMap->getModuleRelativeAddr(*Addr)}); + if (!Symbol) { + WithColor::defaultErrorHandler(Symbol.takeError()); + printRawElement(Node); + return true; + } + + highlight(); + OS << Symbol->Name; + restoreColor(); + return true; +} + bool MarkupFilter::trySGR(const MarkupNode &Node) { if (Node.Text == "\033[0m") { resetColor(); @@ -297,6 +472,24 @@ void MarkupFilter::resetColor() { OS.resetColor(); } +void MarkupFilter::printRawElement(const MarkupNode &Element) { + highlight(); + OS << "[[["; + printValue(Element.Tag); + for (StringRef Field : Element.Fields) { + OS << ':'; + printValue(Field); + } + OS << "]]]"; + restoreColor(); +} + +void MarkupFilter::printValue(Twine Value) { + highlightValue(); + OS << Value; + highlight(); +} + // This macro helps reduce the amount of indirection done through Optional // below, since the usual case upon returning a None Optional is to return None. #define ASSIGN_OR_RETURN_NONE(TYPE, NAME, EXPR) \ @@ -392,6 +585,16 @@ Optional<uint64_t> MarkupFilter::parseSize(StringRef Str) const { return ID; } +// Parse a frame number (%i in the spec). +Optional<uint64_t> MarkupFilter::parseFrameNumber(StringRef Str) const { + uint64_t ID; + if (Str.getAsInteger(10, ID)) { + reportTypeError(Str, "frame number"); + return None; + } + return ID; +} + // Parse a build ID (%x in the spec). Optional<SmallVector<uint8_t>> MarkupFilter::parseBuildID(StringRef Str) const { std::string Bytes; @@ -430,6 +633,17 @@ Optional<std::string> MarkupFilter::parseMode(StringRef Str) const { return Str.lower(); } +Optional<MarkupFilter::PCType> MarkupFilter::parsePCType(StringRef Str) const { + Optional<MarkupFilter::PCType> Type = + StringSwitch<Optional<MarkupFilter::PCType>>(Str) + .Case("ra", MarkupFilter::PCType::ReturnAddress) + .Case("pc", MarkupFilter::PCType::PreciseCode) + .Default(None); + if (!Type) + reportTypeError(Str, "PC type"); + return Type; +} + bool MarkupFilter::checkTag(const MarkupNode &Node) const { if (any_of(Node.Tag, [](char C) { return C < 'a' || C > 'z'; })) { WithColor::error(errs()) << "tags must be all lowercase characters\n"; @@ -442,7 +656,7 @@ bool MarkupFilter::checkTag(const MarkupNode &Node) const { bool MarkupFilter::checkNumFields(const MarkupNode &Element, size_t Size) const { if (Element.Fields.size() != Size) { - WithColor::error(errs()) << "expected " << Size << " fields; found " + WithColor::error(errs()) << "expected " << Size << " field(s); found " << Element.Fields.size() << "\n"; reportLocation(Element.Tag.end()); return false; @@ -454,7 +668,19 @@ bool MarkupFilter::checkNumFieldsAtLeast(const MarkupNode &Element, size_t Size) const { if (Element.Fields.size() < Size) { WithColor::error(errs()) - << "expected at least " << Size << " fields; found " + << "expected at least " << Size << " field(s); found " + << Element.Fields.size() << "\n"; + reportLocation(Element.Tag.end()); + return false; + } + return true; +} + +bool MarkupFilter::checkNumFieldsAtMost(const MarkupNode &Element, + size_t Size) const { + if (Element.Fields.size() > Size) { + WithColor::error(errs()) + << "expected at most " << Size << " field(s); found " << Element.Fields.size() << "\n"; reportLocation(Element.Tag.end()); return false; @@ -479,7 +705,8 @@ void MarkupFilter::reportLocation(StringRef::iterator Loc) const { // Checks for an existing mmap that overlaps the given one and returns a // pointer to one of them. -const MarkupFilter::MMap *MarkupFilter::overlappingMMap(const MMap &Map) const { +const MarkupFilter::MMap * +MarkupFilter::getOverlappingMMap(const MMap &Map) const { // If the given map contains the start of another mmap, they overlap. auto I = MMaps.upper_bound(Map.Addr); if (I != MMaps.end() && Map.contains(I->second.Addr)) @@ -495,6 +722,28 @@ const MarkupFilter::MMap *MarkupFilter::overlappingMMap(const MMap &Map) const { return nullptr; } +// Returns the MMap that contains the given address or nullptr if none. +const MarkupFilter::MMap *MarkupFilter::getContainingMMap(uint64_t Addr) const { + // Find the first mmap starting >= Addr. + auto I = MMaps.lower_bound(Addr); + if (I != MMaps.end() && I->second.contains(Addr)) + return &I->second; + + // The previous mmap is the last one starting < Addr. + if (I == MMaps.begin()) + return nullptr; + --I; + return I->second.contains(Addr) ? &I->second : nullptr; +} + +uint64_t MarkupFilter::adjustAddr(uint64_t Addr, PCType Type) const { + // Decrementing return addresses by one moves them into the call instruction. + // The address doesn't have to be the start of the call instruction, just some + // byte on the inside. Subtracting one avoids needing detailed instruction + // length information here. + return Type == MarkupFilter::PCType::ReturnAddress ? Addr - 1 : Addr; +} + StringRef MarkupFilter::lineEnding() const { return Line.endswith("\r\n") ? "\r\n" : "\n"; } @@ -502,3 +751,8 @@ StringRef MarkupFilter::lineEnding() const { bool MarkupFilter::MMap::contains(uint64_t Addr) const { return this->Addr <= Addr && Addr < this->Addr + Size; } + +// Returns the module-relative address for a given virtual address. +uint64_t MarkupFilter::MMap::getModuleRelativeAddr(uint64_t Addr) const { + return Addr - this->Addr + ModuleRelativeAddr; +} diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp index bf520a560404..c0a94cc758bb 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -4600,9 +4600,16 @@ void AMDGPUTargetLowering::computeKnownBitsForTargetNode( case Intrinsic::amdgcn_mbcnt_hi: { const GCNSubtarget &ST = DAG.getMachineFunction().getSubtarget<GCNSubtarget>(); - // These return at most the wavefront size - 1. + // These return at most the (wavefront size - 1) + src1 + // As long as src1 is an immediate we can calc known bits + KnownBits Src1Known = DAG.computeKnownBits(Op.getOperand(2), Depth + 1); + unsigned Src1ValBits = Src1Known.countMaxActiveBits(); + unsigned MaxActiveBits = std::max(Src1ValBits, ST.getWavefrontSizeLog2()); + // Cater for potential carry + MaxActiveBits += Src1ValBits ? 1 : 0; unsigned Size = Op.getValueType().getSizeInBits(); - Known.Zero.setHighBits(Size - ST.getWavefrontSizeLog2()); + if (MaxActiveBits < Size) + Known.Zero.setHighBits(Size - MaxActiveBits); break; } case Intrinsic::amdgcn_workitem_id_x: diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index 7ec70e42f1c1..34c93be67f80 100644 --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -366,8 +366,8 @@ static SmallVector<uint8_t> parseBuildIDArg(const opt::InputArgList &Args, } // Symbolize markup from stdin and write the result to stdout. -static void filterMarkup(const opt::InputArgList &Args) { - MarkupFilter Filter(outs(), parseColorArg(Args)); +static void filterMarkup(const opt::InputArgList &Args, LLVMSymbolizer &Symbolizer) { + MarkupFilter Filter(outs(), Symbolizer, parseColorArg(Args)); std::string InputString; while (std::getline(std::cin, InputString)) { InputString += '\n'; @@ -437,8 +437,19 @@ int main(int argc, char **argv) { } } + LLVMSymbolizer Symbolizer(Opts); + + // A debuginfod lookup could succeed if a HTTP client is available and at + // least one backing URL is configured. + bool ShouldUseDebuginfodByDefault = + HTTPClient::isAvailable() && + !ExitOnErr(getDefaultDebuginfodUrls()).empty(); + if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod, + ShouldUseDebuginfodByDefault)) + enableDebuginfod(Symbolizer); + if (Args.hasArg(OPT_filter_markup)) { - filterMarkup(Args); + filterMarkup(Args, Symbolizer); return 0; } @@ -458,17 +469,6 @@ int main(int argc, char **argv) { } SmallVector<uint8_t> BuildID = parseBuildIDArg(Args, OPT_build_id_EQ); - LLVMSymbolizer Symbolizer(Opts); - - // A debuginfod lookup could succeed if a HTTP client is available and at - // least one backing URL is configured. - bool ShouldUseDebuginfodByDefault = - HTTPClient::isAvailable() && - !ExitOnErr(getDefaultDebuginfodUrls()).empty(); - if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod, - ShouldUseDebuginfodByDefault)) - enableDebuginfod(Symbolizer); - std::unique_ptr<DIPrinter> Printer; if (Style == OutputStyle::GNU) Printer = std::make_unique<GNUPrinter>(outs(), errs(), Config); |