1 //===- SymbolRemappingReader.cpp - Read symbol remapping file -------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains definitions needed for reading and applying symbol
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ProfileData/SymbolRemappingReader.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/Support/LineIterator.h"
18 #include "llvm/Support/MemoryBuffer.h"
22 char SymbolRemappingParseError::ID
;
24 /// Load a set of name remappings from a text file.
26 /// See the documentation at the top of the file for an explanation of
27 /// the expected format.
28 Error
SymbolRemappingReader::read(MemoryBuffer
&B
) {
29 line_iterator
LineIt(B
, /*SkipBlanks=*/true, '#');
31 auto ReportError
= [&](Twine Msg
) {
32 return llvm::make_error
<SymbolRemappingParseError
>(
33 B
.getBufferIdentifier(), LineIt
.line_number(), Msg
);
36 for (; !LineIt
.is_at_eof(); ++LineIt
) {
37 StringRef Line
= *LineIt
;
38 Line
= Line
.ltrim(' ');
39 // line_iterator only detects comments starting in column 1.
40 if (Line
.starts_with("#") || Line
.empty())
43 SmallVector
<StringRef
, 4> Parts
;
44 Line
.split(Parts
, ' ', /*MaxSplits*/-1, /*KeepEmpty*/false);
46 if (Parts
.size() != 3)
47 return ReportError("Expected 'kind mangled_name mangled_name', "
48 "found '" + Line
+ "'");
50 using FK
= ItaniumManglingCanonicalizer::FragmentKind
;
51 std::optional
<FK
> FragmentKind
= StringSwitch
<std::optional
<FK
>>(Parts
[0])
52 .Case("name", FK::Name
)
53 .Case("type", FK::Type
)
54 .Case("encoding", FK::Encoding
)
55 .Default(std::nullopt
);
57 return ReportError("Invalid kind, expected 'name', 'type', or 'encoding',"
58 " found '" + Parts
[0] + "'");
60 using EE
= ItaniumManglingCanonicalizer::EquivalenceError
;
61 switch (Canonicalizer
.addEquivalence(*FragmentKind
, Parts
[1], Parts
[2])) {
65 case EE::ManglingAlreadyUsed
:
66 return ReportError("Manglings '" + Parts
[1] + "' and '" + Parts
[2] + "' "
67 "have both been used in prior remappings. Move this "
68 "remapping earlier in the file.");
70 case EE::InvalidFirstMangling
:
71 return ReportError("Could not demangle '" + Parts
[1] + "' "
72 "as a <" + Parts
[0] + ">; invalid mangling?");
74 case EE::InvalidSecondMangling
:
75 return ReportError("Could not demangle '" + Parts
[2] + "' "
76 "as a <" + Parts
[0] + ">; invalid mangling?");
80 return Error::success();