/// Emit a global initialization. void SILGenModule::emitGlobalInitialization(PatternBindingDecl *pd, unsigned pbdEntry) { // Generic and dynamic static properties require lazy initialization, which // isn't implemented yet. if (pd->isStatic()) { auto theType = pd->getDeclContext()->getDeclaredTypeInContext(); assert(!theType->is<BoundGenericType>() && "generic static properties not implemented"); (void)theType; } // Emit the lazy initialization token for the initialization expression. auto counter = anonymousSymbolCounter++; // Pick one variable of the pattern. Usually it's only one variable, but it // can also be something like: var (a, b) = ... Pattern *pattern = pd->getPattern(pbdEntry); VarDecl *varDecl = nullptr; pattern->forEachVariable([&](VarDecl *D) { varDecl = D; }); assert(varDecl); std::string onceTokenBuffer; { Mangler tokenMangler; tokenMangler.mangleGlobalInit(varDecl, counter, false); onceTokenBuffer = tokenMangler.finalize(); } auto onceTy = BuiltinIntegerType::getWordType(M.getASTContext()); auto onceSILTy = SILType::getPrimitiveObjectType(onceTy->getCanonicalType()); // TODO: include the module in the onceToken's name mangling. // Then we can make it fragile. auto onceToken = SILGlobalVariable::create(M, SILLinkage::Private, makeModuleFragile, onceTokenBuffer, onceSILTy); onceToken->setDeclaration(false); // Emit the initialization code into a function. std::string onceFuncBuffer; { Mangler funcMangler; funcMangler.mangleGlobalInit(varDecl, counter, true); onceFuncBuffer = funcMangler.finalize(); } SILFunction *onceFunc = emitLazyGlobalInitializer(onceFuncBuffer, pd, pbdEntry); // Generate accessor functions for all of the declared variables, which // Builtin.once the lazy global initializer we just generated then return // the address of the individual variable. GenGlobalAccessors(*this, onceToken, onceFunc) .visit(pd->getPattern(pbdEntry)); }
/// Get or create SILGlobalVariable for a given global VarDecl. SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl, ForDefinition_t forDef) { // First, get a mangled name for the declaration. std::string mangledName; if (auto SILGenName = gDecl->getAttrs().getAttribute<SILGenNameAttr>()) { mangledName = SILGenName->Name; } else { Mangler mangler; mangler.mangleGlobalVariableFull(gDecl); mangledName = mangler.finalize(); } // Check if it is already created, and update linkage if necessary. if (auto gv = M.lookUpGlobalVariable(mangledName)) { // Update the SILLinkage here if this is a definition. if (forDef == ForDefinition) { gv->setLinkage(getSILLinkage(getDeclLinkage(gDecl), ForDefinition)); gv->setDeclaration(false); } return gv; } // Get the linkage for SILGlobalVariable. SILLinkage link = getSILLinkage(getDeclLinkage(gDecl), forDef); SILType silTy = M.Types.getLoweredTypeOfGlobal(gDecl); auto *silGlobal = SILGlobalVariable::create(M, link, makeModuleFragile ? IsFragile : IsNotFragile, mangledName, silTy, None, gDecl); silGlobal->setDeclaration(!forDef); return silGlobal; }
bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) { using namespace Mangle; if (!isa<FuncDecl>(D) && !D->hasName()) return true; // Ignore. if (D->getModuleContext()->isBuiltinModule()) return true; // Ignore. ValueDecl *VD = const_cast<ValueDecl *>(D); if (ClangNode ClangN = VD->getClangNode()) { llvm::SmallString<128> Buf; if (auto ClangD = ClangN.getAsDecl()) { bool Ignore = clang::index::generateUSRForDecl(ClangD, Buf); if (!Ignore) OS << Buf.str(); return Ignore; } auto &Importer = *D->getASTContext().getClangModuleLoader(); auto ClangMacroInfo = ClangN.getAsMacro(); auto PPRecord = Importer.getClangPreprocessor().getPreprocessingRecord(); assert(PPRecord && "Clang importer should be created with " "-detailed-preprocessing-record option"); auto ClangMacroDef = PPRecord->findMacroDefinition(ClangMacroInfo); bool Ignore = clang::index::generateUSRForMacro( ClangMacroDef, Importer.getClangASTContext().getSourceManager(), Buf); if (!Ignore) OS << Buf.str(); return Ignore; } if (!D->hasType()) return true; // FIXME: mangling 'self' in destructors crashes in mangler. if (isa<ParamDecl>(VD) && isa<DestructorDecl>(VD->getDeclContext())) return true; OS << getUSRSpacePrefix(); Mangler Mangler; if (auto Ctor = dyn_cast<ConstructorDecl>(VD)) { Mangler.mangleConstructorEntity(Ctor, /*isAllocating=*/false, /*uncurryingLevel=*/0); } else if (auto Dtor = dyn_cast<DestructorDecl>(VD)) { Mangler.mangleDestructorEntity(Dtor, /*isDeallocating=*/false); } else if (auto NTD = dyn_cast<NominalTypeDecl>(VD)) { Mangler.mangleNominalType(NTD, Mangler::BindGenerics::None); } else if (isa<TypeAliasDecl>(VD) || isa<AssociatedTypeDecl>(VD)) { Mangler.mangleContextOf(VD, Mangler::BindGenerics::None); Mangler.mangleDeclName(VD); } else { Mangler.mangleEntity(VD, /*uncurryingLevel=*/0); } Mangler.finalize(OS); return false; }
static SILValue getBehaviorInitStorageFn(SILGenFunction &gen, VarDecl *behaviorVar) { std::string behaviorInitName; { Mangler m; m.mangleBehaviorInitThunk(behaviorVar); std::string Old = m.finalize(); NewMangling::ASTMangler NewMangler; std::string New = NewMangler.mangleBehaviorInitThunk(behaviorVar); behaviorInitName = NewMangling::selectMangling(Old, New); } SILFunction *thunkFn; // Skip out early if we already emitted this thunk. if (auto existing = gen.SGM.M.lookUpFunction(behaviorInitName)) { thunkFn = existing; } else { auto init = behaviorVar->getBehavior()->InitStorageDecl.getDecl(); auto initFn = gen.SGM.getFunction(SILDeclRef(init), NotForDefinition); // Emit a thunk to inject the `self` metatype and implode tuples. auto storageVar = behaviorVar->getBehavior()->StorageDecl; auto selfTy = behaviorVar->getDeclContext()->getDeclaredInterfaceType(); auto initTy = gen.getLoweredType(selfTy).getFieldType(behaviorVar, gen.SGM.M); auto storageTy = gen.getLoweredType(selfTy).getFieldType(storageVar, gen.SGM.M); auto initConstantTy = initFn->getLoweredType().castTo<SILFunctionType>(); auto param = SILParameterInfo(initTy.getSwiftRValueType(), initTy.isAddress() ? ParameterConvention::Indirect_In : ParameterConvention::Direct_Owned); auto result = SILResultInfo(storageTy.getSwiftRValueType(), storageTy.isAddress() ? ResultConvention::Indirect : ResultConvention::Owned); initConstantTy = SILFunctionType::get(initConstantTy->getGenericSignature(), initConstantTy->getExtInfo(), ParameterConvention::Direct_Unowned, param, result, // TODO: throwing initializer? None, gen.getASTContext()); // TODO: Generate the body of the thunk. thunkFn = gen.SGM.M.getOrCreateFunction(SILLocation(behaviorVar), behaviorInitName, SILLinkage::PrivateExternal, initConstantTy, IsBare, IsTransparent, IsFragile); } return gen.B.createFunctionRef(behaviorVar, thunkFn); }
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); }
bool ide::printAccessorUSR(const AbstractStorageDecl *D, AccessorKind AccKind, llvm::raw_ostream &OS) { using namespace Mangle; // AccKind should always be either IsGetter or IsSetter here, based // on whether a reference is a mutating or non-mutating use. USRs // aren't supposed to reflect implementation differences like stored // vs. addressed vs. observing. // // On the other side, the implementation indexer should be // registering the getter/setter USRs independently of how they're // actually implemented. So a stored variable should still have // getter/setter USRs (pointing to the variable declaration), and an // addressed variable should have its "getter" point at the // addressor. AbstractStorageDecl *SD = const_cast<AbstractStorageDecl*>(D); OS << getUSRSpacePrefix(); Mangler Mangler; Mangler.mangleAccessorEntity(AccKind, AddressorKind::NotAddressor, SD); Mangler.finalize(OS); return false; }
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!"); }
bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) { using namespace Mangle; if (!isa<FuncDecl>(D) && !D->hasName()) return true; // Ignore. if (D->getModuleContext()->isBuiltinModule()) return true; // Ignore. ValueDecl *VD = const_cast<ValueDecl *>(D); auto interpretAsClangNode = [](const ValueDecl *D)->ClangNode { ClangNode ClangN = D->getClangNode(); if (auto ClangD = ClangN.getAsDecl()) { // NSErrorDomain causes the clang enum to be imported like this: // // struct MyError { // enum Code : Int32 { // case errFirst // case errSecond // } // static var errFirst: MyError.Code { get } // static var errSecond: MyError.Code { get } // } // // The clang enum and enum constants are associated with both the // struct/nested enum, and the static vars/enum cases. // But we want unique USRs for the above symbols, so use the clang USR // for the enum and enum cases, and the Swift USR for the struct and vars. // if (isa<clang::EnumDecl>(ClangD)) { if (ClangD->hasAttr<clang::NSErrorDomainAttr>() && isa<StructDecl>(D)) return ClangNode(); } else if (auto *ClangEnumConst = dyn_cast<clang::EnumConstantDecl>(ClangD)) { if (auto *ClangEnum = dyn_cast<clang::EnumDecl>(ClangEnumConst->getDeclContext())) { if (ClangEnum->hasAttr<clang::NSErrorDomainAttr>() && isa<VarDecl>(D)) return ClangNode(); } } } return ClangN; }; if (ClangNode ClangN = interpretAsClangNode(D)) { llvm::SmallString<128> Buf; if (auto ClangD = ClangN.getAsDecl()) { bool Ignore = clang::index::generateUSRForDecl(ClangD, Buf); if (!Ignore) OS << Buf.str(); return Ignore; } auto &Importer = *D->getASTContext().getClangModuleLoader(); auto ClangMacroInfo = ClangN.getAsMacro(); auto PPRecord = Importer.getClangPreprocessor().getPreprocessingRecord(); assert(PPRecord && "Clang importer should be created with " "-detailed-preprocessing-record option"); auto ClangMacroDef = PPRecord->findMacroDefinition(ClangMacroInfo); bool Ignore = clang::index::generateUSRForMacro( ClangMacroDef, Importer.getClangASTContext().getSourceManager(), Buf); if (!Ignore) OS << Buf.str(); return Ignore; } if (!D->hasType()) return true; // FIXME: mangling 'self' in destructors crashes in mangler. if (isa<ParamDecl>(VD) && isa<DestructorDecl>(VD->getDeclContext())) return true; OS << getUSRSpacePrefix(); Mangler Mangler; Mangler.bindGenericParameters(VD->getDeclContext()); if (auto Ctor = dyn_cast<ConstructorDecl>(VD)) { Mangler.mangleConstructorEntity(Ctor, /*isAllocating=*/false, /*uncurryingLevel=*/0); } else if (auto Dtor = dyn_cast<DestructorDecl>(VD)) { Mangler.mangleDestructorEntity(Dtor, /*isDeallocating=*/false); } else if (auto NTD = dyn_cast<NominalTypeDecl>(VD)) { Mangler.mangleNominalType(NTD); } else if (isa<TypeAliasDecl>(VD) || isa<AssociatedTypeDecl>(VD)) { Mangler.mangleContextOf(VD); Mangler.mangleDeclName(VD); } else { Mangler.mangleEntity(VD, /*uncurryingLevel=*/0); } Mangler.finalize(OS); return false; }
/// 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!"); }