Example #1
0
/// 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()) {
    assert(!pd->getDeclContext()->isGenericContext()
           || pd->getDeclContext()->getGenericSignatureOfContext()
                ->areAllParamsConcrete());
  }

  // 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);

  Mangle::ASTMangler TokenMangler;
  std::string onceTokenBuffer = TokenMangler.mangleGlobalInit(varDecl, counter,
                                                              false);
  
  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
                                               ? IsSerialized
                                               : IsNotSerialized,
                                             onceTokenBuffer, onceSILTy);
  onceToken->setDeclaration(false);

  // Emit the initialization code into a function.
  Mangle::ASTMangler FuncMangler;
  std::string onceFuncBuffer = FuncMangler.mangleGlobalInit(varDecl, counter,
                                                            true);
  
  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));
}