Example #1
0
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);
}