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