static SILValue getBehaviorInitStorageFn(SILGenFunction &SGF, VarDecl *behaviorVar) { Mangle::ASTMangler NewMangler; std::string behaviorInitName = NewMangler.mangleBehaviorInitThunk(behaviorVar); SILFunction *thunkFn; // Skip out early if we already emitted this thunk. if (auto existing = SGF.SGM.M.lookUpFunction(behaviorInitName)) { thunkFn = existing; } else { auto init = behaviorVar->getBehavior()->InitStorageDecl.getDecl(); auto initFn = SGF.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 = SGF.getLoweredType(selfTy).getFieldType(behaviorVar, SGF.SGM.M); auto storageTy = SGF.getLoweredType(selfTy).getFieldType(storageVar, SGF.SGM.M); auto initConstantTy = initFn->getLoweredType().castTo<SILFunctionType>(); auto param = SILParameterInfo(initTy.getASTType(), initTy.isAddress() ? ParameterConvention::Indirect_In : ParameterConvention::Direct_Owned); auto result = SILResultInfo(storageTy.getASTType(), storageTy.isAddress() ? ResultConvention::Indirect : ResultConvention::Owned); initConstantTy = SILFunctionType::get(initConstantTy->getGenericSignature(), initConstantTy->getExtInfo(), SILCoroutineKind::None, ParameterConvention::Direct_Unowned, param, /*yields*/ {}, result, // TODO: throwing initializer? None, SGF.getASTContext()); // TODO: Generate the body of the thunk. thunkFn = SGF.SGM.M.getOrCreateFunction(SILLocation(behaviorVar), behaviorInitName, SILLinkage::PrivateExternal, initConstantTy, IsBare, IsTransparent, IsSerialized); } return SGF.B.createFunctionRef(behaviorVar, thunkFn); }