Files
swift-mirror/unittests/Remangler/RemangleTest.cpp
Adrian Prantl ef83539c58 Add unittests for the remangler, particularly to cover error handling.
We currently don't have any tests for remangler error handling, because in
asserts builds it asserts. This patch adds a flag that only exists in !NDEBUG
builds to turn off assertions when inside the unit tests.
2022-05-13 17:55:38 -07:00

128 lines
4.6 KiB
C++

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "swift/Demangling/Demangle.h"
#include "swift/Demangling/Demangler.h"
#include "swift/Strings.h"
#include "llvm/ADT/StringRef.h"
#include "gtest/gtest.h"
/// Helper class to conveniently construct demangle tree hierarchies.
class NodeBuilder {
using NodePointer = swift::Demangle::NodePointer;
using Kind = swift::Demangle::Node::Kind;
swift::Demangle::Demangler &m_dem;
public:
NodeBuilder(swift::Demangle::Demangler &dem) : m_dem(dem) {
#ifndef NDEBUG
m_dem.disableAssertionsForUnitTest = true;
#endif
}
NodePointer Node(Kind kind, StringRef text) {
return m_dem.createNode(kind, text);
}
NodePointer NodeWithIndex(Kind kind, swift::Demangle::Node::IndexType index) {
return m_dem.createNode(kind, index);
}
NodePointer Node(Kind kind, NodePointer child0 = nullptr,
NodePointer child1 = nullptr,
NodePointer child2 = nullptr,
NodePointer child3 = nullptr) {
NodePointer node = m_dem.createNode(kind);
if (child0)
node->addChild(child0, m_dem);
if (child1)
node->addChild(child1, m_dem);
if (child2)
node->addChild(child2, m_dem);
if (child3)
node->addChild(child3, m_dem);
return node;
}
NodePointer IntType() {
return Node(Node::Kind::Type,
Node(Node::Kind::Structure,
Node(Node::Kind::Module, swift::STDLIB_NAME),
Node(Node::Kind::Identifier, "Int")));
}
NodePointer GlobalTypeMangling(NodePointer type) {
assert(type && type->getKind() == Node::Kind::Type);
return Node(Node::Kind::Global, Node(Node::Kind::TypeMangling, type));
}
NodePointer GlobalType(NodePointer type) {
assert(type && type->getKind() != Node::Kind::Type &&
type->getKind() != Node::Kind::TypeMangling &&
type->getKind() != Node::Kind::Global);
return GlobalTypeMangling(Node(Node::Kind::Type, type));
}
ManglingErrorOr<StringRef> remangle(NodePointer node) {
return mangleNode(
node,
[](SymbolicReferenceKind, const void *) -> NodePointer {
return nullptr;
},
m_dem);
}
std::string remangleResult(NodePointer node) {
return remangle(node).result().str();
}
bool remangleSuccess(NodePointer node) {
return remangle(node).isSuccess();
}
};
TEST(TestSwiftRemangler, DependentGenericConformanceRequirement) {
using namespace swift::Demangle;
using Kind = swift::Demangle::Node::Kind;
Demangler dem;
NodeBuilder b(dem);
{
// Well-formed.
NodePointer n = b.GlobalType(b.Node(
Kind::DependentGenericType,
b.Node(Kind::DependentGenericType,
b.Node(Kind::DependentGenericSignature,
b.NodeWithIndex(Kind::DependentGenericParamCount, 1),
b.Node(Kind::DependentGenericConformanceRequirement,
b.Node(Kind::Type,
b.Node(Kind::DependentGenericParamType,
b.NodeWithIndex(Kind::Index, 0),
b.NodeWithIndex(Kind::Index, 0))),
b.Node(Kind::Type,
b.Node(Kind::Protocol,
b.Node(Kind::Module, "M"),
b.Node(Kind::Identifier, "B"))))),
b.IntType())));
ASSERT_EQ(b.remangleResult(n), "$sSi1M1BRzluuD");
}
{
// Malformed.
NodePointer n = b.GlobalType(b.Node(
Kind::DependentGenericType,
b.Node(Kind::DependentGenericType,
b.Node(Kind::DependentGenericSignature,
b.NodeWithIndex(Kind::DependentGenericParamCount, 1),
b.Node(Kind::DependentGenericConformanceRequirement,
b.Node(Kind::Type,
b.Node(Kind::DependentGenericParamType,
b.NodeWithIndex(Kind::Index, 0),
b.NodeWithIndex(Kind::Index, 0))))),
b.IntType())));
ASSERT_FALSE(b.remangleSuccess(n));
}
}