mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
188 lines
6.2 KiB
C++
188 lines
6.2 KiB
C++
//===--- 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/ASTContext.h"
|
|
#include "swift/AST/GenericEnvironment.h"
|
|
#include "swift/AST/GenericSignature.h"
|
|
#include "swift/AST/SubstitutionMap.h"
|
|
#include "swift/Basic/Assertions.h"
|
|
#include "swift/Demangling/ManglingMacros.h"
|
|
|
|
using namespace swift;
|
|
using namespace Mangle;
|
|
|
|
void SpecializationMangler::beginMangling() {
|
|
ASTMangler::beginManglingWithoutPrefix();
|
|
|
|
if (Serialized)
|
|
ArgOpBuffer << 'q';
|
|
|
|
if (RemovedEffects.contains(EffectKind::Async))
|
|
ArgOpBuffer << 'a';
|
|
|
|
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.starts_with(MANGLING_PREFIX_STR)) {
|
|
FuncTopLevel = D.demangleSymbol(FuncName);
|
|
assert(FuncTopLevel);
|
|
}
|
|
else if (FuncName.starts_with(MANGLING_PREFIX_EMBEDDED_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);
|
|
}
|
|
auto mangling = Demangle::mangleNode(TopLevel, Flavor);
|
|
assert(mangling.isSuccess());
|
|
std::string mangledName = mangling.result();
|
|
verify(mangledName, Flavor);
|
|
return mangledName;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Generic Specialization
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void GenericSpecializationMangler::
|
|
appendSubstitutions(GenericSignature sig, SubstitutionMap subs) {
|
|
bool First = true;
|
|
sig->forEachParam([&](GenericTypeParamType *ParamType, bool Canonical) {
|
|
if (Canonical) {
|
|
auto ty = Type(ParamType);
|
|
auto substTy = ty.subst(subs);
|
|
auto canTy = substTy->getCanonicalType();
|
|
appendType(canTy, nullptr);
|
|
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,
|
|
const SmallBitVector ¶msRemoved) {
|
|
beginMangling();
|
|
appendSubstitutions(getGenericSignature(), subs);
|
|
appendOperator("T");
|
|
appendRemovedParams(paramsRemoved);
|
|
appendSpecializationOperator("G");
|
|
return finalize();
|
|
}
|
|
|
|
std::string GenericSpecializationMangler::
|
|
mangleReabstracted(SubstitutionMap subs, bool alternativeMangling,
|
|
const SmallBitVector ¶msRemoved) {
|
|
beginMangling();
|
|
appendSubstitutions(getGenericSignature(), subs);
|
|
appendOperator("T");
|
|
appendRemovedParams(paramsRemoved);
|
|
|
|
// See ReabstractionInfo::hasConvertedResilientParams for why and when to use
|
|
// the alternative mangling.
|
|
appendSpecializationOperator(alternativeMangling ? "B" : "g");
|
|
return finalize();
|
|
}
|
|
|
|
void GenericSpecializationMangler::appendRemovedParams(const SmallBitVector ¶msRemoved) {
|
|
for (int paramIdx : paramsRemoved.set_bits()) {
|
|
appendOperator("t");
|
|
if (paramIdx != 0)
|
|
Buffer << (paramIdx - 1);
|
|
}
|
|
}
|
|
|
|
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 SpecializedGenericEnv = specSig.getGenericEnvironment();
|
|
|
|
auto CalleeInterfaceToSpecializedInterfaceMap = SubstitutionMap::get(
|
|
CalleeGenericSig,
|
|
[&](SubstitutableType *type) -> Type {
|
|
return type;
|
|
},
|
|
LookUpConformanceInModule());
|
|
|
|
auto subs = SubstitutionMap::get(
|
|
CalleeGenericSig,
|
|
[&](SubstitutableType *type) -> Type {
|
|
auto SpecializedInterfaceTy =
|
|
Type(type).subst(CalleeInterfaceToSpecializedInterfaceMap);
|
|
return SpecializedGenericEnv->mapTypeIntoContext(
|
|
SpecializedInterfaceTy);
|
|
},
|
|
LookUpConformanceInModule());
|
|
return subs;
|
|
}
|
|
|
|
std::string GenericSpecializationMangler::manglePrespecialization(ASTContext &Ctx,
|
|
std::string unspecializedName, GenericSignature genericSig,
|
|
GenericSignature specializedSig) {
|
|
auto subs =
|
|
getSubstitutionMapForPrespecialization(genericSig, specializedSig);
|
|
GenericSpecializationMangler mangler(Ctx, unspecializedName);
|
|
return mangler.manglePrespecialized(genericSig, subs);
|
|
}
|