| //===--- IRGenMangler.h - mangling of IRGen symbols -------------*- 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_IRGEN_IRGENMANGLER_H |
| #define SWIFT_IRGEN_IRGENMANGLER_H |
| |
| #include "IRGenModule.h" |
| #include "swift/AST/ASTMangler.h" |
| #include "swift/IRGen/ValueWitness.h" |
| #include "llvm/Support/SaveAndRestore.h" |
| |
| namespace swift { |
| |
| class ProtocolConformance; |
| class NormalProtocolConformance; |
| |
| namespace irgen { |
| |
| enum class MangledTypeRefRole; |
| |
| /// A mangling string that includes embedded symbolic references. |
| struct SymbolicMangling { |
| std::string String; |
| std::vector<std::pair<Mangle::ASTMangler::SymbolicReferent, unsigned>> |
| SymbolicReferences; |
| }; |
| |
| /// The mangler for all kind of symbols produced in IRGen. |
| class IRGenMangler : public Mangle::ASTMangler { |
| public: |
| IRGenMangler() { } |
| |
| std::string mangleDispatchThunk(const FuncDecl *func) { |
| beginMangling(); |
| appendEntity(func); |
| appendOperator("Tj"); |
| return finalize(); |
| } |
| |
| std::string mangleConstructorDispatchThunk(const ConstructorDecl *ctor, |
| bool isAllocating) { |
| beginMangling(); |
| appendConstructorEntity(ctor, isAllocating); |
| appendOperator("Tj"); |
| return finalize(); |
| } |
| |
| std::string mangleMethodDescriptor(const FuncDecl *func) { |
| beginMangling(); |
| appendEntity(func); |
| appendOperator("Tq"); |
| return finalize(); |
| } |
| |
| std::string mangleConstructorMethodDescriptor(const ConstructorDecl *ctor, |
| bool isAllocating) { |
| beginMangling(); |
| appendConstructorEntity(ctor, isAllocating); |
| appendOperator("Tq"); |
| return finalize(); |
| } |
| |
| std::string mangleMethodLookupFunction(const ClassDecl *Decl) { |
| return mangleNominalTypeSymbol(Decl, "Mu"); |
| } |
| |
| std::string mangleValueWitness(Type type, ValueWitness witness); |
| |
| std::string mangleValueWitnessTable(Type type) { |
| return mangleTypeSymbol(type, "WV"); |
| } |
| |
| std::string mangleTypeMetadataAccessFunction(Type type) { |
| return mangleTypeSymbol(type, "Ma"); |
| } |
| |
| std::string mangleTypeMetadataLazyCacheVariable(Type type) { |
| return mangleTypeSymbol(type, "ML"); |
| } |
| |
| std::string mangleTypeFullMetadataFull(Type type) { |
| return mangleTypeSymbol(type, "Mf"); |
| } |
| |
| std::string mangleTypeMetadataFull(Type type) { |
| return mangleTypeSymbol(type, "N"); |
| } |
| |
| std::string mangleTypeMetadataPattern(const NominalTypeDecl *decl) { |
| return mangleNominalTypeSymbol(decl, "MP"); |
| } |
| |
| std::string mangleClassMetaClass(const ClassDecl *Decl) { |
| return mangleNominalTypeSymbol(Decl, "Mm"); |
| } |
| |
| std::string mangleObjCMetadataUpdateFunction(const ClassDecl *Decl) { |
| return mangleNominalTypeSymbol(Decl, "MU"); |
| } |
| |
| std::string mangleClassMetadataBaseOffset(const ClassDecl *Decl) { |
| return mangleNominalTypeSymbol(Decl, "Mo"); |
| } |
| |
| std::string mangleNominalTypeDescriptor(const NominalTypeDecl *Decl) { |
| return mangleNominalTypeSymbol(Decl, "Mn"); |
| } |
| |
| std::string mangleTypeMetadataInstantiationCache(const NominalTypeDecl *Decl){ |
| return mangleNominalTypeSymbol(Decl, "MI"); |
| } |
| |
| std::string mangleTypeMetadataInstantiationFunction( |
| const NominalTypeDecl *Decl) { |
| return mangleNominalTypeSymbol(Decl, "Mi"); |
| } |
| |
| std::string mangleTypeMetadataSingletonInitializationCache( |
| const NominalTypeDecl *Decl) { |
| return mangleNominalTypeSymbol(Decl, "Ml"); |
| } |
| |
| std::string mangleTypeMetadataCompletionFunction(const NominalTypeDecl *Decl){ |
| return mangleNominalTypeSymbol(Decl, "Mr"); |
| } |
| |
| std::string mangleModuleDescriptor(const ModuleDecl *Decl) { |
| beginMangling(); |
| appendContext(Decl); |
| appendOperator("MXM"); |
| return finalize(); |
| } |
| |
| std::string mangleExtensionDescriptor(const ExtensionDecl *Decl) { |
| beginMangling(); |
| appendContext(Decl); |
| appendOperator("MXE"); |
| return finalize(); |
| } |
| |
| std::string mangleAnonymousDescriptor(const DeclContext *DC) { |
| beginMangling(); |
| appendContext(DC); |
| appendOperator("MXX"); |
| return finalize(); |
| } |
| |
| std::string mangleBareProtocol(const ProtocolDecl *Decl) { |
| beginMangling(); |
| appendProtocolName(Decl, /*allowStandardSubstitution=*/false); |
| appendOperator("P"); |
| return finalize(); |
| } |
| |
| std::string mangleProtocolDescriptor(const ProtocolDecl *Decl) { |
| beginMangling(); |
| appendProtocolName(Decl); |
| appendOperator("Mp"); |
| return finalize(); |
| } |
| |
| std::string mangleProtocolRequirementsBaseDescriptor( |
| const ProtocolDecl *Decl) { |
| beginMangling(); |
| appendProtocolName(Decl); |
| appendOperator("TL"); |
| return finalize(); |
| } |
| |
| std::string mangleAssociatedTypeDescriptor( |
| const AssociatedTypeDecl *assocType) { |
| // Don't optimize away the protocol name, because we need it to distinguish |
| // among the type descriptors of different protocols. |
| llvm::SaveAndRestore<bool> optimizeProtocolNames(OptimizeProtocolNames, |
| false); |
| beginMangling(); |
| bool isAssocTypeAtDepth = false; |
| (void)appendAssocType( |
| assocType->getDeclaredInterfaceType()->castTo<DependentMemberType>(), |
| isAssocTypeAtDepth); |
| appendOperator("Tl"); |
| return finalize(); |
| } |
| |
| std::string mangleAssociatedConformanceDescriptor( |
| const ProtocolDecl *proto, |
| CanType subject, |
| const ProtocolDecl *requirement) { |
| beginMangling(); |
| appendAnyGenericType(proto); |
| if (isa<GenericTypeParamType>(subject)) { |
| appendType(subject); |
| } else { |
| bool isFirstAssociatedTypeIdentifier = true; |
| appendAssociatedTypePath(subject, isFirstAssociatedTypeIdentifier); |
| } |
| appendProtocolName(requirement); |
| appendOperator("Tn"); |
| return finalize(); |
| } |
| |
| std::string mangleBaseConformanceDescriptor( |
| const ProtocolDecl *proto, |
| const ProtocolDecl *requirement) { |
| beginMangling(); |
| appendAnyGenericType(proto); |
| appendProtocolName(requirement); |
| appendOperator("Tb"); |
| return finalize(); |
| } |
| |
| std::string mangleDefaultAssociatedConformanceAccessor( |
| const ProtocolDecl *proto, |
| CanType subject, |
| const ProtocolDecl *requirement) { |
| beginMangling(); |
| appendAnyGenericType(proto); |
| bool isFirstAssociatedTypeIdentifier = true; |
| appendAssociatedTypePath(subject, isFirstAssociatedTypeIdentifier); |
| appendProtocolName(requirement); |
| appendOperator("TN"); |
| return finalize(); |
| } |
| |
| std::string mangleProtocolConformanceDescriptor( |
| const RootProtocolConformance *conformance); |
| |
| std::string manglePropertyDescriptor(const AbstractStorageDecl *storage) { |
| beginMangling(); |
| appendEntity(storage); |
| appendOperator("MV"); |
| return finalize(); |
| } |
| |
| std::string mangleFieldOffset(const ValueDecl *Decl) { |
| beginMangling(); |
| appendEntity(Decl); |
| appendOperator("Wvd"); |
| return finalize(); |
| } |
| |
| std::string mangleEnumCase(const ValueDecl *Decl) { |
| beginMangling(); |
| appendEntity(Decl); |
| appendOperator("WC"); |
| return finalize(); |
| } |
| |
| std::string mangleProtocolWitnessTablePattern(const ProtocolConformance *C) { |
| return mangleConformanceSymbol(Type(), C, "Wp"); |
| } |
| |
| std::string mangleGenericProtocolWitnessTableInstantiationFunction( |
| const ProtocolConformance *C) { |
| return mangleConformanceSymbol(Type(), C, "WI"); |
| } |
| |
| std::string mangleProtocolWitnessTableLazyAccessFunction(Type type, |
| const ProtocolConformance *C) { |
| return mangleConformanceSymbol(type, C, "Wl"); |
| } |
| |
| std::string mangleProtocolWitnessTableLazyCacheVariable(Type type, |
| const ProtocolConformance *C) { |
| return mangleConformanceSymbol(type, C, "WL"); |
| } |
| |
| std::string mangleAssociatedTypeWitnessTableAccessFunction( |
| const ProtocolConformance *Conformance, |
| CanType AssociatedType, |
| const ProtocolDecl *Proto) { |
| beginMangling(); |
| appendProtocolConformance(Conformance); |
| bool isFirstAssociatedTypeIdentifier = true; |
| appendAssociatedTypePath(AssociatedType, isFirstAssociatedTypeIdentifier); |
| appendAnyGenericType(Proto); |
| appendOperator("WT"); |
| return finalize(); |
| } |
| |
| std::string mangleBaseWitnessTableAccessFunction( |
| const ProtocolConformance *Conformance, |
| const ProtocolDecl *BaseProto) { |
| beginMangling(); |
| appendProtocolConformance(Conformance); |
| appendAnyGenericType(BaseProto); |
| appendOperator("Wb"); |
| return finalize(); |
| } |
| |
| void appendAssociatedTypePath(CanType associatedType, bool &isFirst) { |
| if (auto memberType = dyn_cast<DependentMemberType>(associatedType)) { |
| appendAssociatedTypePath(memberType.getBase(), isFirst); |
| appendAssociatedTypeName(memberType); |
| appendListSeparator(isFirst); |
| } else { |
| assert(isa<GenericTypeParamType>(associatedType)); |
| } |
| } |
| |
| std::string mangleCoroutineContinuationPrototype(CanSILFunctionType type) { |
| return mangleTypeSymbol(type, "TC"); |
| } |
| |
| std::string mangleReflectionBuiltinDescriptor(Type type) { |
| return mangleTypeSymbol(type, "MB"); |
| } |
| |
| std::string mangleReflectionFieldDescriptor(Type type) { |
| return mangleTypeSymbol(type, "MF"); |
| } |
| |
| std::string mangleReflectionAssociatedTypeDescriptor( |
| const ProtocolConformance *C) { |
| return mangleConformanceSymbol(Type(), C, "MA"); |
| } |
| |
| std::string mangleOutlinedCopyFunction(CanType ty, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(ty); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOy"); |
| return finalize(); |
| } |
| std::string mangleOutlinedConsumeFunction(CanType ty, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(ty); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOe"); |
| return finalize(); |
| } |
| |
| std::string mangleOutlinedRetainFunction(CanType t, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(t); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOr"); |
| return finalize(); |
| } |
| std::string mangleOutlinedReleaseFunction(CanType t, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(t); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOs"); |
| return finalize(); |
| } |
| |
| std::string mangleOutlinedInitializeWithTakeFunction(CanType t, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(t); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOb"); |
| return finalize(); |
| } |
| std::string mangleOutlinedInitializeWithCopyFunction(CanType t, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(t); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOc"); |
| return finalize(); |
| } |
| std::string mangleOutlinedAssignWithTakeFunction(CanType t, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(t); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOd"); |
| return finalize(); |
| } |
| std::string mangleOutlinedAssignWithCopyFunction(CanType t, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(t); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOf"); |
| return finalize(); |
| } |
| std::string mangleOutlinedDestroyFunction(CanType t, |
| CanGenericSignature sig) { |
| beginMangling(); |
| appendType(t); |
| if (sig) |
| appendGenericSignature(sig); |
| appendOperator("WOh"); |
| return finalize(); |
| } |
| |
| std::string manglePartialApplyForwarder(StringRef FuncName); |
| |
| std::string mangleTypeForForeignMetadataUniquing(Type type) { |
| return mangleTypeWithoutPrefix(type); |
| } |
| |
| SymbolicMangling mangleTypeForReflection(IRGenModule &IGM, |
| Type Ty); |
| |
| SymbolicMangling mangleProtocolConformanceForReflection(IRGenModule &IGM, |
| Type Ty, |
| ProtocolConformanceRef conformance); |
| |
| std::string mangleTypeForLLVMTypeName(CanType Ty); |
| |
| std::string mangleProtocolForLLVMTypeName(ProtocolCompositionType *type); |
| |
| std::string mangleSymbolNameForSymbolicMangling( |
| const SymbolicMangling &mangling, |
| MangledTypeRefRole role); |
| |
| std::string mangleSymbolNameForAssociatedConformanceWitness( |
| const NormalProtocolConformance *conformance, |
| CanType associatedType, |
| const ProtocolDecl *proto); |
| |
| std::string mangleSymbolNameForKeyPathMetadata( |
| const char *kind, |
| CanGenericSignature genericSig, |
| CanType type, |
| ProtocolConformanceRef conformance); |
| |
| std::string mangleSymbolNameForGenericEnvironment( |
| CanGenericSignature genericSig); |
| protected: |
| SymbolicMangling |
| withSymbolicReferences(IRGenModule &IGM, |
| llvm::function_ref<void ()> body); |
| |
| std::string mangleTypeSymbol(Type type, const char *Op) { |
| beginMangling(); |
| appendType(type); |
| appendOperator(Op); |
| return finalize(); |
| } |
| |
| std::string mangleNominalTypeSymbol(const NominalTypeDecl *Decl, |
| const char *Op) { |
| beginMangling(); |
| appendAnyGenericType(Decl); |
| appendOperator(Op); |
| return finalize(); |
| } |
| |
| std::string mangleConformanceSymbol(Type type, |
| const ProtocolConformance *Conformance, |
| const char *Op) { |
| beginMangling(); |
| if (type) |
| appendType(type); |
| appendProtocolConformance(Conformance); |
| appendOperator(Op); |
| return finalize(); |
| } |
| }; |
| |
| } // end namespace irgen |
| } // end namespace swift |
| |
| #endif |