Skip to content

Commit 0d63255

Browse files
authored
---
yaml --- r: 348739 b: refs/heads/master c: e2e114f h: refs/heads/master i: 348737: 00800c2 348735: 792944a
1 parent 45e75b7 commit 0d63255

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1465
-848
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: b0e947b0b324ded81f6b8ee4990e562cc237a6a3
2+
refs/heads/master: e2e114f11b837e731ebb79b9278ebfaf5f7c27dd
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/docs/CToSwiftNameTranslation.md

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,29 @@ Additionally, typedefs for `void *` or `const void *` that are themselves annota
212212
If a typedef's underlying type is itself a "CF pointer" typedef, the "alias" typedef will be imported as a regular typealias, with the suffix "Ref" still dropped from its name (if present) unless doing so would conflict with another declaration in the same module as the typedef.
213213

214214

215+
## Objective-C Properties
216+
217+
By default, most property names are not transformed at all. However, if the getter of a property overrides a superclass or adopted protocol method that is also a property accessor, the Swift name of the overridden accessor's property will be used for consistency. If there's more than one such name, one is chosen arbitrarily.
218+
219+
Properties with the type `BOOL` or `Boolean` use the name of the getter as the name of the Swift property by default, rather than the name of the property in Objective-C. This accounts for a difference in Swift and Objective-C naming conventions for boolean properties that use "is".
220+
221+
```objc
222+
@property(getter=isContrivedExample) BOOL contrivedExample;
223+
@property BOOL hasAnotherForm;
224+
```
225+
226+
```swift
227+
var isContrivedExample: Bool { get set }
228+
var hasAnotherForm: Bool { get set }
229+
```
230+
231+
_This rule should probably have applied to C's native `bool` as well._
232+
233+
A property declaration with the `SwiftImportPropertyAsAccessors` API note will not be imported at all, and its accessors will be imported as methods. Additionally, properties whose names start with "accessibility" in the NSAccessibility protocol are always imported as methods, as are properties whose names start with "accessibility" in an `@interface` declaration (class or category) that provides the adoption of NSAccessibility.
234+
235+
_Objective-C code has historically not been consistent about whether the NSAccessibility declarations should be considered properties and therefore the Swift compiler chooses to import them as methods, as a sort of lowest common denominator._
236+
237+
215238
## `swift_private`
216239

217240
The `swift_private` Clang attribute prepends `__` onto the base name of any declaration being imported except initializers. For initializers with no arguments, a dummy `Void` argument with the name `__` is inserted; otherwise, the label for the first argument has `__` prepended. This transformation takes place after any other name manipulation, unless the declaration has a custom name. It will not occur if the declaration is an override; in that case the name needs to match the overridden declaration.
@@ -252,6 +275,8 @@ __attribute__((swift_name("SpacecraftCoordinates")))
252275
struct SPKSpacecraftCoordinates {
253276
double x, y, z, t; // space and time, of course
254277
};
278+
279+
// Usually seen as NS_SWIFT_NAME.
255280
```
256281
257282
```swift
@@ -287,12 +312,10 @@ The `swift_name` attribute can be used to give a C function a custom name. The v
287312
```objc
288313
__attribute__((swift_name("doSomething(to:bar:)")))
289314
void doSomethingToFoo(Foo *foo, int bar);
290-
291-
// Usually seen as NS_SWIFT_NAME.
292315
```
293316
294317
```swift
295-
func doSomething(foo: UnsafeMutablePointer<Foo>, bar: Int32)
318+
func doSomething(to foo: UnsafeMutablePointer<Foo>, bar: Int32)
296319
```
297320

298321
An underscore can be used in place of an empty parameter label, as in Swift.
@@ -430,4 +453,86 @@ Although enumerators always have global scope in C, they are often imported as m
430453

431454
_Currently, `swift_name` does not even allow importing an enum case as a member of the enum type itself, even if the enum is not recognized as an `@objc` enum, error code enum, or option set (i.e. the situation where a case is imported as a global constant)._
432455

