1327f0550SRichard Smith //===- SymbolRemappingReader.cpp - Read symbol remapping file -------------===//
2327f0550SRichard Smith //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6327f0550SRichard Smith //
7327f0550SRichard Smith //===----------------------------------------------------------------------===//
8327f0550SRichard Smith //
9327f0550SRichard Smith // This file contains definitions needed for reading and applying symbol
10327f0550SRichard Smith // remapping files.
11327f0550SRichard Smith //
12327f0550SRichard Smith //===----------------------------------------------------------------------===//
13327f0550SRichard Smith
14327f0550SRichard Smith #include "llvm/Support/SymbolRemappingReader.h"
15327f0550SRichard Smith #include "llvm/ADT/StringSwitch.h"
16327f0550SRichard Smith #include "llvm/ADT/Twine.h"
17327f0550SRichard Smith #include "llvm/Support/LineIterator.h"
18*75e164f6Sserge-sans-paille #include "llvm/Support/MemoryBuffer.h"
19327f0550SRichard Smith
20327f0550SRichard Smith using namespace llvm;
21327f0550SRichard Smith
22327f0550SRichard Smith char SymbolRemappingParseError::ID;
23327f0550SRichard Smith
24327f0550SRichard Smith /// Load a set of name remappings from a text file.
25327f0550SRichard Smith ///
26327f0550SRichard Smith /// See the documentation at the top of the file for an explanation of
27327f0550SRichard Smith /// the expected format.
read(MemoryBuffer & B)28327f0550SRichard Smith Error SymbolRemappingReader::read(MemoryBuffer &B) {
29327f0550SRichard Smith line_iterator LineIt(B, /*SkipBlanks=*/true, '#');
30327f0550SRichard Smith
31327f0550SRichard Smith auto ReportError = [&](Twine Msg) {
32327f0550SRichard Smith return llvm::make_error<SymbolRemappingParseError>(
33327f0550SRichard Smith B.getBufferIdentifier(), LineIt.line_number(), Msg);
34327f0550SRichard Smith };
35327f0550SRichard Smith
36327f0550SRichard Smith for (; !LineIt.is_at_eof(); ++LineIt) {
37327f0550SRichard Smith StringRef Line = *LineIt;
38327f0550SRichard Smith Line = Line.ltrim(' ');
39327f0550SRichard Smith // line_iterator only detects comments starting in column 1.
40327f0550SRichard Smith if (Line.startswith("#") || Line.empty())
41327f0550SRichard Smith continue;
42327f0550SRichard Smith
43327f0550SRichard Smith SmallVector<StringRef, 4> Parts;
44327f0550SRichard Smith Line.split(Parts, ' ', /*MaxSplits*/-1, /*KeepEmpty*/false);
45327f0550SRichard Smith
46327f0550SRichard Smith if (Parts.size() != 3)
47327f0550SRichard Smith return ReportError("Expected 'kind mangled_name mangled_name', "
48327f0550SRichard Smith "found '" + Line + "'");
49327f0550SRichard Smith
50327f0550SRichard Smith using FK = ItaniumManglingCanonicalizer::FragmentKind;
51327f0550SRichard Smith Optional<FK> FragmentKind = StringSwitch<Optional<FK>>(Parts[0])
52327f0550SRichard Smith .Case("name", FK::Name)
53327f0550SRichard Smith .Case("type", FK::Type)
54327f0550SRichard Smith .Case("encoding", FK::Encoding)
55327f0550SRichard Smith .Default(None);
56327f0550SRichard Smith if (!FragmentKind)
57327f0550SRichard Smith return ReportError("Invalid kind, expected 'name', 'type', or 'encoding',"
58327f0550SRichard Smith " found '" + Parts[0] + "'");
59327f0550SRichard Smith
60327f0550SRichard Smith using EE = ItaniumManglingCanonicalizer::EquivalenceError;
61327f0550SRichard Smith switch (Canonicalizer.addEquivalence(*FragmentKind, Parts[1], Parts[2])) {
62327f0550SRichard Smith case EE::Success:
63327f0550SRichard Smith break;
64327f0550SRichard Smith
65327f0550SRichard Smith case EE::ManglingAlreadyUsed:
66327f0550SRichard Smith return ReportError("Manglings '" + Parts[1] + "' and '" + Parts[2] + "' "
67327f0550SRichard Smith "have both been used in prior remappings. Move this "
68327f0550SRichard Smith "remapping earlier in the file.");
69327f0550SRichard Smith
70327f0550SRichard Smith case EE::InvalidFirstMangling:
71327f0550SRichard Smith return ReportError("Could not demangle '" + Parts[1] + "' "
72327f0550SRichard Smith "as a <" + Parts[0] + ">; invalid mangling?");
73327f0550SRichard Smith
74327f0550SRichard Smith case EE::InvalidSecondMangling:
75327f0550SRichard Smith return ReportError("Could not demangle '" + Parts[2] + "' "
76327f0550SRichard Smith "as a <" + Parts[0] + ">; invalid mangling?");
77327f0550SRichard Smith }
78327f0550SRichard Smith }
79327f0550SRichard Smith
80327f0550SRichard Smith return Error::success();
81327f0550SRichard Smith }
82