Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ClangImporter] Non-class member initializers are not "factory" inits. #8540

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 28 additions & 19 deletions lib/ClangImporter/ImportDecl.cpp
Expand Up @@ -3084,10 +3084,12 @@ namespace {

Decl *importGlobalAsInitializer(const clang::FunctionDecl *decl,
DeclName name, DeclContext *dc,
CtorInitializerKind initKind);
CtorInitializerKind initKind,
Optional<ImportedName> correctSwiftName);

Decl *importGlobalAsMethod(const clang::FunctionDecl *decl, DeclName name,
DeclContext *dc, Optional<unsigned> selfIdx);
DeclContext *dc, Optional<unsigned> selfIdx,
Optional<ImportedName> correctSwiftName);

/// Create an implicit property given the imported name of one of
/// the accessors.
Expand Down Expand Up @@ -3137,16 +3139,16 @@ namespace {

DeclName name = owningStorage ? DeclName() : importedName.getDeclName();
if (importedName.importAsMember()) {
assert(!correctSwiftName && "Swift 2 didn't support import-as-member!");

// Handle initializers.
if (name.getBaseName() == Impl.SwiftContext.Id_init)
return importGlobalAsInitializer(decl, name, dc,
importedName.getInitKind());
importedName.getInitKind(),
correctSwiftName);

// Everything else is a method.
return importGlobalAsMethod(decl, name, dc,
importedName.getSelfIndex());
importedName.getSelfIndex(),
correctSwiftName);
}

// Import the function type. If we have parameters, make sure their names
Expand Down Expand Up @@ -4705,12 +4707,8 @@ Decl *SwiftDeclConverter::importCompatibilityTypeAlias(
}
}

// Import the declaration context where this name will go. Note that
// this is the "natural" context for the declaration, without
// import-as-member inference or swift_name tricks.
EffectiveClangContext effectiveContext(
decl->getDeclContext()->getRedeclContext());
auto dc = Impl.importDeclContextOf(decl, effectiveContext);
auto dc = Impl.importDeclContextOf(decl,
compatibilityName.getEffectiveContext());
if (!dc)
return nullptr;

Expand Down Expand Up @@ -5054,10 +5052,12 @@ SwiftDeclConverter::importAsOptionSetType(DeclContext *dc, Identifier name,
return structDecl;
}

