Skip to content

Reorganize TypeContextDescriptorFlags to be a bit more semantic #18253

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

Merged

Conversation

rjmccall
Copy link
Contributor

Leave space for new kinds of non-generic metadata initialization (one of which I'm about to claim for "foreign") and non-default type namespaces.

@rjmccall rjmccall requested review from jckarter and jrose-apple July 26, 2018 08:04
@rjmccall
Copy link
Contributor Author

rjmccall commented Jul 26, 2018

@jrose-apple, I'd like your opinion about the right thing to do with CTag and CTypedef here. In the abstract, I think probably the right thing to do with C namespaces is:

  • The ordinary namespace (home of typedefs, @interfaces, templates, template parameters, and ObjC generic parameters) is the default namespace. Those kinds of declarations don't get a special namespace kind in these flags; we can detect them by the absence of a namespace and by knowing that a declaration comes from C (which I think we can detect otherwise?). But I don't know if that's okay for our current uses of this in the runtime.

  • The tag namespace (home of enums, structs, classes, and unions) is a special namespace that needs its own kind here. We can decide whether or not to set the flag for class templates, which inhabit both namespaces.

  • The protocol namespace (home of @protocols) can continue to be distinguished by just being a protocol, I guess?

  • None of the other identifier namespaces contain types.

Also, I've left importer-synthesized related declarations as a bit independent from the imported namespace kind.

It looks like we don't actually set an imported declaration on related imports. We honor the original name but don't have any way of recording whether it was in a special namespace.

@rjmccall
Copy link
Contributor Author

@swift-ci Please test.

@jrose-apple
Copy link
Contributor

We already encode all that information in the mangled name now, so I'm not sure how important it is to have additional flags in the type descriptor. Does anything actually query for this?

@rjmccall
Copy link
Contributor Author

Type descriptors don't store a mangled name. There are uses of isCTag() and isCTypedef, in part when recreating mangle trees but also in MetadataLookup; that's what I was asking you about.

@jrose-apple
Copy link
Contributor

I see, these are the flags used to determine how to interact with manglings. Tracking these as "namespaces" kind of works, I guess. (The mangling side of this is best captured by the tryAppendClangName helper.)

It looks like we don't actually set an imported declaration on related imports. We honor the original name but don't have any way of recording whether it was in a special namespace.

This is handled in the mangling but I guess not in the metadata? That does seem like a problem for buildNominalTypeMangling. I'm not sure how to solve it, though—it seems weird to set these flags for the metadata of related decls and have the isSynthesizedRelatedEntity field say "oh, actually those apply to the original decl". I guess that'd be a practical answer, though.

@rjmccall
Copy link
Contributor Author

The idea is that there's a foreign declaration which caused this type to exist. The context, name, and special namespace kind identify that declaration; the namespace is required because you could have different foreign declarations with the same name in different namespaces, depending on how the source language works. (e.g. C lets you write struct A and typedef int A; in the same scope.) If this type is exactly that foreign declaration, this is not a related entity; otherwise, it's just a related entity and there's the additional discriminator in the name field. But you could have related entities for all the different foreign types with the same name, so you really need the related entity to be orthogonal.

At least, that's the design that makes sense to me and which justifies mangling typedef vs. tag.

@jrose-apple
Copy link
Contributor

Okay, that makes sense. It's probably worth including that in the doc comment for isSynthesizedRelatedEntity, then.

Leave space for new kinds of non-generic metadata initialization
(one of which I'm about to claim for "foreign") and non-default
type namespaces.
@rjmccall rjmccall force-pushed the reorganize-type-descriptor-flags branch from 65dff02 to 374f08f Compare July 26, 2018 19:26
@rjmccall
Copy link
Contributor Author

@swift-ci Please smoke test.

@rjmccall
Copy link
Contributor Author

@jrose-apple Comment changed. I'm going to leave tags and typedefs alone for now, but there's a comment in ImportNamespaceKind explaining the situation as I see it.

@rjmccall rjmccall merged commit ff70528 into swiftlang:master Jul 26, 2018
@rjmccall rjmccall deleted the reorganize-type-descriptor-flags branch July 26, 2018 21:22
// ObjC classes are in the ordinary namespace in C.
// - Protocols are assumed to come from Objective-C by default.
// ObjC protocols are in their own namespace in C.
// - Structs and enums seem to always get either CTag or CTypedef.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct. Structs, enums, and unions always get CTag. CTypedef is only for typedefs with the swift_wrapper attribute.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, and for CF types.

// ObjC protocols are in their own namespace in C.
// - Structs and enums seem to always get either CTag or CTypedef.
// It would probably make more sense to assume they come from the
// tag namespace in C and then just use CTypedef as an override.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This part is still fine, though. We would never map a class or protocol to a struct.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants