106c3fb27SDimitry Andric //===- SymbolRemappingReader.cpp - Read symbol remapping file -------------===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric // 906c3fb27SDimitry Andric // This file contains definitions needed for reading and applying symbol 1006c3fb27SDimitry Andric // remapping files. 1106c3fb27SDimitry Andric // 1206c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 1306c3fb27SDimitry Andric 1406c3fb27SDimitry Andric #include "llvm/ProfileData/SymbolRemappingReader.h" 1506c3fb27SDimitry Andric #include "llvm/ADT/StringSwitch.h" 1606c3fb27SDimitry Andric #include "llvm/ADT/Twine.h" 1706c3fb27SDimitry Andric #include "llvm/Support/LineIterator.h" 1806c3fb27SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 1906c3fb27SDimitry Andric 2006c3fb27SDimitry Andric using namespace llvm; 2106c3fb27SDimitry Andric 2206c3fb27SDimitry Andric char SymbolRemappingParseError::ID; 2306c3fb27SDimitry Andric 2406c3fb27SDimitry Andric /// Load a set of name remappings from a text file. 2506c3fb27SDimitry Andric /// 2606c3fb27SDimitry Andric /// See the documentation at the top of the file for an explanation of 2706c3fb27SDimitry Andric /// the expected format. 2806c3fb27SDimitry Andric Error SymbolRemappingReader::read(MemoryBuffer &B) { 2906c3fb27SDimitry Andric line_iterator LineIt(B, /*SkipBlanks=*/true, '#'); 3006c3fb27SDimitry Andric 3106c3fb27SDimitry Andric auto ReportError = [&](Twine Msg) { 3206c3fb27SDimitry Andric return llvm::make_error<SymbolRemappingParseError>( 3306c3fb27SDimitry Andric B.getBufferIdentifier(), LineIt.line_number(), Msg); 3406c3fb27SDimitry Andric }; 3506c3fb27SDimitry Andric 3606c3fb27SDimitry Andric for (; !LineIt.is_at_eof(); ++LineIt) { 3706c3fb27SDimitry Andric StringRef Line = *LineIt; 3806c3fb27SDimitry Andric Line = Line.ltrim(' '); 3906c3fb27SDimitry Andric // line_iterator only detects comments starting in column 1. 40*5f757f3fSDimitry Andric if (Line.starts_with("#") || Line.empty()) 4106c3fb27SDimitry Andric continue; 4206c3fb27SDimitry Andric 4306c3fb27SDimitry Andric SmallVector<StringRef, 4> Parts; 4406c3fb27SDimitry Andric Line.split(Parts, ' ', /*MaxSplits*/-1, /*KeepEmpty*/false); 4506c3fb27SDimitry Andric 4606c3fb27SDimitry Andric if (Parts.size() != 3) 4706c3fb27SDimitry Andric return ReportError("Expected 'kind mangled_name mangled_name', " 4806c3fb27SDimitry Andric "found '" + Line + "'"); 4906c3fb27SDimitry Andric 5006c3fb27SDimitry Andric using FK = ItaniumManglingCanonicalizer::FragmentKind; 5106c3fb27SDimitry Andric std::optional<FK> FragmentKind = StringSwitch<std::optional<FK>>(Parts[0]) 5206c3fb27SDimitry Andric .Case("name", FK::Name) 5306c3fb27SDimitry Andric .Case("type", FK::Type) 5406c3fb27SDimitry Andric .Case("encoding", FK::Encoding) 5506c3fb27SDimitry Andric .Default(std::nullopt); 5606c3fb27SDimitry Andric if (!FragmentKind) 5706c3fb27SDimitry Andric return ReportError("Invalid kind, expected 'name', 'type', or 'encoding'," 5806c3fb27SDimitry Andric " found '" + Parts[0] + "'"); 5906c3fb27SDimitry Andric 6006c3fb27SDimitry Andric using EE = ItaniumManglingCanonicalizer::EquivalenceError; 6106c3fb27SDimitry Andric switch (Canonicalizer.addEquivalence(*FragmentKind, Parts[1], Parts[2])) { 6206c3fb27SDimitry Andric case EE::Success: 6306c3fb27SDimitry Andric break; 6406c3fb27SDimitry Andric 6506c3fb27SDimitry Andric case EE::ManglingAlreadyUsed: 6606c3fb27SDimitry Andric return ReportError("Manglings '" + Parts[1] + "' and '" + Parts[2] + "' " 6706c3fb27SDimitry Andric "have both been used in prior remappings. Move this " 6806c3fb27SDimitry Andric "remapping earlier in the file."); 6906c3fb27SDimitry Andric 7006c3fb27SDimitry Andric case EE::InvalidFirstMangling: 7106c3fb27SDimitry Andric return ReportError("Could not demangle '" + Parts[1] + "' " 7206c3fb27SDimitry Andric "as a <" + Parts[0] + ">; invalid mangling?"); 7306c3fb27SDimitry Andric 7406c3fb27SDimitry Andric case EE::InvalidSecondMangling: 7506c3fb27SDimitry Andric return ReportError("Could not demangle '" + Parts[2] + "' " 7606c3fb27SDimitry Andric "as a <" + Parts[0] + ">; invalid mangling?"); 7706c3fb27SDimitry Andric } 7806c3fb27SDimitry Andric } 7906c3fb27SDimitry Andric 8006c3fb27SDimitry Andric return Error::success(); 8106c3fb27SDimitry Andric } 82