static std::string mangleConstant(NormalProtocolConformance *C) { using namespace Mangle; Mangler mangler; // mangled-name ::= '_T' global // global ::= 'WP' protocol-conformance mangler.append("_TWP"); mangler.mangleProtocolConformance(C); return mangler.finalize(); }
static std::string mangleConstant(NormalProtocolConformance *C) { using namespace Mangle; Mangler mangler; // mangled-name ::= '_T' global // global ::= 'WP' protocol-conformance mangler.append("_TWP"); mangler.mangleProtocolConformance(C); std::string Old = mangler.finalize(); NewMangling::ASTMangler NewMangler; std::string New = NewMangler.mangleWitnessTable(C); return NewMangling::selectMangling(Old, New); }
static std::string mangleConstant(SILDeclRef c, SILDeclRef::ManglingKind Kind) { using namespace Mangle; Mangler mangler; // Almost everything below gets one of the common prefixes: // mangled-name ::= '_T' global // Native symbol // mangled-name ::= '_TTo' global // ObjC interop thunk // mangled-name ::= '_TTO' global // Foreign function thunk // mangled-name ::= '_TTd' global // Direct StringRef introducer = "_T"; switch (Kind) { case SILDeclRef::ManglingKind::Default: if (c.isForeign) { introducer = "_TTo"; } else if (c.isDirectReference) { introducer = "_TTd"; } else if (c.isForeignToNativeThunk()) { introducer = "_TTO"; } break; case SILDeclRef::ManglingKind::VTableMethod: introducer = "_TTV"; break; case SILDeclRef::ManglingKind::DynamicThunk: introducer = "_TTD"; break; } // As a special case, Clang functions and globals don't get mangled at all. if (c.hasDecl()) { if (auto clangDecl = c.getDecl()->getClangDecl()) { if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk() && !c.isCurried) { if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) { if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) { mangler.append('\01'); mangler.append(asmLabel->getLabel()); } else if (namedClangDecl->hasAttr<clang::OverloadableAttr>()) { std::string storage; llvm::raw_string_ostream SS(storage); // FIXME: When we can import C++, use Clang's mangler all the time. mangleClangDecl(SS, namedClangDecl, c.getDecl()->getASTContext()); mangler.append(SS.str()); } else { mangler.append(namedClangDecl->getName()); } return mangler.finalize(); } } } } switch (c.kind) { // entity ::= declaration // other declaration case SILDeclRef::Kind::Func: if (!c.hasDecl()) { mangler.append(introducer); mangler.mangleClosureEntity(c.getAbstractClosureExpr(), c.uncurryLevel); return mangler.finalize(); } // As a special case, functions can have manually mangled names. // Use the SILGen name only for the original non-thunked, non-curried entry // point. if (auto NameA = c.getDecl()->getAttrs().getAttribute<SILGenNameAttr>()) if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk() && !c.isCurried) { mangler.append(NameA->Name); return mangler.finalize(); } // Use a given cdecl name for native-to-foreign thunks. if (auto CDeclA = c.getDecl()->getAttrs().getAttribute<CDeclAttr>()) if (c.isNativeToForeignThunk()) { mangler.append(CDeclA->Name); return mangler.finalize(); } // Otherwise, fall through into the 'other decl' case. SWIFT_FALLTHROUGH; case SILDeclRef::Kind::EnumElement: mangler.append(introducer); mangler.mangleEntity(c.getDecl(), c.uncurryLevel); return mangler.finalize(); // entity ::= context 'D' // deallocating destructor case SILDeclRef::Kind::Deallocator: mangler.append(introducer); mangler.mangleDestructorEntity(cast<DestructorDecl>(c.getDecl()), /*isDeallocating*/ true); return mangler.finalize(); // entity ::= context 'd' // destroying destructor case SILDeclRef::Kind::Destroyer: mangler.append(introducer); mangler.mangleDestructorEntity(cast<DestructorDecl>(c.getDecl()), /*isDeallocating*/ false); return mangler.finalize(); // entity ::= context 'C' type // allocating constructor case SILDeclRef::Kind::Allocator: mangler.append(introducer); mangler.mangleConstructorEntity(cast<ConstructorDecl>(c.getDecl()), /*allocating*/ true, c.uncurryLevel); return mangler.finalize(); // entity ::= context 'c' type // initializing constructor case SILDeclRef::Kind::Initializer: mangler.append(introducer); mangler.mangleConstructorEntity(cast<ConstructorDecl>(c.getDecl()), /*allocating*/ false, c.uncurryLevel); return mangler.finalize(); // entity ::= declaration 'e' // ivar initializer // entity ::= declaration 'E' // ivar destroyer case SILDeclRef::Kind::IVarInitializer: case SILDeclRef::Kind::IVarDestroyer: mangler.append(introducer); mangler.mangleIVarInitDestroyEntity( cast<ClassDecl>(c.getDecl()), c.kind == SILDeclRef::Kind::IVarDestroyer); return mangler.finalize(); // entity ::= declaration 'a' // addressor case SILDeclRef::Kind::GlobalAccessor: mangler.append(introducer); mangler.mangleAddressorEntity(c.getDecl()); return mangler.finalize(); // entity ::= declaration 'G' // getter case SILDeclRef::Kind::GlobalGetter: mangler.append(introducer); mangler.mangleGlobalGetterEntity(c.getDecl()); return mangler.finalize(); // entity ::= context 'e' index // default arg generator case SILDeclRef::Kind::DefaultArgGenerator: mangler.append(introducer); mangler.mangleDefaultArgumentEntity(cast<AbstractFunctionDecl>(c.getDecl()), c.defaultArgIndex); return mangler.finalize(); // entity ::= 'I' declaration 'i' // stored property initializer case SILDeclRef::Kind::StoredPropertyInitializer: mangler.append(introducer); mangler.mangleInitializerEntity(cast<VarDecl>(c.getDecl())); return mangler.finalize(); } llvm_unreachable("bad entity kind!"); }
/// Mangle this entity into the given stream. void LinkEntity::mangle(raw_ostream &buffer) const { // Almost everything below gets the common prefix: // mangled-name ::= '_T' global Mangler mangler; switch (getKind()) { // global ::= 'w' value-witness-kind type // value witness case Kind::ValueWitness: mangler.append("_Tw"); mangler.append(mangleValueWitness(getValueWitness())); mangler.mangleType(getType(), 0); return mangler.finalize(buffer); // global ::= 'WV' type // value witness case Kind::ValueWitnessTable: mangler.append("_TWV"); mangler.mangleType(getType(), 0); return mangler.finalize(buffer); // global ::= 't' type // Abstract type manglings just follow <type>. case Kind::TypeMangling: mangler.mangleType(getType(), 0); return mangler.finalize(buffer); // global ::= 'Ma' type // type metadata access function case Kind::TypeMetadataAccessFunction: mangler.append("_TMa"); mangler.mangleType(getType(), 0); return mangler.finalize(buffer); // global ::= 'ML' type // type metadata lazy cache variable case Kind::TypeMetadataLazyCacheVariable: mangler.append("_TML"); mangler.mangleType(getType(), 0); return mangler.finalize(buffer); // global ::= 'Mf' type // 'full' type metadata // global ::= 'M' directness type // type metadata // global ::= 'MP' directness type // type metadata pattern case Kind::TypeMetadata: switch (getMetadataAddress()) { case TypeMetadataAddress::FullMetadata: mangler.mangleTypeFullMetadataFull(getType()); break; case TypeMetadataAddress::AddressPoint: mangler.mangleTypeMetadataFull(getType(), isMetadataPattern()); break; } return mangler.finalize(buffer); // global ::= 'M' directness type // type metadata case Kind::ForeignTypeMetadataCandidate: mangler.mangleTypeMetadataFull(getType(), /*isPattern=*/false); return mangler.finalize(buffer); // global ::= 'Mm' type // class metaclass case Kind::SwiftMetaclassStub: mangler.append("_TMm"); mangler.mangleNominalType(cast<ClassDecl>(getDecl()), Mangler::BindGenerics::None); return mangler.finalize(buffer); // global ::= 'Mn' type // nominal type descriptor case Kind::NominalTypeDescriptor: mangler.append("_TMn"); mangler.mangleNominalType(cast<NominalTypeDecl>(getDecl()), Mangler::BindGenerics::None); return mangler.finalize(buffer); // global ::= 'Mp' type // protocol descriptor case Kind::ProtocolDescriptor: mangler.append("_TMp"); mangler.mangleProtocolName(cast<ProtocolDecl>(getDecl())); return mangler.finalize(buffer); // global ::= 'Wo' entity case Kind::WitnessTableOffset: mangler.append("_TWo"); // Witness table entries for constructors always refer to the allocating // constructor. if (auto ctor = dyn_cast<ConstructorDecl>(getDecl())) mangler.mangleConstructorEntity(ctor, /*isAllocating=*/true, getUncurryLevel()); else mangler.mangleEntity(getDecl(), getUncurryLevel()); return mangler.finalize(buffer); // global ::= 'Wv' directness entity case Kind::FieldOffset: mangler.mangleFieldOffsetFull(getDecl(), isOffsetIndirect()); return mangler.finalize(buffer); // global ::= 'WP' protocol-conformance case Kind::DirectProtocolWitnessTable: mangler.append("_TWP"); mangler.mangleProtocolConformance(getProtocolConformance()); return mangler.finalize(buffer); // global ::= 'WG' protocol-conformance case Kind::GenericProtocolWitnessTableCache: buffer << "_TWG"; mangler.mangleProtocolConformance(getProtocolConformance()); return mangler.finalize(buffer); // global ::= 'WI' protocol-conformance case Kind::GenericProtocolWitnessTableInstantiationFunction: buffer << "_TWI"; mangler.mangleProtocolConformance(getProtocolConformance()); return mangler.finalize(buffer); // global ::= 'Wa' protocol-conformance case Kind::ProtocolWitnessTableAccessFunction: mangler.append("_TWa"); mangler.mangleProtocolConformance(getProtocolConformance()); return mangler.finalize(buffer); // global ::= 'Wl' type protocol-conformance case Kind::ProtocolWitnessTableLazyAccessFunction: mangler.append("_TWl"); mangler.mangleType(getType(), 0); mangler.mangleProtocolConformance(getProtocolConformance()); return mangler.finalize(buffer); // global ::= 'WL' type protocol-conformance case Kind::ProtocolWitnessTableLazyCacheVariable: mangler.append("_TWL"); mangler.mangleType(getType(), 0); mangler.mangleProtocolConformance(getProtocolConformance()); return mangler.finalize(buffer); // global ::= 'Wt' protocol-conformance identifier case Kind::AssociatedTypeMetadataAccessFunction: mangler.append("_TWt"); mangler.mangleProtocolConformance(getProtocolConformance()); mangler.mangleIdentifier(getAssociatedType()->getNameStr()); return mangler.finalize(buffer); // global ::= 'WT' protocol-conformance identifier nominal-type case Kind::AssociatedTypeWitnessTableAccessFunction: mangler.append("_TWT"); mangler.mangleProtocolConformance(getProtocolConformance()); mangler.mangleIdentifier(getAssociatedType()->getNameStr()); mangler.mangleProtocolDecl(getAssociatedProtocol()); return mangler.finalize(buffer); // For all the following, this rule was imposed above: // global ::= local-marker? entity // some identifiable thing // entity ::= declaration // other declaration case Kind::Function: // As a special case, functions can have manually mangled names. if (auto AsmA = getDecl()->getAttrs().getAttribute<SILGenNameAttr>()) { mangler.append(AsmA->Name); return mangler.finalize(buffer); } // Otherwise, fall through into the 'other decl' case. SWIFT_FALLTHROUGH; case Kind::Other: // As a special case, Clang functions and globals don't get mangled at all. if (auto clangDecl = getDecl()->getClangDecl()) { if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) { if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) { mangler.append('\01'); mangler.append(asmLabel->getLabel()); } else if (namedClangDecl->hasAttr<clang::OverloadableAttr>()) { // FIXME: When we can import C++, use Clang's mangler all the time. std::string storage; llvm::raw_string_ostream SS(storage); mangleClangDecl(SS, namedClangDecl, getDecl()->getASTContext()); mangler.append(SS.str()); } else { mangler.append(namedClangDecl->getName()); } return mangler.finalize(buffer); } } mangler.append("_T"); if (auto type = dyn_cast<NominalTypeDecl>(getDecl())) { mangler.mangleNominalType(type, Mangler::BindGenerics::None); } else if (auto ctor = dyn_cast<ConstructorDecl>(getDecl())) { // FIXME: Hack. LinkInfo should be able to refer to the allocating // constructor rather than inferring it here. mangler.mangleConstructorEntity(ctor, /*isAllocating=*/true, getUncurryLevel()); } else { mangler.mangleEntity(getDecl(), getUncurryLevel()); } return mangler.finalize(buffer); // An Objective-C class reference reference. The symbol is private, so // the mangling is unimportant; it should just be readable in LLVM IR. case Kind::ObjCClassRef: { mangler.append("OBJC_CLASS_REF_$_"); llvm::SmallString<64> tempBuffer; StringRef name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(tempBuffer); mangler.append(name); return mangler.finalize(buffer); } // An Objective-C class reference; not a swift mangling. case Kind::ObjCClass: { llvm::SmallString<64> TempBuffer; mangler.append("OBJC_CLASS_$_"); StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer); mangler.append(Name); return mangler.finalize(buffer); } // An Objective-C metaclass reference; not a swift mangling. case Kind::ObjCMetaclass: { llvm::SmallString<64> TempBuffer; mangler.append("OBJC_METACLASS_$_"); StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer); mangler.append(Name); return mangler.finalize(buffer); } case Kind::SILFunction: mangler.appendSymbol(getSILFunction()->getName()); return mangler.finalize(buffer); case Kind::SILGlobalVariable: mangler.appendSymbol(getSILGlobalVariable()->getName()); return mangler.finalize(buffer); } llvm_unreachable("bad entity kind!"); }