456+
457+
### Fields of structs and unions; Objective-C properties
458+
459+
The `swift_name` attribute can be applied to rename a struct or union field or an Objective-C property (whether on a class or a protocol). The value of the attribute must be a valid Swift identifier.
460+
461+
```objc
462+
struct SPKSpaceflightBooking {
463+
const SPKLocation * _Nullable destination;
464+
bool roundTrip __attribute__((swift_name("isRoundTrip")));
465+
};
466+
```
467+
468+
```swift
469+
struct SPKSpaceflightBooking {
470+
var destination: UnsafePointer<SPKLocation>?
471+
var isRoundTrip: Bool
472+
}
473+
```
474+
475+
476+
### Objective-C methods
477+
478+
The `swift_name` attribute can be used to give an Objective-C method a custom name. The value of the attribute must be a full Swift function name, including parameter labels.
479+
480+
```objc
481+
- (void)doSomethingToFoo:(Foo *)foo bar:(int)bar
482+
__attribute__((swift_name("doSomethingImportant(to:bar:)")));
483+
```
484+
485+
```swift
486+
func doSomethingImportant(to foo: UnsafeMutablePointer<Foo>, bar: Int32)
487+
```
488+
489+
As with functions, an underscore can be used to represent an empty parameter label.
490+
491+
Methods that follow the NSError out-parameter convention may provide one fewer parameter label than the number of parameters in the original method to indicate that a parameter should be dropped, but they do not have to. The `swift_error` attribute is still respected even when using a custom name for purposes of transforming an NSError out-parameter and the method return type.
492+
493+
```objc
494+
- (BOOL)doSomethingRiskyAndReturnError:(NSError **)error
495+
__attribute__((swift_name("doSomethingRisky()")));
496+
- (BOOL)doSomethingContrived:(NSString *)action error:(NSError **)outError
497+
__attribute__((swift_name("doSomethingContrived(_:error:)")));
498+
```
499+
500+
```swift
501+
func doSomethingRisky() throws
502+
func doSomethingContrived(_ action: String, error: ()) throws
503+
```
504+
505+
A base name of "init" can be used on a *class* method that returns `instancetype` or the containing static type in order to import that method as an initializer. Any other custom name *prevents* a class method from being imported as an initializer even if it would normally be inferred as one.
506+
507+
```objc
508+
+ (Action *)makeActionWithHandler:(void(^)(void))handler
509+
__attribute__((swift_name("init(handler:)")));
510+
+ (instancetype)makeActionWithName:(NSString *)name
511+
__attribute__((swift_name("init(name:)")));
512+
```
513+
514+
```swift
515+
/* non-inherited */ init(handler: () -> Void)
516+
init(name: String)
517+
```
518+
519+
A no-argument method imported as an initializer can be given a dummy argument label to disambiguate it from the no-argument `init()`, whether the method is an init-family instance method or a factory class method in Objective-C.
520+
521+
```objc
522+
- (instancetype)initSafely
523+
__attribute__((swift_name("init(safe:)")));
524+
+ (instancetype)makeDefaultAction
525+
__attribute__((swift_name("init(default:)")));
526+
```
527+
528+
```swift
529+
init(safe: ())
530+
init(default: ())
531+
```
532+
533+
A custom name on an instance method with one of Objective-C's subscript selectors (`objectAtIndexedSubscript:`, `objectForKeyedSubscript:`, `setObject:atIndexedSubscript:`, or `setObject:forKeyedSubscript:`) prevents that method from being imported as a subscript or used as the accessor for another subscript.
534+
535+
_Currently, this only works if *both* methods in a read/write subscript are given custom names; if just one is, a read/write subscript will still be formed. A read-only subscript only has one method to rename._
536+
537+
433538
## More to come...

