mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
With this patch, I'm flipping the polarity of things. The flag `-enable-experimental-feature ManualOwnership` now turns on the diagnostics, but they're all silenced by default. So, you need to add -Wwarning or -Werror to your build settings to turn on the specific diagnostics you care about. These are the diagnostic groups relevant to the feature: - SemanticCopies aka "explicit copies mode" - DynamicExclusivity For example, the build setting `-Werror SemanticCopies` now gives you errors about explicit copies, just as before, but now you can make them just warnings with -Wwarning. To opt-out a declaration from everything when using the feature, use @_noManualOwnership. @_manualOwnership is no longer an attribute as a result. resolves rdar://163372569
465 lines
20 KiB
C++
465 lines
20 KiB
C++
//===--- SILFunctionBuilder.cpp -------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/SIL/SILFunctionBuilder.h"
|
|
#include "swift/AST/ASTMangler.h"
|
|
#include "swift/AST/AttrKind.h"
|
|
#include "swift/AST/AvailabilityInference.h"
|
|
#include "swift/AST/Decl.h"
|
|
#include "swift/AST/DiagnosticsParse.h"
|
|
#include "swift/AST/DistributedDecl.h"
|
|
#include "swift/AST/Expr.h"
|
|
#include "swift/AST/ParameterList.h"
|
|
#include "swift/AST/SemanticAttrs.h"
|
|
#include "swift/Basic/Assertions.h"
|
|
#include "clang/AST/Mangle.h"
|
|
|
|
using namespace swift;
|
|
|
|
SILFunction *SILFunctionBuilder::getOrCreateFunction(
|
|
SILLocation loc, StringRef name, SILLinkage linkage,
|
|
CanSILFunctionType type, IsBare_t isBareSILFunction,
|
|
IsTransparent_t isTransparent, SerializedKind_t serializedKind,
|
|
IsDynamicallyReplaceable_t isDynamic, IsDistributed_t isDistributed,
|
|
IsRuntimeAccessible_t isRuntimeAccessible, ProfileCounter entryCount,
|
|
IsThunk_t isThunk, SubclassScope subclassScope) {
|
|
assert(!type->isNoEscape() && "Function decls always have escaping types.");
|
|
if (auto fn = mod.lookUpFunction(name)) {
|
|
assert(fn->getLoweredFunctionType() == type);
|
|
assert(stripExternalFromLinkage(fn->getLinkage()) ==
|
|
stripExternalFromLinkage(linkage) || mod.getOptions().EmbeddedSwift);
|
|
return fn;
|
|
}
|
|
|
|
auto fn = SILFunction::create(mod, linkage, name, type, nullptr, loc,
|
|
isBareSILFunction, isTransparent, serializedKind,
|
|
entryCount, isDynamic, isDistributed,
|
|
isRuntimeAccessible, IsNotExactSelfClass,
|
|
isThunk, subclassScope);
|
|
fn->setDebugScope(new (mod) SILDebugScope(loc, fn));
|
|
return fn;
|
|
}
|
|
|
|
void SILFunctionBuilder::addFunctionAttributes(
|
|
SILFunction *F, DeclAttributes &Attrs, SILModule &M,
|
|
llvm::function_ref<SILFunction *(SILLocation loc, SILDeclRef constant)>
|
|
getOrCreateDeclaration,
|
|
SILDeclRef constant) {
|
|
|
|
for (auto *A : Attrs.getAttributes<SemanticsAttr>())
|
|
F->addSemanticsAttr(cast<SemanticsAttr>(A)->Value);
|
|
|
|
// If we are asked to emit assembly vision remarks for this function, mark the
|
|
// function as force emitting all optremarks including assembly vision
|
|
// remarks. This allows us to emit the assembly vision remarks without needing
|
|
// to change any of the underlying optremark mechanisms.
|
|
if (Attrs.getAttribute(DeclAttrKind::EmitAssemblyVisionRemarks) ||
|
|
M.getOptions().EnableGlobalAssemblyVision)
|
|
F->addSemanticsAttr(semantics::FORCE_EMIT_OPT_REMARK_PREFIX);
|
|
|
|
// Propagate @_specialize.
|
|
for (auto *A : Attrs.getAttributes<AbstractSpecializeAttr>()) {
|
|
auto *SA = cast<AbstractSpecializeAttr>(A);
|
|
auto kind =
|
|
SA->getSpecializationKind() == SpecializeAttr::SpecializationKind::Full
|
|
? SILSpecializeAttr::SpecializationKind::Full
|
|
: SILSpecializeAttr::SpecializationKind::Partial;
|
|
assert(!constant.isNull());
|
|
SILFunction *targetFunction = nullptr;
|
|
auto *attributedFuncDecl = constant.getAbstractFunctionDecl();
|
|
auto *targetFunctionDecl = SA->getTargetFunctionDecl(attributedFuncDecl);
|
|
// Filter out _spi.
|
|
auto spiGroups = SA->getSPIGroups();
|
|
bool hasSPI = !spiGroups.empty();
|
|
if (hasSPI) {
|
|
if (attributedFuncDecl->getModuleContext() != M.getSwiftModule() &&
|
|
!M.getSwiftModule()->isImportedAsSPI(SA, attributedFuncDecl)) {
|
|
continue;
|
|
}
|
|
}
|
|
assert(spiGroups.size() <= 1 && "SIL does not support multiple SPI groups");
|
|
Identifier spiGroupIdent;
|
|
if (hasSPI) {
|
|
spiGroupIdent = spiGroups[0];
|
|
}
|
|
auto availability = AvailabilityInference::annotatedAvailableRangeForAttr(
|
|
attributedFuncDecl, SA, M.getSwiftModule()->getASTContext());
|
|
auto specializedSignature = SA->getSpecializedSignature(attributedFuncDecl);
|
|
if (targetFunctionDecl) {
|
|
SILDeclRef declRef(targetFunctionDecl, constant.kind, false);
|
|
targetFunction = getOrCreateDeclaration(targetFunctionDecl, declRef);
|
|
F->addSpecializeAttr(SILSpecializeAttr::create(
|
|
M, specializedSignature, SA->getTypeErasedParams(),
|
|
SA->isExported(), kind, targetFunction, spiGroupIdent,
|
|
attributedFuncDecl->getModuleContext(), availability));
|
|
} else {
|
|
F->addSpecializeAttr(SILSpecializeAttr::create(
|
|
M, specializedSignature, SA->getTypeErasedParams(),
|
|
SA->isExported(), kind, nullptr, spiGroupIdent,
|
|
attributedFuncDecl->getModuleContext(), availability));
|
|
}
|
|
}
|
|
|
|
llvm::SmallVector<const EffectsAttr *, 8> customEffects;
|
|
if (constant) {
|
|
for (auto *attr : Attrs.getAttributes<EffectsAttr>()) {
|
|
auto *effectsAttr = cast<EffectsAttr>(attr);
|
|
if (effectsAttr->getKind() == EffectsKind::Custom) {
|
|
customEffects.push_back(effectsAttr);
|
|
continue;
|
|
}
|
|
if (F->getEffectsKind() != EffectsKind::Unspecified) {
|
|
// If multiple known effects are specified, the most restrictive one
|
|
// is used.
|
|
F->setEffectsKind(
|
|
std::min(effectsAttr->getKind(), F->getEffectsKind()));
|
|
} else {
|
|
F->setEffectsKind(effectsAttr->getKind());
|
|
}
|
|
}
|
|
|
|
if (auto asmName = constant.getAsmName()) {
|
|
F->setAsmName(*asmName);
|
|
}
|
|
}
|
|
|
|
if (!customEffects.empty()) {
|
|
llvm::SmallVector<StringRef, 8> paramNames;
|
|
auto *fnDecl = cast<AbstractFunctionDecl>(constant.getDecl());
|
|
if (ParameterList *paramList = fnDecl->getParameters()) {
|
|
for (ParamDecl *pd : *paramList) {
|
|
// Give up on tuples. Their elements are added as individual
|
|
// arguments. It destroys the 1-1 relation ship between parameters
|
|
// and arguments.
|
|
if (pd->getInterfaceType()->is<TupleType>())
|
|
break;
|
|
// First try the "local" parameter name. If there is none, use the
|
|
// API name. E.g. `foo(apiName localName: Type) {}`
|
|
StringRef name = pd->getName().str();
|
|
if (name.empty())
|
|
name = pd->getArgumentName().str();
|
|
if (!name.empty())
|
|
paramNames.push_back(name);
|
|
}
|
|
}
|
|
for (const EffectsAttr *effectsAttr : llvm::reverse(customEffects)) {
|
|
auto error = F->parseArgumentEffectsFromSource(
|
|
effectsAttr->getCustomString(), paramNames);
|
|
if (error.first) {
|
|
SourceLoc loc = effectsAttr->getCustomStringLocation();
|
|
if (loc.isValid())
|
|
loc = loc.getAdvancedLoc(error.second);
|
|
mod.getASTContext().Diags.diagnose(loc,
|
|
diag::warning_in_effects_attribute, StringRef(error.first));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (auto *OA = Attrs.getAttribute<OptimizeAttr>()) {
|
|
F->setOptimizationMode(OA->getMode());
|
|
}
|
|
|
|
// @_silgen_name and @_cdecl functions may be called from C code somewhere.
|
|
if (Attrs.hasAttribute<SILGenNameAttr>() || Attrs.hasAttribute<CDeclAttr>())
|
|
F->setHasCReferences(true);
|
|
|
|
for (auto *EA : Attrs.getAttributes<ExposeAttr>()) {
|
|
bool shouldExportDecl = true;
|
|
if (Attrs.hasAttribute<CDeclAttr>()) {
|
|
// If the function is marked with @c, expose only C compatible
|
|
// thunk function.
|
|
shouldExportDecl = constant.isNativeToForeignThunk();
|
|
}
|
|
if (EA->getExposureKind() == ExposureKind::Wasm && shouldExportDecl) {
|
|
// A wasm-level exported function must be retained if it appears in a
|
|
// compilation unit.
|
|
F->setMarkedAsUsed(true);
|
|
if (EA->Name.empty())
|
|
F->setWasmExportName(F->getName());
|
|
else
|
|
F->setWasmExportName(EA->Name);
|
|
}
|
|
}
|
|
|
|
if (auto *EA = ExternAttr::find(Attrs, ExternKind::Wasm)) {
|
|
// @_extern(wasm) always has explicit names
|
|
F->setWasmImportModuleAndField(*EA->ModuleName, *EA->Name);
|
|
}
|
|
|
|
if (Attrs.hasAttribute<UsedAttr>())
|
|
F->setMarkedAsUsed(true);
|
|
|
|
if (Attrs.hasAttribute<NoLocksAttr>()) {
|
|
F->setPerfConstraints(PerformanceConstraints::NoLocks);
|
|
} else if (Attrs.hasAttribute<NoAllocationAttr>()) {
|
|
F->setPerfConstraints(PerformanceConstraints::NoAllocation);
|
|
} else if (Attrs.hasAttribute<NoRuntimeAttr>()) {
|
|
F->setPerfConstraints(PerformanceConstraints::NoRuntime);
|
|
} else if (Attrs.hasAttribute<NoExistentialsAttr>()) {
|
|
F->setPerfConstraints(PerformanceConstraints::NoExistentials);
|
|
} else if (Attrs.hasAttribute<NoObjCBridgingAttr>()) {
|
|
F->setPerfConstraints(PerformanceConstraints::NoObjCBridging);
|
|
} else if (M.getASTContext().LangOpts.hasFeature(Feature::ManualOwnership) &&
|
|
constant && constant.hasDecl() && !constant.isImplicit() &&
|
|
!Attrs.hasAttribute<NoManualOwnershipAttr>()) {
|
|
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
|
|
}
|
|
|
|
if (Attrs.hasAttribute<LexicalLifetimesAttr>()) {
|
|
F->setForceEnableLexicalLifetimes(DoForceEnableLexicalLifetimes);
|
|
}
|
|
|
|
if (Attrs.hasAttribute<UnsafeNonEscapableResultAttr>()) {
|
|
F->setHasUnsafeNonEscapableResult(true);
|
|
}
|
|
|
|
// Validate `@differentiable` attributes by calling `getParameterIndices`.
|
|
// This is important for:
|
|
// - Skipping invalid `@differentiable` attributes in non-primary files.
|
|
// - Preventing duplicate SIL differentiability witness creation for
|
|
// `@differentiable` attributes on `AbstractStorageDecl` declarations.
|
|
// Such `@differentiable` attributes are deleted and recreated on the getter
|
|
// `AccessorDecl` of the `AbstractStorageDecl`.
|
|
for (auto *A : Attrs.getAttributes<DifferentiableAttr>())
|
|
(void)A->getParameterIndices();
|
|
|
|
// Propagate `@noDerivative` as `[_semantics "autodiff.nonvarying"]`.
|
|
//
|
|
// `@noDerivative` implies non-varying semantics for differentiable activity
|
|
// analysis. SIL values produced from references to `@noDerivative`
|
|
// declarations will not be marked as varying; these values do not need a
|
|
// derivative.
|
|
if (Attrs.hasAttribute<NoDerivativeAttr>())
|
|
F->addSemanticsAttr("autodiff.nonvarying");
|
|
|
|
// Propagate @_dynamicReplacement(for:).
|
|
if (constant.isNull())
|
|
return;
|
|
auto *decl = constant.getDecl();
|
|
|
|
// Don't add section for addressor functions (where decl is a global)
|
|
if (isa<FuncDecl>(decl)) {
|
|
if (auto *SA = Attrs.getAttribute<SectionAttr>())
|
|
F->setSection(SA->Name);
|
|
}
|
|
|
|
// Only emit replacements for the objc entry point of objc methods.
|
|
// There is one exception: @_dynamicReplacement(for:) of @objc methods in
|
|
// generic classes. In this special case we use native replacement instead of
|
|
// @objc categories.
|
|
if (decl->isObjC() && !decl->isNativeMethodReplacement() &&
|
|
F->getLoweredFunctionType()->getExtInfo().getRepresentation() !=
|
|
SILFunctionTypeRepresentation::ObjCMethod)
|
|
return;
|
|
|
|
// Only assign replacements when the thing being replaced is function-like and
|
|
// explicitly declared.
|
|
auto *origDecl = decl->getDynamicallyReplacedDecl();
|
|
if (auto *replacedDecl = dyn_cast_or_null<AbstractFunctionDecl>(origDecl)) {
|
|
// For @objc method replacement we normally use categories to perform the
|
|
// replacement. Except for methods in generic class where we can't. Instead,
|
|
// we special case this and use the native swift replacement mechanism.
|
|
if (decl->isObjC() && !decl->isNativeMethodReplacement()) {
|
|
F->setObjCReplacement(replacedDecl);
|
|
return;
|
|
}
|
|
|
|
if (constant.canBeDynamicReplacement()) {
|
|
SILDeclRef declRef(replacedDecl, constant.kind, false);
|
|
auto *replacedFunc = getOrCreateDeclaration(replacedDecl, declRef);
|
|
|
|
assert(replacedFunc->getLoweredFunctionType() ==
|
|
F->getLoweredFunctionType() ||
|
|
replacedFunc->getLoweredFunctionType()->hasOpaqueArchetype());
|
|
|
|
F->setDynamicallyReplacedFunction(replacedFunc);
|
|
}
|
|
} else if (constant.isDistributedThunk()) {
|
|
// It's okay for `decodeFuncDecl` to be null because system could be
|
|
// generic.
|
|
if (auto decodeFuncDecl =
|
|
getAssociatedDistributedInvocationDecoderDecodeNextArgumentFunction(
|
|
decl)) {
|
|
auto decodeRef = SILDeclRef(decodeFuncDecl);
|
|
auto *adHocFunc = getOrCreateDeclaration(decodeFuncDecl, decodeRef);
|
|
F->setReferencedAdHocRequirementWitnessFunction(adHocFunc);
|
|
}
|
|
}
|
|
}
|
|
|
|
SILFunction *SILFunctionBuilder::getOrCreateFunction(
|
|
SILLocation loc, SILDeclRef constant, ForDefinition_t forDefinition,
|
|
llvm::function_ref<SILFunction *(SILLocation loc, SILDeclRef constant)>
|
|
getOrCreateDeclaration,
|
|
ProfileCounter entryCount) {
|
|
auto nameTmp = constant.mangle();
|
|
auto constantType = mod.Types.getConstantFunctionType(
|
|
TypeExpansionContext::minimal(), constant);
|
|
SILLinkage linkage = constant.getLinkage(forDefinition);
|
|
|
|
if (auto fn = mod.lookUpFunction(nameTmp)) {
|
|
// During SILGen (where the module's SIL stage is Raw), there might be
|
|
// mismatches between the type or linkage. This can happen, when two
|
|
// functions are mistakenly mapped to the same name (e.g. with @_cdecl).
|
|
// We want to issue a regular error in this case and not crash with an
|
|
// assert.
|
|
assert(mod.getStage() == SILStage::Raw ||
|
|
fn->getLoweredFunctionType() == constantType);
|
|
auto linkageForDef = constant.getLinkage(ForDefinition_t::ForDefinition);
|
|
auto fnLinkage = fn->getLinkage();
|
|
assert(mod.getStage() == SILStage::Raw || fn->getLinkage() == linkage ||
|
|
(forDefinition == ForDefinition_t::NotForDefinition &&
|
|
(fnLinkage == linkageForDef ||
|
|
(linkageForDef == SILLinkage::PublicNonABI ||
|
|
linkageForDef == SILLinkage::PackageNonABI) &&
|
|
fnLinkage == SILLinkage::Shared)));
|
|
if (forDefinition) {
|
|
// In all the cases where getConstantLinkage returns something
|
|
// different for ForDefinition, it returns an available-externally
|
|
// linkage.
|
|
if (isAvailableExternally(fn->getLinkage())) {
|
|
fn->setLinkage(constant.getLinkage(ForDefinition));
|
|
}
|
|
}
|
|
return fn;
|
|
}
|
|
|
|
IsTransparent_t IsTrans =
|
|
constant.isTransparent() ? IsTransparent : IsNotTransparent;
|
|
|
|
SerializedKind_t IsSer = constant.getSerializedKind();
|
|
// Don't create a [serialized] function after serialization has happened.
|
|
if (IsSer != IsNotSerialized && mod.isSerialized())
|
|
IsSer = IsNotSerialized;
|
|
|
|
Inline_t inlineStrategy = InlineDefault;
|
|
if (constant.isNoinline())
|
|
inlineStrategy = NoInline;
|
|
else if (constant.isUnderscoredAlwaysInline())
|
|
inlineStrategy = HeuristicAlwaysInline;
|
|
else if (constant.isAlwaysInline())
|
|
inlineStrategy = AlwaysInline;
|
|
|
|
StringRef name = mod.allocateCopy(nameTmp);
|
|
IsDynamicallyReplaceable_t IsDyn = IsNotDynamic;
|
|
if (constant.isDynamicallyReplaceable()) {
|
|
IsDyn = IsDynamic;
|
|
IsTrans = IsNotTransparent;
|
|
}
|
|
|
|
IsDistributed_t IsDistributed = IsDistributed_t::IsNotDistributed;
|
|
// Mark both distributed thunks and methods as distributed.
|
|
if (constant.hasFuncDecl() && constant.getFuncDecl()->isDistributed()) {
|
|
IsDistributed = IsDistributed_t::IsDistributed;
|
|
}
|
|
|
|
IsRuntimeAccessible_t isRuntimeAccessible = IsNotRuntimeAccessible;
|
|
|
|
auto *F = SILFunction::create(
|
|
mod, linkage, name, constantType, nullptr, std::nullopt, IsNotBare,
|
|
IsTrans, IsSer, entryCount, IsDyn, IsDistributed, isRuntimeAccessible,
|
|
IsNotExactSelfClass, IsNotThunk, constant.getSubclassScope(),
|
|
inlineStrategy);
|
|
F->setDebugScope(new (mod) SILDebugScope(loc, F));
|
|
|
|
if (constant.isGlobal())
|
|
F->setSpecialPurpose(SILFunction::Purpose::GlobalInit);
|
|
|
|
if (constant.hasDecl()) {
|
|
auto decl = constant.getDecl();
|
|
|
|
if (constant.isForeign && decl->hasClangNode() &&
|
|
!decl->getObjCImplementationDecl())
|
|
F->setClangNodeOwner(decl);
|
|
|
|
if (auto availability = constant.getAvailabilityForLinkage())
|
|
F->setAvailabilityForLinkage(*availability);
|
|
|
|
F->setIsAlwaysWeakImported(decl->isAlwaysWeakImported());
|
|
|
|
if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {
|
|
auto *storage = accessor->getStorage();
|
|
// Add attributes for e.g. computed properties.
|
|
ASSERT(ABIRoleInfo(storage).providesAPI()
|
|
&& "addFunctionAttributes() on ABI-only accessor?");
|
|
|
|
addFunctionAttributes(F, storage->getAttrs(), mod,
|
|
getOrCreateDeclaration);
|
|
|
|
auto *varDecl = dyn_cast<VarDecl>(storage);
|
|
if (varDecl && varDecl->getAttrs().hasAttribute<LazyAttr>() &&
|
|
accessor->getAccessorKind() == AccessorKind::Get) {
|
|
F->setSpecialPurpose(SILFunction::Purpose::LazyPropertyGetter);
|
|
|
|
// Lazy property getters should not get inlined because they are usually
|
|
// non-trivial functions (otherwise the user would not implement it as
|
|
// lazy property). Inlining such getters would most likely not benefit
|
|
// other optimizations because the top-level switch_enum cannot be
|
|
// constant folded in most cases.
|
|
// Also, not inlining lazy property getters enables optimizing them in
|
|
// CSE.
|
|
F->setInlineStrategy(NoInline);
|
|
}
|
|
}
|
|
ASSERT(ABIRoleInfo(decl).providesAPI()
|
|
&& "addFunctionAttributes() on ABI-only decl?");
|
|
addFunctionAttributes(F, decl->getAttrs(), mod, getOrCreateDeclaration,
|
|
constant);
|
|
} else if (auto *ce = constant.getAbstractClosureExpr()) {
|
|
if (mod.getOptions().EnableGlobalAssemblyVision) {
|
|
F->addSemanticsAttr(semantics::FORCE_EMIT_OPT_REMARK_PREFIX);
|
|
} else {
|
|
// Add the attribute to a closure if the enclosing method has it.
|
|
auto decl = ce->getParent()->getInnermostDeclarationDeclContext();
|
|
if (decl &&
|
|
decl->getAttrs().getAttribute(DeclAttrKind::EmitAssemblyVisionRemarks)) {
|
|
F->addSemanticsAttr(semantics::FORCE_EMIT_OPT_REMARK_PREFIX);
|
|
}
|
|
}
|
|
} else {
|
|
if (mod.getOptions().EnableGlobalAssemblyVision) {
|
|
F->addSemanticsAttr(semantics::FORCE_EMIT_OPT_REMARK_PREFIX);
|
|
}
|
|
}
|
|
|
|
return F;
|
|
}
|
|
|
|
SILFunction *SILFunctionBuilder::getOrCreateSharedFunction(
|
|
SILLocation loc, StringRef name, CanSILFunctionType type,
|
|
IsBare_t isBareSILFunction, IsTransparent_t isTransparent,
|
|
SerializedKind_t serializedKind, ProfileCounter entryCount, IsThunk_t isThunk,
|
|
IsDynamicallyReplaceable_t isDynamic, IsDistributed_t isDistributed,
|
|
IsRuntimeAccessible_t isRuntimeAccessible) {
|
|
return getOrCreateFunction(loc, name, SILLinkage::Shared, type,
|
|
isBareSILFunction, isTransparent, serializedKind,
|
|
isDynamic, isDistributed, isRuntimeAccessible,
|
|
entryCount, isThunk, SubclassScope::NotApplicable);
|
|
}
|
|
|
|
SILFunction *SILFunctionBuilder::createFunction(
|
|
SILLinkage linkage, StringRef name, CanSILFunctionType loweredType,
|
|
GenericEnvironment *genericEnv, std::optional<SILLocation> loc,
|
|
IsBare_t isBareSILFunction, IsTransparent_t isTrans,
|
|
SerializedKind_t serializedKind, IsDynamicallyReplaceable_t isDynamic,
|
|
IsDistributed_t isDistributed, IsRuntimeAccessible_t isRuntimeAccessible,
|
|
ProfileCounter entryCount, IsThunk_t isThunk, SubclassScope subclassScope,
|
|
Inline_t inlineStrategy, EffectsKind EK, SILFunction *InsertBefore,
|
|
const SILDebugScope *DebugScope) {
|
|
return SILFunction::create(mod, linkage, name, loweredType, genericEnv, loc,
|
|
isBareSILFunction, isTrans, serializedKind,
|
|
entryCount, isDynamic, isDistributed,
|
|
isRuntimeAccessible, IsNotExactSelfClass, isThunk,
|
|
subclassScope, inlineStrategy, EK, InsertBefore,
|
|
DebugScope);
|
|
}
|