mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
If the specialized function has a re-abstracted (= converted from indirect to direct) resilient argument or return types, use an alternative mangling: "TB" instead of "Tg". Resilient parameters/returns can be converted from indirect to direct if the specialization is created within the type's resilience domain, i.e. in its module (where the type is loadable). In this case we need to generate a different mangled name for the specialized function to distinguish it from specializations in other modules, which cannot re-abstract this resilient type. This fixes a miscompile resulting from ODR-linking specializations from different modules, which in fact have different function signatures. https://bugs.swift.org/browse/SR-13900 rdar://71914016
111 lines
3.7 KiB
C++
111 lines
3.7 KiB
C++
//===- GenericSpecializationMangler.h - generic specializations -*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SIL_UTILS_GENERICSPECIALIZATIONMANGLER_H
|
|
#define SWIFT_SIL_UTILS_GENERICSPECIALIZATIONMANGLER_H
|
|
|
|
#include "swift/AST/ASTMangler.h"
|
|
#include "swift/Basic/NullablePtr.h"
|
|
#include "swift/Demangling/Demangler.h"
|
|
#include "swift/SIL/SILFunction.h"
|
|
|
|
namespace swift {
|
|
namespace Mangle {
|
|
|
|
enum class SpecializationKind : uint8_t {
|
|
Generic,
|
|
NotReAbstractedGeneric,
|
|
FunctionSignature,
|
|
};
|
|
|
|
/// Inject SpecializationPass into the Mangle namespace.
|
|
using SpecializationPass = Demangle::SpecializationPass;
|
|
|
|
/// The base class for specialization mangles.
|
|
class SpecializationMangler : public Mangle::ASTMangler {
|
|
protected:
|
|
/// The specialization pass.
|
|
SpecializationPass Pass;
|
|
|
|
IsSerialized_t Serialized;
|
|
|
|
/// The original function which is specialized.
|
|
SILFunction *Function;
|
|
std::string FunctionName;
|
|
|
|
llvm::SmallVector<char, 32> ArgOpStorage;
|
|
llvm::raw_svector_ostream ArgOpBuffer;
|
|
|
|
protected:
|
|
SpecializationMangler(SpecializationPass P, IsSerialized_t Serialized,
|
|
SILFunction *F)
|
|
: Pass(P), Serialized(Serialized), Function(F),
|
|
ArgOpBuffer(ArgOpStorage) {}
|
|
|
|
SpecializationMangler(SpecializationPass P, IsSerialized_t Serialized,
|
|
std::string functionName)
|
|
: Pass(P), Serialized(Serialized), Function(nullptr),
|
|
FunctionName(functionName), ArgOpBuffer(ArgOpStorage) {}
|
|
|
|
void beginMangling();
|
|
|
|
/// Finish the mangling of the symbol and return the mangled name.
|
|
std::string finalize();
|
|
|
|
void appendSpecializationOperator(StringRef Op) {
|
|
appendOperator(Op, StringRef(ArgOpStorage.data(), ArgOpStorage.size()));
|
|
}
|
|
};
|
|
|
|
// The mangler for specialized generic functions.
|
|
class GenericSpecializationMangler : public SpecializationMangler {
|
|
|
|
GenericSpecializationMangler(std::string origFuncName)
|
|
: SpecializationMangler(SpecializationPass::GenericSpecializer,
|
|
IsNotSerialized, origFuncName) {}
|
|
|
|
GenericSignature getGenericSignature() {
|
|
assert(Function && "Need a SIL function to get a generic signature");
|
|
return Function->getLoweredFunctionType()->getInvocationGenericSignature();
|
|
}
|
|
|
|
void appendSubstitutions(GenericSignature sig, SubstitutionMap subs);
|
|
|
|
std::string manglePrespecialized(GenericSignature sig,
|
|
SubstitutionMap subs);
|
|
|
|
public:
|
|
GenericSpecializationMangler(SILFunction *F, IsSerialized_t Serialized)
|
|
: SpecializationMangler(SpecializationPass::GenericSpecializer,
|
|
Serialized, F) {}
|
|
|
|
std::string mangleNotReabstracted(SubstitutionMap subs);
|
|
|
|
std::string mangleReabstracted(SubstitutionMap subs, bool alternativeMangling);
|
|
|
|
std::string mangleForDebugInfo(GenericSignature sig, SubstitutionMap subs,
|
|
bool forInlining);
|
|
|
|
std::string manglePrespecialized(SubstitutionMap subs) {
|
|
return manglePrespecialized(getGenericSignature(), subs);
|
|
}
|
|
|
|
static std::string manglePrespecialization(std::string unspecializedName,
|
|
GenericSignature genericSig,
|
|
GenericSignature specializedSig);
|
|
};
|
|
|
|
} // end namespace Mangle
|
|
} // end namespace swift
|
|
|
|
#endif
|