trunk/include/swift/AST/Identifier.h

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,26 @@ class Identifier {
5656

5757
const char *Pointer;
5858

59+
public:
60+
enum : size_t {
61+
NumLowBitsAvailable = 2,
62+
RequiredAlignment = 1 << NumLowBitsAvailable,
63+
SpareBitMask = ((intptr_t)1 << NumLowBitsAvailable) - 1
64+
};
65+
66+
private:
5967
/// Constructor, only accessible by ASTContext, which handles the uniquing.
60-
explicit Identifier(const char *Ptr) : Pointer(Ptr) {}
68+
explicit Identifier(const char *Ptr) : Pointer(Ptr) {
69+
assert(((uintptr_t)Ptr & SpareBitMask) == 0
70+
&& "Identifier pointer does not use any spare bits");
71+
}
72+
73+
/// A type with the alignment expected of a valid \c Identifier::Pointer .
74+
struct alignas(uint32_t) Aligner {};
75+
76+
static_assert(alignof(Aligner) >= RequiredAlignment,
77+
"Identifier table will provide enough spare bits");
78+
6179
public:
6280
explicit Identifier() : Pointer(nullptr) {}
6381

@@ -153,12 +171,15 @@ class Identifier {
153171
bool operator<(Identifier RHS) const { return Pointer < RHS.Pointer; }
154172

155173
static Identifier getEmptyKey() {
156-
return Identifier((const char*)
157-
llvm::DenseMapInfo<const void*>::getEmptyKey());
174+
uintptr_t Val = static_cast<uintptr_t>(-1);
175+
Val <<= NumLowBitsAvailable;
176+
return Identifier((const char*)Val);
158177
}
178+
159179
static Identifier getTombstoneKey() {
160-
return Identifier((const char*)
161-
llvm::DenseMapInfo<const void*>::getTombstoneKey());
180+
uintptr_t Val = static_cast<uintptr_t>(-2);
181+
Val <<= NumLowBitsAvailable;
182+
return Identifier((const char*)Val);
162183
}
163184

164185
private:
@@ -202,7 +223,7 @@ namespace llvm {
202223
static inline swift::Identifier getFromVoidPointer(void *P) {
203224
return swift::Identifier::getFromOpaquePointer(P);
204225
}
205-
enum { NumLowBitsAvailable = 2 };
226+
enum { NumLowBitsAvailable = swift::Identifier::NumLowBitsAvailable };
206227
};
207228

208229
} // end namespace llvm
@@ -221,15 +242,15 @@ class DeclBaseName {
221242
};
222243

223244
private:
224-
/// In a special DeclName represenenting a subscript, this opaque pointer
245+
/// In a special DeclName representing a subscript, this opaque pointer
225246
/// is used as the data of the base name identifier.
226247
/// This is an implementation detail that should never leak outside of
227248
/// DeclName.
228-
static void *SubscriptIdentifierData;
249+
static const Identifier::Aligner SubscriptIdentifierData;
229250
/// As above, for special constructor DeclNames.
230-
static void *ConstructorIdentifierData;
251+
static const Identifier::Aligner ConstructorIdentifierData;
231252
/// As above, for special destructor DeclNames.
232-
static void *DestructorIdentifierData;
253+
static const Identifier::Aligner DestructorIdentifierData;
233254

234255
Identifier Ident;
235256

@@ -239,23 +260,23 @@ class DeclBaseName {
239260
DeclBaseName(Identifier I) : Ident(I) {}
240261

241262
static DeclBaseName createSubscript() {
242-
return DeclBaseName(Identifier((const char *)SubscriptIdentifierData));
263+
return DeclBaseName(Identifier((const char *)&SubscriptIdentifierData));
243264
}
244265

245266
static DeclBaseName createConstructor() {
246-
return DeclBaseName(Identifier((const char *)ConstructorIdentifierData));
267+
return DeclBaseName(Identifier((const char *)&ConstructorIdentifierData));
247268
}
248269

249270
static DeclBaseName createDestructor() {
250-
return DeclBaseName(Identifier((const char *)DestructorIdentifierData));
271+
return DeclBaseName(Identifier((const char *)&DestructorIdentifierData));
251272
}
252273

253274
Kind getKind() const {
254-
if (Ident.get() == SubscriptIdentifierData) {
275+
if (Ident.get() == (const char *)&SubscriptIdentifierData) {
255276
return Kind::Subscript;
256-
} else if (Ident.get() == ConstructorIdentifierData) {
277+
} else if (Ident.get() == (const char *)&ConstructorIdentifierData) {
257278
return Kind::Constructor;
258-
} else if (Ident.get() == DestructorIdentifierData) {
279+
} else if (Ident.get() == (const char *)&DestructorIdentifierData) {
259280
return Kind::Destructor;
260281
} else {
261282
return Kind::Normal;
@@ -720,7 +741,7 @@ namespace llvm {
720741
static inline swift::DeclName getFromVoidPointer(void *ptr) {
721742
return swift::DeclName::getFromOpaqueValue(ptr);
722743
}
723-
enum { NumLowBitsAvailable = 0 };
744+
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclBaseName>::NumLowBitsAvailable - 2 };
724745
};
725746

726747
// DeclNames hash just like pointers.

trunk/include/swift/Parse/ASTGen.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ class ASTGen {
3737

3838
// FIXME: remove when Syntax can represent all types and ASTGen can handle
3939
// them
40-
/// Types that cannot be represented by Syntax or generated by ASTGen.
41-
llvm::DenseMap<SourceLoc, TypeRepr *> Types;
42-
40+
/// Decl attributes that cannot be represented by Syntax or generated by
41+
/// ASTGen.
4342
llvm::DenseMap<SourceLoc, DeclAttributes> ParsedDeclAttrs;
4443

4544
public:
@@ -103,7 +102,8 @@ class ASTGen {
103102
//===--------------------------------------------------------------------===//
104103
// Types.
105104

106-
TypeRepr *generate(const syntax::TypeSyntax &Type, const SourceLoc Loc);
105+
TypeRepr *generate(const syntax::TypeSyntax &Type, const SourceLoc Loc,
106+
bool IsSILFuncDecl = false);
107107
TypeRepr *generate(const syntax::SomeTypeSyntax &Type, const SourceLoc Loc);
108108
TypeRepr *generate(const syntax::CompositionTypeSyntax &Type,
109109
const SourceLoc Loc);
@@ -127,11 +127,19 @@ class ASTGen {
127127
const SourceLoc Loc);
128128
TypeRepr *generate(const syntax::ClassRestrictionTypeSyntax &Type,
129129
const SourceLoc Loc);
130+
TypeRepr *generate(const syntax::SILBoxTypeSyntax &Type, const SourceLoc Loc,
131+
bool IsSILFuncDecl);
132+
TypeRepr *generate(const syntax::SILFunctionTypeSyntax &Type,
133+
const SourceLoc Loc, bool IsSILFuncDecl);
130134
TypeRepr *generate(const syntax::CodeCompletionTypeSyntax &Type,
131135
const SourceLoc Loc);
132136
TypeRepr *generate(const syntax::UnknownTypeSyntax &Type,
133137
const SourceLoc Loc);
134138

139+
TypeAttributes
140+
generateTypeAttributes(const syntax::AttributeListSyntax &syntax,
141+
const SourceLoc Loc);
142+
135143
private:
136144
TupleTypeRepr *
137145
generateTuple(const syntax::TokenSyntax &LParen,
@@ -196,10 +204,6 @@ class ASTGen {
196204
TypeRepr *lookupType(syntax::TypeSyntax Type);
197205

198206
public:
199-
void addType(TypeRepr *Type, const SourceLoc Loc);
200-
bool hasType(const SourceLoc Loc) const;
201-
TypeRepr *getType(const SourceLoc Loc) const;
202-
203207
void addDeclAttributes(DeclAttributes attrs, const SourceLoc Loc);
204208
bool hasDeclAttributes(SourceLoc Loc) const;
205209
DeclAttributes getDeclAttributes(const SourceLoc Loc) const;

trunk/include/swift/Parse/ParsedRawSyntaxNode.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,20 @@ class ParsedRawSyntaxNode {
119119
assert(getTokenKind() == tokKind && "Token kind with too large value!");
120120
}
121121

122+
#ifndef NDEBUG
123+
bool ensureDataIsNotRecorded() {
124+
if (DK != DataKind::Recorded)
125+
return true;
126+
llvm::dbgs() << "Leaking node: ";
127+
dump(llvm::dbgs());
128+
llvm::dbgs() << "\n";
129+
return false;
130+
}
131+
#endif
132+
122133
ParsedRawSyntaxNode &operator=(ParsedRawSyntaxNode &&other) {
123-
assert(DK != DataKind::Recorded);
134+
assert(ensureDataIsNotRecorded() &&
135+
"recorded data is being destroyed by assignment");
124136
switch (other.DK) {
125137
case DataKind::Null:
126138
break;
@@ -145,7 +157,7 @@ class ParsedRawSyntaxNode {
145157
*this = std::move(other);
146158
}
147159
~ParsedRawSyntaxNode() {
148-
assert(DK != DataKind::Recorded);
160+
assert(ensureDataIsNotRecorded() && "recorded data is being destructed");
149161
}
150162

151163
syntax::SyntaxKind getKind() const { return syntax::SyntaxKind(SynKind); }

0 commit comments

Comments
 (0)