1343171Sdim//===- SymbolRemappingReader.cpp - Read symbol remapping file -------------===// 2343171Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343171Sdim// 7343171Sdim//===----------------------------------------------------------------------===// 8343171Sdim// 9343171Sdim// This file contains definitions needed for reading and applying symbol 10343171Sdim// remapping files. 11343171Sdim// 12343171Sdim//===----------------------------------------------------------------------===// 13343171Sdim 14343171Sdim#include "llvm/Support/SymbolRemappingReader.h" 15343171Sdim#include "llvm/ADT/StringSwitch.h" 16343171Sdim#include "llvm/ADT/Twine.h" 17343171Sdim#include "llvm/Support/LineIterator.h" 18343171Sdim 19343171Sdimusing namespace llvm; 20343171Sdim 21343171Sdimchar SymbolRemappingParseError::ID; 22343171Sdim 23343171Sdim/// Load a set of name remappings from a text file. 24343171Sdim/// 25343171Sdim/// See the documentation at the top of the file for an explanation of 26343171Sdim/// the expected format. 27343171SdimError SymbolRemappingReader::read(MemoryBuffer &B) { 28343171Sdim line_iterator LineIt(B, /*SkipBlanks=*/true, '#'); 29343171Sdim 30343171Sdim auto ReportError = [&](Twine Msg) { 31343171Sdim return llvm::make_error<SymbolRemappingParseError>( 32343171Sdim B.getBufferIdentifier(), LineIt.line_number(), Msg); 33343171Sdim }; 34343171Sdim 35343171Sdim for (; !LineIt.is_at_eof(); ++LineIt) { 36343171Sdim StringRef Line = *LineIt; 37343171Sdim Line = Line.ltrim(' '); 38343171Sdim // line_iterator only detects comments starting in column 1. 39343171Sdim if (Line.startswith("#") || Line.empty()) 40343171Sdim continue; 41343171Sdim 42343171Sdim SmallVector<StringRef, 4> Parts; 43343171Sdim Line.split(Parts, ' ', /*MaxSplits*/-1, /*KeepEmpty*/false); 44343171Sdim 45343171Sdim if (Parts.size() != 3) 46343171Sdim return ReportError("Expected 'kind mangled_name mangled_name', " 47343171Sdim "found '" + Line + "'"); 48343171Sdim 49343171Sdim using FK = ItaniumManglingCanonicalizer::FragmentKind; 50343171Sdim Optional<FK> FragmentKind = StringSwitch<Optional<FK>>(Parts[0]) 51343171Sdim .Case("name", FK::Name) 52343171Sdim .Case("type", FK::Type) 53343171Sdim .Case("encoding", FK::Encoding) 54343171Sdim .Default(None); 55343171Sdim if (!FragmentKind) 56343171Sdim return ReportError("Invalid kind, expected 'name', 'type', or 'encoding'," 57343171Sdim " found '" + Parts[0] + "'"); 58343171Sdim 59343171Sdim using EE = ItaniumManglingCanonicalizer::EquivalenceError; 60343171Sdim switch (Canonicalizer.addEquivalence(*FragmentKind, Parts[1], Parts[2])) { 61343171Sdim case EE::Success: 62343171Sdim break; 63343171Sdim 64343171Sdim case EE::ManglingAlreadyUsed: 65343171Sdim return ReportError("Manglings '" + Parts[1] + "' and '" + Parts[2] + "' " 66343171Sdim "have both been used in prior remappings. Move this " 67343171Sdim "remapping earlier in the file."); 68343171Sdim 69343171Sdim case EE::InvalidFirstMangling: 70343171Sdim return ReportError("Could not demangle '" + Parts[1] + "' " 71343171Sdim "as a <" + Parts[0] + ">; invalid mangling?"); 72343171Sdim 73343171Sdim case EE::InvalidSecondMangling: 74343171Sdim return ReportError("Could not demangle '" + Parts[2] + "' " 75343171Sdim "as a <" + Parts[0] + ">; invalid mangling?"); 76343171Sdim } 77343171Sdim } 78343171Sdim 79343171Sdim return Error::success(); 80343171Sdim} 81