1*06c3fb27SDimitry Andric //===- SymbolRemappingReader.cpp - Read symbol remapping file -------------===// 2*06c3fb27SDimitry Andric // 3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06c3fb27SDimitry Andric // 7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 8*06c3fb27SDimitry Andric // 9*06c3fb27SDimitry Andric // This file contains definitions needed for reading and applying symbol 10*06c3fb27SDimitry Andric // remapping files. 11*06c3fb27SDimitry Andric // 12*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 13*06c3fb27SDimitry Andric 14*06c3fb27SDimitry Andric #include "llvm/ProfileData/SymbolRemappingReader.h" 15*06c3fb27SDimitry Andric #include "llvm/ADT/StringSwitch.h" 16*06c3fb27SDimitry Andric #include "llvm/ADT/Twine.h" 17*06c3fb27SDimitry Andric #include "llvm/Support/LineIterator.h" 18*06c3fb27SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 19*06c3fb27SDimitry Andric 20*06c3fb27SDimitry Andric using namespace llvm; 21*06c3fb27SDimitry Andric 22*06c3fb27SDimitry Andric char SymbolRemappingParseError::ID; 23*06c3fb27SDimitry Andric 24*06c3fb27SDimitry Andric /// Load a set of name remappings from a text file. 25*06c3fb27SDimitry Andric /// 26*06c3fb27SDimitry Andric /// See the documentation at the top of the file for an explanation of 27*06c3fb27SDimitry Andric /// the expected format. 28*06c3fb27SDimitry Andric Error SymbolRemappingReader::read(MemoryBuffer &B) { 29*06c3fb27SDimitry Andric line_iterator LineIt(B, /*SkipBlanks=*/true, '#'); 30*06c3fb27SDimitry Andric 31*06c3fb27SDimitry Andric auto ReportError = [&](Twine Msg) { 32*06c3fb27SDimitry Andric return llvm::make_error<SymbolRemappingParseError>( 33*06c3fb27SDimitry Andric B.getBufferIdentifier(), LineIt.line_number(), Msg); 34*06c3fb27SDimitry Andric }; 35*06c3fb27SDimitry Andric 36*06c3fb27SDimitry Andric for (; !LineIt.is_at_eof(); ++LineIt) { 37*06c3fb27SDimitry Andric StringRef Line = *LineIt; 38*06c3fb27SDimitry Andric Line = Line.ltrim(' '); 39*06c3fb27SDimitry Andric // line_iterator only detects comments starting in column 1. 40*06c3fb27SDimitry Andric if (Line.startswith("#") || Line.empty()) 41*06c3fb27SDimitry Andric continue; 42*06c3fb27SDimitry Andric 43*06c3fb27SDimitry Andric SmallVector<StringRef, 4> Parts; 44*06c3fb27SDimitry Andric Line.split(Parts, ' ', /*MaxSplits*/-1, /*KeepEmpty*/false); 45*06c3fb27SDimitry Andric 46*06c3fb27SDimitry Andric if (Parts.size() != 3) 47*06c3fb27SDimitry Andric return ReportError("Expected 'kind mangled_name mangled_name', " 48*06c3fb27SDimitry Andric "found '" + Line + "'"); 49*06c3fb27SDimitry Andric 50*06c3fb27SDimitry Andric using FK = ItaniumManglingCanonicalizer::FragmentKind; 51*06c3fb27SDimitry Andric std::optional<FK> FragmentKind = StringSwitch<std::optional<FK>>(Parts[0]) 52*06c3fb27SDimitry Andric .Case("name", FK::Name) 53*06c3fb27SDimitry Andric .Case("type", FK::Type) 54*06c3fb27SDimitry Andric .Case("encoding", FK::Encoding) 55*06c3fb27SDimitry Andric .Default(std::nullopt); 56*06c3fb27SDimitry Andric if (!FragmentKind) 57*06c3fb27SDimitry Andric return ReportError("Invalid kind, expected 'name', 'type', or 'encoding'," 58*06c3fb27SDimitry Andric " found '" + Parts[0] + "'"); 59*06c3fb27SDimitry Andric 60*06c3fb27SDimitry Andric using EE = ItaniumManglingCanonicalizer::EquivalenceError; 61*06c3fb27SDimitry Andric switch (Canonicalizer.addEquivalence(*FragmentKind, Parts[1], Parts[2])) { 62*06c3fb27SDimitry Andric case EE::Success: 63*06c3fb27SDimitry Andric break; 64*06c3fb27SDimitry Andric 65*06c3fb27SDimitry Andric case EE::ManglingAlreadyUsed: 66*06c3fb27SDimitry Andric return ReportError("Manglings '" + Parts[1] + "' and '" + Parts[2] + "' " 67*06c3fb27SDimitry Andric "have both been used in prior remappings. Move this " 68*06c3fb27SDimitry Andric "remapping earlier in the file."); 69*06c3fb27SDimitry Andric 70*06c3fb27SDimitry Andric case EE::InvalidFirstMangling: 71*06c3fb27SDimitry Andric return ReportError("Could not demangle '" + Parts[1] + "' " 72*06c3fb27SDimitry Andric "as a <" + Parts[0] + ">; invalid mangling?"); 73*06c3fb27SDimitry Andric 74*06c3fb27SDimitry Andric case EE::InvalidSecondMangling: 75*06c3fb27SDimitry Andric return ReportError("Could not demangle '" + Parts[2] + "' " 76*06c3fb27SDimitry Andric "as a <" + Parts[0] + ">; invalid mangling?"); 77*06c3fb27SDimitry Andric } 78*06c3fb27SDimitry Andric } 79*06c3fb27SDimitry Andric 80*06c3fb27SDimitry Andric return Error::success(); 81*06c3fb27SDimitry Andric } 82