xref: /freebsd-src/contrib/llvm-project/llvm/lib/ProfileData/SymbolRemappingReader.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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.
read(MemoryBuffer & B)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