//===--- GenericSpecializationMangler.cpp - mangling of specializations ---===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 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/SIL/GenericSpecializationMangler.h" #include "swift/AST/GenericEnvironment.h" #include "swift/AST/GenericSignature.h" #include "swift/AST/SubstitutionMap.h" #include "swift/Demangling/ManglingMacros.h" using namespace swift; using namespace Mangle; void SpecializationMangler::beginMangling() { ASTMangler::beginManglingWithoutPrefix(); if (Serialized) ArgOpBuffer << 'q'; ArgOpBuffer << char(uint8_t(Pass) + '0'); } namespace { /// Utility class for demangling specialization attributes. class AttributeDemangler : public Demangle::Demangler { public: void demangleAndAddAsChildren(StringRef MangledSpecialization, NodePointer Parent) { DemangleInitRAII state(*this, MangledSpecialization, nullptr); if (!parseAndPushNodes()) { llvm::errs() << "Can't demangle: " << MangledSpecialization << '\n'; abort(); } for (Node *Nd : NodeStack) { addChild(Parent, Nd); } } }; } // namespace std::string SpecializationMangler::finalize() { StringRef MangledSpecialization(Storage.data(), Storage.size()); AttributeDemangler D; NodePointer TopLevel = D.createNode(Node::Kind::Global); D.demangleAndAddAsChildren(MangledSpecialization, TopLevel); StringRef FuncName = Function ? Function->getName() : StringRef(FunctionName); NodePointer FuncTopLevel = nullptr; if (FuncName.startswith(MANGLING_PREFIX_STR)) { FuncTopLevel = D.demangleSymbol(FuncName); assert(FuncTopLevel); } if (!FuncTopLevel) { FuncTopLevel = D.createNode(Node::Kind::Global); FuncTopLevel->addChild(D.createNode(Node::Kind::Identifier, FuncName), D); } for (NodePointer FuncChild : *FuncTopLevel) { TopLevel->addChild(FuncChild, D); } std::string mangledName = Demangle::mangleNode(TopLevel); verify(mangledName); return mangledName; } //===----------------------------------------------------------------------===// // Generic Specialization //===----------------------------------------------------------------------===// void GenericSpecializationMangler:: appendSubstitutions(GenericSignature sig, SubstitutionMap subs) { bool First = true; sig->forEachParam([&](GenericTypeParamType *ParamType, bool Canonical) { if (Canonical) { appendType(Type(ParamType).subst(subs)->getCanonicalType()); appendListSeparator(First); } }); assert(!First && "no generic substitutions"); } std::string GenericSpecializationMangler:: manglePrespecialized(GenericSignature sig, SubstitutionMap subs) { beginMangling(); appendSubstitutions(sig, subs); appendSpecializationOperator("Ts"); return finalize(); } std::string GenericSpecializationMangler:: mangleNotReabstracted(SubstitutionMap subs) { beginMangling(); appendSubstitutions(getGenericSignature(), subs); appendSpecializationOperator("TG"); return finalize(); } std::string GenericSpecializationMangler:: mangleReabstracted(SubstitutionMap subs, bool alternativeMangling) { beginMangling(); appendSubstitutions(getGenericSignature(), subs); // See ReabstractionInfo::hasConvertedResilientParams for why and when to use // the alternative mangling. appendSpecializationOperator(alternativeMangling ? "TB" : "Tg"); return finalize(); } std::string GenericSpecializationMangler:: mangleForDebugInfo(GenericSignature sig, SubstitutionMap subs, bool forInlining) { beginMangling(); appendSubstitutions(sig, subs); appendSpecializationOperator(forInlining ? "Ti" : "TG"); return finalize(); } static SubstitutionMap getSubstitutionMapForPrespecialization(GenericSignature genericSig, GenericSignature specSig) { auto CalleeGenericSig = genericSig; auto SpecializedGenericSig = specSig; auto SpecializedGenericEnv = specSig->getGenericEnvironment(); auto CalleeInterfaceToSpecializedInterfaceMap = SubstitutionMap::get( CalleeGenericSig, [&](SubstitutableType *type) -> Type { return type; }, LookUpConformanceInSignature(CalleeGenericSig.getPointer())); auto subs = SubstitutionMap::get( CalleeGenericSig, [&](SubstitutableType *type) -> Type { auto SpecializedInterfaceTy = Type(type).subst(CalleeInterfaceToSpecializedInterfaceMap); return SpecializedGenericEnv->mapTypeIntoContext( SpecializedInterfaceTy); }, LookUpConformanceInSignature(SpecializedGenericSig.getPointer())); return subs; } std::string GenericSpecializationMangler::manglePrespecialization( std::string unspecializedName, GenericSignature genericSig, GenericSignature specializedSig) { auto subs = getSubstitutionMapForPrespecialization(genericSig, specializedSig); GenericSpecializationMangler mangler(unspecializedName); return mangler.manglePrespecialized(genericSig, subs); }