1327f0550SRichard Smith //===- unittests/Support/SymbolRemappingReaderTest.cpp --------------------===//
2327f0550SRichard Smith //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6327f0550SRichard Smith //
7327f0550SRichard Smith //===----------------------------------------------------------------------===//
8327f0550SRichard Smith 
9327f0550SRichard Smith #include "llvm/Support/SymbolRemappingReader.h"
10327f0550SRichard Smith #include "llvm/Support/MemoryBuffer.h"
11327f0550SRichard Smith #include "gtest/gtest.h"
12327f0550SRichard Smith 
13327f0550SRichard Smith using namespace llvm;
14327f0550SRichard Smith 
15327f0550SRichard Smith namespace {
16327f0550SRichard Smith class SymbolRemappingReaderTest : public testing::Test {
17327f0550SRichard Smith public:
18327f0550SRichard Smith   std::unique_ptr<MemoryBuffer> Buffer;
19327f0550SRichard Smith   SymbolRemappingReader Reader;
20327f0550SRichard Smith 
readWithErrors(StringRef Text,StringRef BufferName)21327f0550SRichard Smith   std::string readWithErrors(StringRef Text, StringRef BufferName) {
22327f0550SRichard Smith     Buffer = MemoryBuffer::getMemBuffer(Text, BufferName);
23327f0550SRichard Smith     Error E = Reader.read(*Buffer);
24327f0550SRichard Smith     EXPECT_TRUE((bool)E);
25327f0550SRichard Smith     return toString(std::move(E));
26327f0550SRichard Smith   }
27327f0550SRichard Smith 
read(StringRef Text,StringRef BufferName)28327f0550SRichard Smith   void read(StringRef Text, StringRef BufferName) {
29327f0550SRichard Smith     Buffer = MemoryBuffer::getMemBuffer(Text, BufferName);
30327f0550SRichard Smith     Error E = Reader.read(*Buffer);
31327f0550SRichard Smith     EXPECT_FALSE((bool)E);
32327f0550SRichard Smith   }
33327f0550SRichard Smith };
34327f0550SRichard Smith } // unnamed namespace
35327f0550SRichard Smith 
TEST_F(SymbolRemappingReaderTest,ParseErrors)36327f0550SRichard Smith TEST_F(SymbolRemappingReaderTest, ParseErrors) {
37327f0550SRichard Smith   EXPECT_EQ(readWithErrors("error", "foo.map"),
38327f0550SRichard Smith             "foo.map:1: Expected 'kind mangled_name mangled_name', "
39327f0550SRichard Smith             "found 'error'");
40327f0550SRichard Smith 
41327f0550SRichard Smith   EXPECT_EQ(readWithErrors("error m1 m2", "foo.map"),
42327f0550SRichard Smith             "foo.map:1: Invalid kind, expected 'name', 'type', or 'encoding', "
43327f0550SRichard Smith             "found 'error'");
44327f0550SRichard Smith }
45327f0550SRichard Smith 
TEST_F(SymbolRemappingReaderTest,DemanglingErrors)46327f0550SRichard Smith TEST_F(SymbolRemappingReaderTest, DemanglingErrors) {
47327f0550SRichard Smith   EXPECT_EQ(readWithErrors("type i banana", "foo.map"),
48327f0550SRichard Smith             "foo.map:1: Could not demangle 'banana' as a <type>; "
49327f0550SRichard Smith             "invalid mangling?");
50327f0550SRichard Smith   EXPECT_EQ(readWithErrors("name i 1X", "foo.map"),
51327f0550SRichard Smith             "foo.map:1: Could not demangle 'i' as a <name>; "
52327f0550SRichard Smith             "invalid mangling?");
53327f0550SRichard Smith   EXPECT_EQ(readWithErrors("name 1X 1fv", "foo.map"),
54327f0550SRichard Smith             "foo.map:1: Could not demangle '1fv' as a <name>; "
55327f0550SRichard Smith             "invalid mangling?");
56327f0550SRichard Smith   EXPECT_EQ(readWithErrors("encoding 1fv 1f1gE", "foo.map"),
57327f0550SRichard Smith             "foo.map:1: Could not demangle '1f1gE' as a <encoding>; "
58327f0550SRichard Smith             "invalid mangling?");
59327f0550SRichard Smith }
60327f0550SRichard Smith 
TEST_F(SymbolRemappingReaderTest,BadMappingOrder)61327f0550SRichard Smith TEST_F(SymbolRemappingReaderTest, BadMappingOrder) {
62327f0550SRichard Smith   StringRef Map = R"(
63327f0550SRichard Smith     # N::foo == M::bar
64327f0550SRichard Smith     name N1N3fooE N1M3barE
65327f0550SRichard Smith 
66327f0550SRichard Smith     # N:: == M::
67327f0550SRichard Smith     name 1N 1M
68327f0550SRichard Smith   )";
69327f0550SRichard Smith   EXPECT_EQ(readWithErrors(Map, "foo.map"),
70327f0550SRichard Smith             "foo.map:6: Manglings '1N' and '1M' have both been used in prior "
71327f0550SRichard Smith             "remappings. Move this remapping earlier in the file.");
72327f0550SRichard Smith }
73327f0550SRichard Smith 
TEST_F(SymbolRemappingReaderTest,RemappingsAdded)74327f0550SRichard Smith TEST_F(SymbolRemappingReaderTest, RemappingsAdded) {
75327f0550SRichard Smith   StringRef Map = R"(
76327f0550SRichard Smith     # A::foo == B::bar
77327f0550SRichard Smith     name N1A3fooE N1B3barE
78327f0550SRichard Smith 
79327f0550SRichard Smith     # int == long
80327f0550SRichard Smith     type i l
81327f0550SRichard Smith 
82327f0550SRichard Smith     # void f<int>() = void g<int>()
83327f0550SRichard Smith     encoding 1fIiEvv 1gIiEvv
84327f0550SRichard Smith   )";
85327f0550SRichard Smith 
86327f0550SRichard Smith   read(Map, "foo.map");
87327f0550SRichard Smith   auto Key = Reader.insert("_ZN1B3bar3bazIiEEvv");
88327f0550SRichard Smith   EXPECT_NE(Key, SymbolRemappingReader::Key());
89327f0550SRichard Smith   EXPECT_EQ(Key, Reader.lookup("_ZN1A3foo3bazIlEEvv"));
90327f0550SRichard Smith   EXPECT_NE(Key, Reader.lookup("_ZN1C3foo3bazIlEEvv"));
91327f0550SRichard Smith 
92327f0550SRichard Smith   Key = Reader.insert("_Z1fIiEvv");
93327f0550SRichard Smith   EXPECT_NE(Key, SymbolRemappingReader::Key());
94327f0550SRichard Smith   EXPECT_EQ(Key, Reader.lookup("_Z1gIlEvv"));
95327f0550SRichard Smith }
96