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

[SR-6958] ClangImporter ignore aliased Objective-C type name #49506

Open
krzyzanowskim opened this issue Feb 8, 2018 · 16 comments
Open

[SR-6958] ClangImporter ignore aliased Objective-C type name #49506

krzyzanowskim opened this issue Feb 8, 2018 · 16 comments

Comments

@krzyzanowskim
Copy link
Contributor

krzyzanowskim commented Feb 8, 2018

Previous ID SR-6958
Radar rdar://problem/37470600
Original Reporter @krzyzanowskim
Type Bug
Environment

Swift 4.0.3. Xcode 9.2

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, ClangImporter
Assignee None
Priority Medium

md5: 5ad94f5dd12a2f7cc4f9b104597dfc1f

Issue Description:

When importing Objective-C function signature with basic primitive type aliased with the typedef, the function is imported with the aliased type name, not with the used alias:

Objective-C

typedef NSUInteger PageIndex;

- (nullable NSURL *)pathForPageAtIndex:(PageIndex)pageIndex;

Swift

func pathForPage(at pageIndex: UInt) -> URL?

Expected behavior:

func pathForPage(at pageIndex: PageIndex) -> URL?
@swift-ci
Copy link
Collaborator

swift-ci commented Feb 8, 2018

Comment by Peter Steinberger (JIRA)

This would make a lot of our API much nicer. Thanks for filing that one!

@belkadan
Copy link
Contributor

belkadan commented Feb 9, 2018

It's supposed to already do that. Do you have a self-contained example where it isn't?

@belkadan
Copy link
Contributor

belkadan commented Feb 9, 2018

(Note that NSUInteger could very well be the weirdness here, since that's imported as Int in most-but-not-all positions, and we have to pick which side the typedef falls on.)

@krzyzanowskim
Copy link
Contributor Author

krzyzanowskim commented Feb 9, 2018

It may be something with the NSUInteger. Here is my current workaround where I basically mimic the NSUInteger type:

    #if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
    typedef unsigned long PageIndex;
    #else
    typedef unsigned int PageIndex;
    #endif

Will try to build self-contained example.

@belkadan
Copy link
Contributor

belkadan commented Feb 9, 2018

On all the platforms you care about uintptr_t is close enough to NSUInteger to be interoperable. But there's a reason Swift imports NSUInteger as UInt: converting between Int and UInt stinks.

@krzyzanowskim
Copy link
Contributor Author

krzyzanowskim commented Feb 9, 2018

It looks like PageIndex is converted differently than the NSUInteger, and I don't get it.
cannot convert value of type 'PageIndex' (aka 'UInt32') to expected argument type 'UInt'

@belkadan
Copy link
Contributor

belkadan commented Feb 9, 2018

Certain types are recognized as "word-sized", something that needs information beyond what you get out of a preprocessed C file. long is actually one of them on Apple platforms, but int is not. uintptr_t and NSUInteger both are special-cased to work regardless of their underlying type.

@krzyzanowskim
Copy link
Contributor Author

krzyzanowskim commented Feb 9, 2018

hm... when used uintptr_t

Conflicting return type in implementation of 'pageIndex': 'PSPDFPageIndex' (aka 'unsigned long') vs 'NSUInteger' (aka 'unsigned int')

@belkadan
Copy link
Contributor

belkadan commented Feb 9, 2018

I mean, you do have to be consistent about it…

@krzyzanowskim
Copy link
Contributor Author

krzyzanowskim commented Feb 10, 2018

I see. I thought you said "uintptr_t is close enough to NSUInteger to be interoperable" meaning it's the same type, but it's not apparently. Ok. I also tried to use API notes with, does it make sense in this case? (couldn't find any docs how it works)

Typedefs:
- Name: "PSPDFPageIndex"
  SwiftBridge: "Swift.UInt"   

and if I look at the generated interface, it's UInt, but it doesn't seem to impact the type checked as it still thinks it's UInt32 eg.

Cannot convert value of type 'PSPDFPageIndex' (aka 'UInt32') to expected argument type 'UInt'

@belkadan
Copy link
Contributor

belkadan commented Feb 12, 2018

No, sorry, that's not what SwiftBridge is for.

Stepping back, why do you want UInt for this API? That's not standard Swift. If the typedef were imported as Int would you be happy?

@krzyzanowskim
Copy link
Contributor Author

krzyzanowskim commented Feb 12, 2018

I want to do
typedef NSUInteger PageIndex;

@belkadan
Copy link
Contributor

belkadan commented Feb 12, 2018

Oh, wait, sorry. I got confused because system APIs import NSUInteger as Int. Non-system ones are still UInt. Okay, this is just a bug, then. Leaving it NSUInteger is fine.

@belkadan
Copy link
Contributor

belkadan commented Feb 12, 2018

@swift-ci create

@krzyzanowskim
Copy link
Contributor Author

krzyzanowskim commented Feb 19, 2018

To add, for the type defined like this:

typedef unsigned long PSPDFUInteger;
typedef PSPDFUInteger PSPDFPageIndex NS_SWIFT_NAME(PageIndex);

And use

- (nullable NSURL *)pathForPageAtIndex:(PSPDFPageIndex)pageIndex;

it's imported as

func pathForPage(at pageIndex: Any!) -> URL?

so it looks like there is something missing with typedef resolving.

@swift-ci
Copy link
Collaborator

swift-ci commented Jan 27, 2020

Comment by Peter Steinberger (JIRA)

I've tested this with Xcode 11.3.1 (11C505), the importer still has the same issue.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants