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