Skip to content

Commit 971fb0a

Browse files
authored
Refactor away importGlobalAsMethod. (#26683)
1 parent 9b338c4 commit 971fb0a

File tree

1 file changed

+102
-134
lines changed

1 file changed

+102
-134
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 102 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -3599,11 +3599,6 @@ namespace {
35993599
CtorInitializerKind initKind,
36003600
Optional<ImportedName> correctSwiftName);
36013601

3602-
Decl *importGlobalAsMethod(const clang::FunctionDecl *decl, DeclName name,
3603-
DeclContext *dc, Optional<unsigned> selfIdx,
3604-
Optional<ImportedName> correctSwiftName,
3605-
Optional<AccessorInfo> accessorInfo);
3606-
36073602
/// Create an implicit property given the imported name of one of
36083603
/// the accessors.
36093604
VarDecl *getImplicitProperty(ImportedName importedName,
@@ -3651,7 +3646,12 @@ namespace {
36513646
return nullptr;
36523647

36533648
DeclName name = accessorInfo ? DeclName() : importedName.getDeclName();
3649+
auto selfIdx = importedName.getSelfIndex();
36543650

3651+
FuncDecl *result = nullptr;
3652+
ImportedType importedType;
3653+
bool selfIsInOut = false;
3654+
ParameterList *bodyParams = nullptr;
36553655
if (!dc->isModuleScopeContext() && !isa<clang::CXXMethodDecl>(decl)) {
36563656
// Handle initializers.
36573657
if (name.getBaseName() == DeclBaseName::createConstructor()) {
@@ -3661,23 +3661,78 @@ namespace {
36613661
correctSwiftName);
36623662
}
36633663

3664-
// Everything else is a method.
3665-
return importGlobalAsMethod(decl, name, dc,
3666-
importedName.getSelfIndex(),
3667-
correctSwiftName, accessorInfo);
3668-
}
3664+
if (dc->getSelfProtocolDecl() && !selfIdx) {
3665+
// FIXME: source location...
3666+
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_protocol_static,
3667+
/*isInit=*/false);
3668+
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
3669+
decl->getName());
3670+
return nullptr;
3671+
}
36693672

3670-
// Import the function type. If we have parameters, make sure their names
3671-
// get into the resulting function type.
3672-
ParameterList *bodyParams = nullptr;
3673-
auto importedType = Impl.importFunctionType(
3674-
dc, decl, {decl->param_begin(), decl->param_size()},
3675-
decl->isVariadic(), isInSystemModule(dc), name, bodyParams);
3676-
if (!importedType)
3677-
return nullptr;
3673+
if (!decl->hasPrototype()) {
3674+
// FIXME: source location...
3675+
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_no_prototype);
3676+
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
3677+
decl->getName());
3678+
return nullptr;
3679+
}
36783680

3679-
auto resultTy = importedType.getType();
3680-
auto loc = Impl.importSourceLoc(decl->getLocation());
3681+
// There is an inout 'self' when the parameter is a pointer to a
3682+
// non-const instance of the type we're importing onto. Importing this
3683+
// as a method means that the method should be treated as mutating in
3684+
// this situation.
3685+
if (selfIdx &&
3686+
!dc->getDeclaredInterfaceType()->hasReferenceSemantics()) {
3687+
auto selfParam = decl->getParamDecl(*selfIdx);
3688+
auto selfParamTy = selfParam->getType();
3689+
if ((selfParamTy->isPointerType() ||
3690+
selfParamTy->isReferenceType()) &&
3691+
!selfParamTy->getPointeeType().isConstQualified()) {
3692+
selfIsInOut = true;
3693+
3694+
// If there's a swift_newtype, check the levels of indirection: self
3695+
// is only inout if this is a pointer to the typedef type (which
3696+
// itself is a pointer).
3697+
if (auto nominalTypeDecl = dc->getSelfNominalTypeDecl()) {
3698+
if (auto clangDCTy = dyn_cast_or_null<clang::TypedefNameDecl>(
3699+
nominalTypeDecl->getClangDecl()))
3700+
if (getSwiftNewtypeAttr(clangDCTy, getVersion()))
3701+
if (clangDCTy->getUnderlyingType().getCanonicalType() !=
3702+
selfParamTy->getPointeeType().getCanonicalType())
3703+
selfIsInOut = false;
3704+
}
3705+
}
3706+
}
3707+
3708+
bool allowNSUIntegerAsInt =
3709+
Impl.shouldAllowNSUIntegerAsInt(isInSystemModule(dc), decl);
3710+
3711+
bodyParams =
3712+
getNonSelfParamList(dc, decl, selfIdx, name.getArgumentNames(),
3713+
allowNSUIntegerAsInt, !name);
3714+
3715+
importedType =
3716+
Impl.importFunctionReturnType(dc, decl, allowNSUIntegerAsInt);
3717+
} else {
3718+
// Import the function type. If we have parameters, make sure their
3719+
// names get into the resulting function type.
3720+
importedType = Impl.importFunctionType(
3721+
dc, decl, {decl->param_begin(), decl->param_size()},
3722+
decl->isVariadic(), isInSystemModule(dc), name, bodyParams);
3723+
3724+
if (auto *mdecl = dyn_cast<clang::CXXMethodDecl>(decl)) {
3725+
if (!mdecl->isStatic()) {
3726+
selfIdx = 0;
3727+
// Workaround until proper const support is handled: Force
3728+
// everything to be mutating. This implicitly makes the parameter
3729+
// indirect.
3730+
selfIsInOut = true;
3731+
} else {
3732+
selfIdx = None;
3733+
}
3734+
}
3735+
}
36813736

