void Remangler::mangleSILBoxTypeWithLayout(Node *node) { assert(node->getKind() == Node::Kind::SILBoxTypeWithLayout); assert(node->getNumChildren() == 1 || node->getNumChildren() == 3); Out << "XB"; auto layout = node->getChild(0); assert(layout->getKind() == Node::Kind::SILBoxLayout); NodePointer genericArgs = nullptr; if (node->getNumChildren() == 3) { NodePointer signature = node->getChild(1); assert(signature->getKind() == Node::Kind::DependentGenericSignature); genericArgs = node->getChild(2); assert(genericArgs->getKind() == Node::Kind::TypeList); Out << 'G'; mangleDependentGenericSignature(signature); } mangleSILBoxLayout(layout); if (genericArgs) { for (unsigned i = 0; i < genericArgs->getNumChildren(); ++i) { auto type = genericArgs->getChild(i); assert(genericArgs->getKind() == Node::Kind::Type); mangleType(type); } Out << '_'; } }
bool Context::isThunkSymbol(llvm::StringRef MangledName) { if (isMangledName(MangledName)) { // First do a quick check if (MangledName.endswith("TA") || // partial application forwarder MangledName.endswith("Ta") || // ObjC partial application forwarder MangledName.endswith("To") || // swift-as-ObjC thunk MangledName.endswith("TO") || // ObjC-as-swift thunk MangledName.endswith("TR") || // reabstraction thunk helper function MangledName.endswith("Tr") || // reabstraction thunk MangledName.endswith("TW") || // protocol witness thunk MangledName.endswith("fC")) { // allocating constructor // To avoid false positives, we need to fully demangle the symbol. NodePointer Nd = D->demangleSymbol(MangledName); if (!Nd || Nd->getKind() != Node::Kind::Global || Nd->getNumChildren() == 0) return false; switch (Nd->getFirstChild()->getKind()) { case Node::Kind::ObjCAttribute: case Node::Kind::NonObjCAttribute: case Node::Kind::PartialApplyObjCForwarder: case Node::Kind::PartialApplyForwarder: case Node::Kind::ReabstractionThunkHelper: case Node::Kind::ReabstractionThunk: case Node::Kind::ProtocolWitness: case Node::Kind::Allocator: return true; default: break; } } return false; } if (MangledName.startswith("_T")) { // Old mangling. StringRef Remaining = MangledName.substr(2); if (Remaining.startswith("To") || // swift-as-ObjC thunk Remaining.startswith("TO") || // ObjC-as-swift thunk Remaining.startswith("PA_") || // partial application forwarder Remaining.startswith("PAo_")) { // ObjC partial application forwarder return true; } } return false; }
NodePointer Demangle::stripGenericArgsFromContextNode(NodePointer node, NodeFactory &factory) { switch (node->getKind()) { case Demangle::Node::Kind::BoundGenericClass: case Demangle::Node::Kind::BoundGenericEnum: case Demangle::Node::Kind::BoundGenericStructure: case Demangle::Node::Kind::BoundGenericOtherNominalType: // Bound generic types have a 'Type' node under them, whose child is // the non-generic reference. If we don't see that structure, do nothing. if (node->getNumChildren() < 2 || node->getChild(0)->getKind() != Demangle::Node::Kind::Type || node->getChild(0)->getNumChildren() < 1) return node; // Strip generic arguments from that child, then return it. return stripGenericArgsFromContextNode(node->getChild(0)->getChild(0), factory); case Demangle::Node::Kind::Class: case Demangle::Node::Kind::Enum: case Demangle::Node::Kind::Structure: case Demangle::Node::Kind::OtherNominalType: { if (node->getNumChildren() < 2) return node; auto newContext = stripGenericArgsFromContextNode(node->getChild(0), factory); if (newContext == node->getChild(0)) return node; auto newNode = factory.createNode(node->getKind()); newNode->addChild(newContext, factory); for (unsigned i = 1, n = node->getNumChildren(); i != n; ++i) newNode->addChild(node->getChild(i), factory); return newNode; } case Demangle::Node::Kind::Extension: { // Strip generic arguments from the extended type. if (node->getNumChildren() < 2) return node; auto newExtended = stripGenericArgsFromContextNode(node->getChild(1), factory); if (newExtended == node->getChild(1)) return node; auto newNode = factory.createNode(Node::Kind::Extension); newNode->addChild(node->getChild(0), factory); newNode->addChild(newExtended, factory); if (node->getNumChildren() == 3) newNode->addChild(node->getChild(2), factory); return newNode; } case Demangle::Node::Kind::Module: // Modules terminate the recursion. return node; default: // FIXME: Handle local contexts. return node; } }