Decl *
SwiftDeclConverter::importGlobalAsInitializer(const clang::FunctionDecl *decl,
DeclName name, DeclContext *dc,
CtorInitializerKind initKind) {
Decl *SwiftDeclConverter::importGlobalAsInitializer(
const clang::FunctionDecl *decl,
DeclName name,
DeclContext *dc,
CtorInitializerKind initKind,
Optional<ImportedName> correctSwiftName) {
// TODO: Should this be an error? How can this come up?
assert(dc->isTypeContext() && "cannot import as member onto non-type");

Expand All @@ -5070,6 +5070,8 @@ SwiftDeclConverter::importGlobalAsInitializer(const clang::FunctionDecl *decl,
decl->getName());
return nullptr;
}
if (!dc->getAsClassOrClassExtensionContext())
initKind = CtorInitializerKind::Designated;

bool allowNSUIntegerAsInt =
Impl.shouldAllowNSUIntegerAsInt(isInSystemModule(dc), decl);
Expand Down Expand Up @@ -5124,12 +5126,17 @@ SwiftDeclConverter::importGlobalAsInitializer(const clang::FunctionDecl *decl,
result->setInterfaceType(allocType);

finishFuncDecl(decl, result);
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
return result;
}

Decl *SwiftDeclConverter::importGlobalAsMethod(const clang::FunctionDecl *decl,
DeclName name, DeclContext *dc,
Optional<unsigned> selfIdx) {
Decl *SwiftDeclConverter::importGlobalAsMethod(
const clang::FunctionDecl *decl,
DeclName name,
DeclContext *dc,
Optional<unsigned> selfIdx,
Optional<ImportedName> correctSwiftName) {
if (dc->getAsProtocolOrProtocolExtensionContext() && !selfIdx) {
// FIXME: source location...
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_protocol_static,
Expand Down Expand Up @@ -5206,6 +5213,8 @@ Decl *SwiftDeclConverter::importGlobalAsMethod(const clang::FunctionDecl *decl,
result->getAttrs().add(new (C) FinalAttr(/*IsImplicit=*/true));

finishFuncDecl(decl, result);
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
return result;
}

Expand Down
2 changes: 1 addition & 1 deletion test/APINotes/versioned.swift
Expand Up @@ -63,5 +63,5 @@ func testRenamedTopLevel() {

// CHECK-DIAGS-4-NOT: versioned.swift:[[@LINE+1]]:
_ = Outer.Inner()
// CHECK-DIAGS-3: versioned.swift:[[@LINE-1]]:7: error: type 'Outer' has no member 'Inner'
// CHECK-DIAGS-3: versioned.swift:[[@LINE-1]]:13: error: 'Inner' has been renamed to 'InnerInSwift4'
}
18 changes: 17 additions & 1 deletion test/IDE/Inputs/custom-modules/ImportAsMember.apinotes
Expand Up @@ -4,10 +4,26 @@ Globals:
SwiftName: Struct1.newApiNoteVar
- Name: IAMStruct1APINoteVarInSwift4
SwiftName: Struct1.apiNoteVarInSwift4
Functions:
- Name: IAMStruct1APINoteFunction
SwiftName: "Struct1.newApiNoteMethod()"
- Name: IAMStruct1APINoteCreateFunction
SwiftName: "Struct1.init(newLabel:)"
Typedefs:
- Name: IAMStruct1APINoteType
SwiftName: Struct1.NewApiNoteType
SwiftVersions:
- Version: 3
Globals:
- Name: IAMStruct1APINoteVar
SwiftName: Struct1.oldApiNoteVar
- Name: IAMStruct1APINoteVarInSwift4
SwiftName: IAMStruct1APINoteVarInSwift4
SwiftName: IAMStruct1APINoteVarInSwift4
Functions:
- Name: IAMStruct1APINoteFunction
SwiftName: "Struct1.oldApiNoteMethod()"
- Name: IAMStruct1APINoteCreateFunction
SwiftName: "Struct1.init(oldLabel:)"
Typedefs:
- Name: IAMStruct1APINoteType
SwiftName: Struct1.OldApiNoteType
5 changes: 5 additions & 0 deletions test/IDE/Inputs/custom-modules/ImportAsMemberAPINotes.h
Expand Up @@ -6,4 +6,9 @@
extern double IAMStruct1APINoteVar;
extern double IAMStruct1APINoteVarInSwift4;

extern void IAMStruct1APINoteFunction(void);
extern struct IAMStruct1 IAMStruct1APINoteCreateFunction(int);

typedef double IAMStruct1APINoteType;

#endif // IMPORT_AS_MEMBER_B_H
45 changes: 35 additions & 10 deletions test/IDE/import_as_member.swift
Expand Up @@ -4,8 +4,10 @@
// RUN: %FileCheck %s -check-prefix=PRINT -strict-whitespace < %t.printed.A.txt
// RUN: %FileCheck %s -check-prefix=PRINTB -strict-whitespace < %t.printed.B.txt

// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -I %t -I %S/Inputs/custom-modules -print-module -source-filename %s -module-to-print=ImportAsMember.APINotes -swift-version 3 -always-argument-labels | %FileCheck %s -check-prefix=PRINT-APINOTES-3 -strict-whitespace
// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -I %t -I %S/Inputs/custom-modules -print-module -source-filename %s -module-to-print=ImportAsMember.APINotes -swift-version 4 -always-argument-labels | %FileCheck %s -check-prefix=PRINT-APINOTES-4 -strict-whitespace
// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -I %t -I %S/Inputs/custom-modules -print-module -source-filename %s -module-to-print=ImportAsMember.APINotes -swift-version 3 -always-argument-labels | %FileCheck %s -check-prefix=PRINT-APINOTES-3 -implicit-check-not "not inherited" -strict-whitespace
// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -I %t -I %S/Inputs/custom-modules -print-module -source-filename %s -module-to-print=ImportAsMember.APINotes -swift-version 4 -always-argument-labels | %FileCheck %s -check-prefix=PRINT-APINOTES-4 -implicit-check-not "not inherited" -strict-whitespace

// RUN: %target-typecheck-verify-swift -I %S/Inputs/custom-modules

// PRINT: struct Struct1 {
// PRINT-NEXT: var x: Double
Expand Down Expand Up @@ -60,9 +62,24 @@
// PRINT-APINOTES-3-NEXT: var newApiNoteVar: Double
// PRINT-APINOTES-3-NEXT: @available(swift, introduced: 4, renamed: "IAMStruct1APINoteVarInSwift4")
// PRINT-APINOTES-3-NEXT: var apiNoteVarInSwift4: Double
// PRINT-APINOTES-3-NEXT: static func oldApiNoteMethod()
// PRINT-APINOTES-3-NEXT: @available(swift, introduced: 4, renamed: "Struct1.oldApiNoteMethod()")
// PRINT-APINOTES-3-NEXT: static func newApiNoteMethod()
// PRINT-APINOTES-3-NEXT: init(oldLabel _: Int32)
// PRINT-APINOTES-3-NEXT: @available(swift, introduced: 4, renamed: "Struct1.init(oldLabel:)")
// PRINT-APINOTES-3-NEXT: init(newLabel _: Int32)
// PRINT-APINOTES-3-NEXT: typealias OldApiNoteType = Double
// PRINT-APINOTES-3-NEXT: @available(swift, introduced: 4, renamed: "Struct1.OldApiNoteType")
// PRINT-APINOTES-3-NEXT: typealias NewApiNoteType = Struct1.OldApiNoteType
// PRINT-APINOTES-3-NEXT: }
// PRINT-APINOTES-3-NOT: @available
// PRINT-APINOTES-3: var IAMStruct1APINoteVarInSwift4: Double
// PRINT-APINOTES-3: var IAMStruct1APINoteVarInSwift4: Double
// PRINT-APINOTES-3: @available(swift, obsoleted: 3, renamed: "Struct1.oldApiNoteMethod()")
// PRINT-APINOTES-3-NEXT: func IAMStruct1APINoteFunction()
// PRINT-APINOTES-3: @available(swift, obsoleted: 3, renamed: "Struct1.init(oldLabel:)")
// PRINT-APINOTES-3-NEXT: func IAMStruct1APINoteCreateFunction(_ _: Int32) -> Struct1
// PRINT-APINOTES-3: @available(swift, obsoleted: 3, renamed: "Struct1.OldApiNoteType")
// PRINT-APINOTES-3-NEXT: typealias IAMStruct1APINoteType = Struct1.OldApiNoteType

// PRINT-APINOTES-4: @available(swift, obsoleted: 3, renamed: "Struct1.newApiNoteVar")
// PRINT-APINOTES-4-NEXT: var IAMStruct1APINoteVar: Double
Expand All @@ -71,11 +88,24 @@
// PRINT-APINOTES-4-NEXT: @available(swift, obsoleted: 4, renamed: "Struct1.newApiNoteVar")
// PRINT-APINOTES-4-NEXT: var oldApiNoteVar: Double
// PRINT-APINOTES-4-NEXT: var apiNoteVarInSwift4: Double
// PRINT-APINOTES-4-NEXT: static func newApiNoteMethod()
// PRINT-APINOTES-4-NEXT: @available(swift, obsoleted: 4, renamed: "Struct1.newApiNoteMethod()")
// PRINT-APINOTES-4-NEXT: static func oldApiNoteMethod()
// PRINT-APINOTES-4-NEXT: init(newLabel _: Int32)
// PRINT-APINOTES-4-NEXT: @available(swift, obsoleted: 4, renamed: "Struct1.init(newLabel:)")
// PRINT-APINOTES-4-NEXT: init(oldLabel _: Int32)
// PRINT-APINOTES-4-NEXT: typealias NewApiNoteType = Double
// PRINT-APINOTES-4-NEXT: @available(swift, obsoleted: 4, renamed: "Struct1.NewApiNoteType")
// PRINT-APINOTES-4-NEXT: typealias OldApiNoteType = Struct1.NewApiNoteType
// PRINT-APINOTES-4-NEXT: }
// PRINT-APINOTES-4: @available(swift, obsoleted: 4, renamed: "Struct1.apiNoteVarInSwift4")
// PRINT-APINOTES-4-NEXT: var IAMStruct1APINoteVarInSwift4: Double

// RUN: %target-typecheck-verify-swift -I %S/Inputs/custom-modules -verify-ignore-unknown
// PRINT-APINOTES-4: @available(swift, obsoleted: 3, renamed: "Struct1.newApiNoteMethod()")
// PRINT-APINOTES-4-NEXT: func IAMStruct1APINoteFunction()
// PRINT-APINOTES-4: @available(swift, obsoleted: 3, renamed: "Struct1.init(newLabel:)")
// PRINT-APINOTES-4-NEXT: func IAMStruct1APINoteCreateFunction(_ _: Int32) -> Struct1
// PRINT-APINOTES-4: @available(swift, obsoleted: 3, renamed: "Struct1.NewApiNoteType")
// PRINT-APINOTES-4-NEXT: typealias IAMStruct1APINoteType = Struct1.NewApiNoteType

import ImportAsMember.A
import ImportAsMember.B
Expand Down Expand Up @@ -105,8 +135,3 @@ iamStruct = Struct1.zero

// Global properties
currentStruct1.x += 1.5

// FIXME: Remove -verify-ignore-unknown.
// <unknown>:0: error: unexpected note produced: 'IAMStruct1CreateSimple' declared here
// <unknown>:0: error: unexpected note produced: 'IAMStruct1GlobalVar' was obsoleted in Swift 3
// <unknown>:0: error: unexpected note produced: 'IAMStruct1CreateSimple' was obsoleted in Swift 3