mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[sil-module] Add a helper method to lookup or create a SILFunction based on the SILDeclRef.
This API is more convenient than using the old getOrCreate API, which requires 9 parameters to be provided. I'm going to use this API in the subsequent commits. Swift SVN r27097
This commit is contained in:
@@ -406,6 +406,12 @@ public:
|
|||||||
SILFunction::ClassVisibility_t CV =
|
SILFunction::ClassVisibility_t CV =
|
||||||
SILFunction::NotRelevant);
|
SILFunction::NotRelevant);
|
||||||
|
|
||||||
|
/// \brief Return the declaration of a function, or create it if it doesn't
|
||||||
|
/// exist..
|
||||||
|
SILFunction *getOrCreateFunction(SILLocation loc,
|
||||||
|
SILDeclRef constant,
|
||||||
|
ForDefinition_t forDefinition);
|
||||||
|
|
||||||
/// Look up the SILWitnessTable representing the lowering of a protocol
|
/// Look up the SILWitnessTable representing the lowering of a protocol
|
||||||
/// conformance, and collect the substitutions to apply to the referenced
|
/// conformance, and collect the substitutions to apply to the referenced
|
||||||
/// witnesses, if any.
|
/// witnesses, if any.
|
||||||
|
|||||||
@@ -242,6 +242,103 @@ SILFunction *SILModule::getOrCreateFunction(SILLocation loc,
|
|||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SILFunction::ClassVisibility_t getClassVisibility(SILDeclRef constant) {
|
||||||
|
if (!constant.hasDecl())
|
||||||
|
return SILFunction::NotRelevant;
|
||||||
|
|
||||||
|
// If this decleration is a function which goes into a vtable, then it's
|
||||||
|
// symbol must be as visible as its class. Derived classes even have to put
|
||||||
|
// all less visible methods of the base class into their vtables.
|
||||||
|
|
||||||
|
auto *FD = dyn_cast<AbstractFunctionDecl>(constant.getDecl());
|
||||||
|
if (!FD)
|
||||||
|
return SILFunction::NotRelevant;
|
||||||
|
|
||||||
|
DeclContext *context = FD->getDeclContext();
|
||||||
|
|
||||||
|
// Methods from extensions don't go into vtables (yet).
|
||||||
|
if (context->isExtensionContext())
|
||||||
|
return SILFunction::NotRelevant;
|
||||||
|
|
||||||
|
auto *classType = context->isClassOrClassExtensionContext();
|
||||||
|
if (!classType || classType->isFinal())
|
||||||
|
return SILFunction::NotRelevant;
|
||||||
|
|
||||||
|
if (FD->isFinal() && !FD->getOverriddenDecl())
|
||||||
|
return SILFunction::NotRelevant;
|
||||||
|
|
||||||
|
assert(FD->getEffectiveAccess() <= classType->getEffectiveAccess() &&
|
||||||
|
"class must be as visible as its members");
|
||||||
|
|
||||||
|
switch (classType->getEffectiveAccess()) {
|
||||||
|
case Accessibility::Private:
|
||||||
|
return SILFunction::NotRelevant;
|
||||||
|
case Accessibility::Internal:
|
||||||
|
return SILFunction::InternalClass;
|
||||||
|
case Accessibility::Public:
|
||||||
|
return SILFunction::PublicClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SILFunction *SILModule::getOrCreateFunction(SILLocation loc,
|
||||||
|
SILDeclRef constant,
|
||||||
|
ForDefinition_t forDefinition) {
|
||||||
|
|
||||||
|
SmallVector<char, 128> buffer;
|
||||||
|
auto name = constant.mangle(buffer);
|
||||||
|
auto constantType = Types.getConstantType(constant).castTo<SILFunctionType>();
|
||||||
|
SILLinkage linkage = constant.getLinkage(forDefinition);
|
||||||
|
|
||||||
|
if (auto fn = lookUpFunction(name)) {
|
||||||
|
assert(fn->getLoweredFunctionType() == constantType);
|
||||||
|
assert(fn->getLinkage() == linkage);
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsTransparent_t IsTrans = constant.isTransparent()?
|
||||||
|
IsTransparent : IsNotTransparent;
|
||||||
|
IsFragile_t IsFrag = IsNotFragile;
|
||||||
|
if (IsTrans == IsTransparent && (linkage == SILLinkage::Public
|
||||||
|
|| linkage == SILLinkage::PublicExternal)) {
|
||||||
|
IsFrag = IsFragile;
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectsKind EK = constant.hasEffectsAttribute() ?
|
||||||
|
constant.getEffectsAttribute() : EffectsKind::Unspecified;
|
||||||
|
|
||||||
|
Inline_t inlineStrategy = InlineDefault;
|
||||||
|
if (constant.isNoinline())
|
||||||
|
inlineStrategy = NoInline;
|
||||||
|
else if (constant.isAlwaysInline())
|
||||||
|
inlineStrategy = AlwaysInline;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
auto *F = SILFunction::create(*this, linkage, name,
|
||||||
|
constantType, nullptr,
|
||||||
|
None, IsNotBare, IsTrans, IsFrag, IsNotThunk,
|
||||||
|
getClassVisibility(constant),
|
||||||
|
inlineStrategy, EK);
|
||||||
|
|
||||||
|
if (forDefinition == ForDefinition_t::ForDefinition)
|
||||||
|
F->setDebugScope(new (*this) SILDebugScope(loc, *F));
|
||||||
|
|
||||||
|
F->setGlobalInit(constant.isGlobal());
|
||||||
|
if (constant.hasDecl())
|
||||||
|
if (auto SemanticsA =
|
||||||
|
constant.getDecl()->getAttrs().getAttribute<SemanticsAttr>())
|
||||||
|
F->setSemanticsAttr(SemanticsA->Value);
|
||||||
|
|
||||||
|
ValueDecl *VD = nullptr;
|
||||||
|
if (constant.hasDecl())
|
||||||
|
VD = constant.getDecl();
|
||||||
|
|
||||||
|
F->setDeclContext(VD);
|
||||||
|
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SILFunction *SILModule::getOrCreateSharedFunction(SILLocation loc,
|
SILFunction *SILModule::getOrCreateSharedFunction(SILLocation loc,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
CanSILFunctionType type,
|
CanSILFunctionType type,
|
||||||
|
|||||||
Reference in New Issue
Block a user