36823737
if (name && name.isSimpleName()) {
36833738
assert(importedName.hasCustomName() &&
@@ -3686,34 +3741,46 @@ namespace {
36863741
name = DeclName(Impl.SwiftContext, name.getBaseName(), bodyParams);
36873742
}
36883743

3744+
if (!importedType)
3745+
return nullptr;
3746+
3747+
auto resultTy = importedType.getType();
3748+
auto loc = Impl.importSourceLoc(decl->getLocation());
3749+
36893750
// FIXME: Poor location info.
36903751
auto nameLoc = Impl.importSourceLoc(decl->getLocation());
3691-
FuncDecl *result = createFuncOrAccessor(Impl.SwiftContext, loc,
3692-
accessorInfo, name, nameLoc,
3693-
bodyParams, resultTy,
3694-
/*throws*/ false,
3695-
dc, decl);
3696-
3697-
if (auto *mdecl = dyn_cast<clang::CXXMethodDecl>(decl)) {
3698-
if (!mdecl->isStatic()) {
3699-
// Workaround until proper const support is handled: Force
3700-
// everything to be mutating. This implicitly makes the parameter
3701-
// indirect.
3752+
result = createFuncOrAccessor(Impl.SwiftContext, loc, accessorInfo, name,
3753+
nameLoc, bodyParams, resultTy,
3754+
/*throws*/ false, dc, decl);
3755+
3756+
result->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
3757+
3758+
if (!dc->isModuleScopeContext()) {
3759+
if (selfIsInOut)
37023760
result->setSelfAccessKind(SelfAccessKind::Mutating);
3703-
// "self" is the first argument.
3704-
result->setSelfIndex(0);
3761+
else
3762+
result->setSelfAccessKind(SelfAccessKind::NonMutating);
3763+
if (selfIdx) {
3764+
result->setSelfIndex(selfIdx.getValue());
37053765
} else {
37063766
result->setStatic();
37073767
result->setImportAsStaticMember();
37083768
}
37093769
}
3710-
result->computeType();
3711-
result->setValidationToChecked();
3770+
37123771
result->setIsObjC(false);
37133772
result->setIsDynamic(false);
3773+
result->computeType();
3774+
result->setValidationToChecked();
3775+
37143776
Impl.recordImplicitUnwrapForDecl(result,
37153777
importedType.isImplicitlyUnwrapped());
37163778

3779+
if (dc->getSelfClassDecl())
3780+
// FIXME: only if the class itself is not marked final
3781+
result->getAttrs().add(new (Impl.SwiftContext)
3782+
FinalAttr(/*IsImplicit=*/true));
3783+
37173784
// Someday, maybe this will need to be 'open' for C++ virtual methods.
37183785
result->setAccess(AccessLevel::Public);
37193786
finishFuncDecl(decl, result);
@@ -5780,105 +5847,6 @@ Decl *SwiftDeclConverter::importGlobalAsInitializer(
57805847
return result;
57815848
}
57825849

5783-
Decl *SwiftDeclConverter::importGlobalAsMethod(
5784-
const clang::FunctionDecl *decl,
5785-
DeclName name,
5786-
DeclContext *dc,
5787-
Optional<unsigned> selfIdx,
5788-
Optional<ImportedName> correctSwiftName,
5789-
Optional<AccessorInfo> accessorInfo) {
5790-
if (dc->getSelfProtocolDecl() && !selfIdx) {
5791-
// FIXME: source location...
5792-
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_protocol_static,
5793-
/*isInit=*/false);
5794-
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
5795-
decl->getName());
5796-
return nullptr;
5797-
}
5798-
5799-
if (!decl->hasPrototype()) {
5800-
// FIXME: source location...
5801-
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_no_prototype);
5802-
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
5803-
decl->getName());
5804-
return nullptr;
5805-
}
5806-
5807-
bool allowNSUIntegerAsInt =
5808-
Impl.shouldAllowNSUIntegerAsInt(isInSystemModule(dc), decl);
5809-
5810-
auto &C = Impl.SwiftContext;
5811-
// There is an inout 'self' when the parameter is a pointer to a non-const
5812-
// instance of the type we're importing onto. Importing this as a method means
5813-
// that the method should be treated as mutating in this situation.
5814-
bool selfIsInOut = false;
5815-
if (selfIdx && !dc->getDeclaredInterfaceType()->hasReferenceSemantics()) {
5816-
auto selfParam = decl->getParamDecl(*selfIdx);
5817-
auto selfParamTy = selfParam->getType();
5818-
if ((selfParamTy->isPointerType() || selfParamTy->isReferenceType()) &&
5819-
!selfParamTy->getPointeeType().isConstQualified()) {
5820-
selfIsInOut = true;
5821-
5822-
// If there's a swift_newtype, check the levels of indirection: self is
5823-
// only inout if this is a pointer to the typedef type (which itself is a
5824-
// pointer).
5825-
if (auto nominalTypeDecl = dc->getSelfNominalTypeDecl()) {
5826-
if (auto clangDCTy = dyn_cast_or_null<clang::TypedefNameDecl>(
5827-
nominalTypeDecl->getClangDecl()))
5828-
if (getSwiftNewtypeAttr(clangDCTy, getVersion()))
5829-
if (clangDCTy->getUnderlyingType().getCanonicalType() !=
5830-
selfParamTy->getPointeeType().getCanonicalType())
5831-
selfIsInOut = false;
5832-
}
5833-
}
5834-
}
5835-
5836-
auto *bodyParams = getNonSelfParamList(
5837-
dc, decl, selfIdx, name.getArgumentNames(), allowNSUIntegerAsInt, !name);
5838-
5839-
auto importedType =
5840-
Impl.importFunctionReturnType(dc, decl, allowNSUIntegerAsInt);
5841-
Type swiftResultTy = importedType.getType();
5842-
5843-
auto loc = Impl.importSourceLoc(decl->getLocation());
5844-
auto nameLoc = Impl.importSourceLoc(decl->getLocation());
5845-
auto result =
5846-
createFuncOrAccessor(C, loc, accessorInfo, name, nameLoc,
5847-
bodyParams, swiftResultTy,
5848-
/*throws*/ false, dc, decl);
5849-
5850-
result->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
5851-
5852-
result->setAccess(AccessLevel::Public);
5853-
if (selfIsInOut)
5854-
result->setSelfAccessKind(SelfAccessKind::Mutating);
5855-
else
5856-
result->setSelfAccessKind(SelfAccessKind::NonMutating);
5857-
if (selfIdx) {
5858-
result->setSelfIndex(selfIdx.getValue());
5859-
} else {
5860-
result->setStatic();
5861-
result->setImportAsStaticMember();
5862-
}
5863-
5864-
result->computeType();
5865-
result->setValidationToChecked();
5866-
5867-
Impl.recordImplicitUnwrapForDecl(result,
5868-
importedType.isImplicitlyUnwrapped());
5869-
5870-
assert(selfIdx ? result->getSelfIndex() == *selfIdx
5871-
: result->isImportAsStaticMember());
5872-
5873-
if (dc->getSelfClassDecl())
5874-
// FIXME: only if the class itself is not marked final
5875-
result->getAttrs().add(new (C) FinalAttr(/*IsImplicit=*/true));
5876-
5877-
finishFuncDecl(decl, result);
5878-
if (correctSwiftName)
5879-
markAsVariant(result, *correctSwiftName);
5880-
return result;
5881-
}
58825850

58835851
/// Create an implicit property given the imported name of one of
58845852
/// the accessors.

0 commit comments

Comments
 (0)