SILValue SILGenFunction::emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant, SILConstantInfo constantInfo) { assert(constantInfo == getConstantInfo(constant)); // Builtins must be fully applied at the point of reference. if (constant.hasDecl() && isa<BuiltinUnit>(constant.getDecl()->getDeclContext())) { SGM.diagnose(loc.getSourceLoc(), diag::not_implemented, "delayed application of builtin"); return SILUndef::get(constantInfo.getSILType(), SGM.M); } // If the constant is a thunk we haven't emitted yet, emit it. if (!SGM.hasFunction(constant)) { if (constant.isCurried) { auto vd = constant.getDecl(); // Reference the next uncurrying level of the function. SILDeclRef next = SILDeclRef(vd, constant.kind, SILDeclRef::ConstructAtBestResilienceExpansion, constant.uncurryLevel + 1); // If the function is fully uncurried and natively foreign, reference its // foreign entry point. if (!next.isCurried) { if (requiresForeignToNativeThunk(vd)) next = next.asForeign(); } // Preserve whether the curry thunks lead to a direct reference to the // method implementation. next = next.asDirectReference(constant.isDirectReference); SGM.emitCurryThunk(vd, constant, next); } // Otherwise, if this is a calling convention thunk we haven't emitted yet, // emit it. else if (constant.isForeignToNativeThunk()) { SGM.emitForeignToNativeThunk(constant); } else if (constant.isNativeToForeignThunk()) { SGM.emitNativeToForeignThunk(constant); } else if (constant.kind == SILDeclRef::Kind::EnumElement) { SGM.emitEnumConstructor(cast<EnumElementDecl>(constant.getDecl())); } } auto f = SGM.getFunction(constant, NotForDefinition); assert(f->getLoweredFunctionType() == constantInfo.SILFnType); return B.createFunctionRef(loc, f); }