Skip to content

Commit 214a9d6

Browse files
authored
---
yaml --- r: 348780 b: refs/heads/master c: 8c5dcc0 h: refs/heads/master
1 parent 12d6a7e commit 214a9d6

File tree

177 files changed

+5948
-5238
lines changed

Some content is hidden

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

177 files changed

+5948
-5238
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: 5914325a0248292d7443cbd952ec6fc11ea513e7
2+
refs/heads/master: 8c5dcc0fe5c9c4aa3bf3ccb15a6b6a342ba393ad
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/docs/WindowsBuild.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,11 @@ cmake -G "Visual Studio 2017" -A x64 -T "host=x64"^ ...
186186
md "S:\b\lldb"
187187
cd "S:\b\lldb"
188188
cmake -G Ninja^
189+
-DLLVM_DIR="S:/b/llvm/lib/cmake/llvm"^
190+
-DClang_DIR="S:/b/llvm/lib/cmake/clang"^
191+
-DSwift_DIR="S:/b/swift/lib/cmake/swift"^
189192
-DCMAKE_BUILD_TYPE=RelWithDebInfo^
190193
-DLLDB_ALLOW_STATIC_BINDINGS=YES^
191-
-DLLDB_PATH_TO_CLANG_SOURCE="S:\clang"^
192-
-DLLDB_PATH_TO_SWIFT_SOURCE="S:\swift"^
193-
-DLLDB_PATH_TO_CLANG_BUILD="S:\b\llvm"^
194-
-DLLDB_PATH_TO_LLVM_BUILD="S:\b\llvm"^
195-
-DLLDB_PATH_TO_SWIFT_BUILD="S:\b\swift"^
196194
-DLLVM_ENABLE_ASSERTIONS=ON^
197195
-DPYTHON_HOME="%ProgramFiles(x86)%\Microsoft Visual Studio\Shared\Python37_64"^
198196
S:\lldb

trunk/include/swift/AST/DiagnosticConsumer.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,17 @@ enum class DiagnosticKind : uint8_t {
3838
Note
3939
};
4040

41-
/// Extra information carried along with a diagnostic, which may or
42-
/// may not be of interest to a given diagnostic consumer.
41+
/// Information about a diagnostic passed to DiagnosticConsumers.
4342
struct DiagnosticInfo {
4443
DiagID ID = DiagID(0);
44+
SourceLoc Loc;
45+
DiagnosticKind Kind;
46+
StringRef FormatString;
47+
ArrayRef<DiagnosticArgument> FormatArgs;
48+
SourceLoc BufferIndirectlyCausingDiagnostic;
49+
50+
/// DiagnosticInfo of notes which are children of this diagnostic, if any
51+
ArrayRef<DiagnosticInfo *> ChildDiagnosticInfo;
4552

4653
/// Represents a fix-it, a replacement of one range of text with another.
4754
class FixIt {
@@ -60,6 +67,24 @@ struct DiagnosticInfo {
6067

6168
/// Extra source ranges that are attached to the diagnostic.
6269
ArrayRef<FixIt> FixIts;
70+
71+
/// This is a note which has a parent error or warning
72+
bool IsChildNote = false;
73+
74+
DiagnosticInfo() {}
75+
76+
DiagnosticInfo(DiagID ID, SourceLoc Loc, DiagnosticKind Kind,
77+
StringRef FormatString,
78+
ArrayRef<DiagnosticArgument> FormatArgs,
79+
SourceLoc BufferIndirectlyCausingDiagnostic,
80+
ArrayRef<DiagnosticInfo *> ChildDiagnosticInfo,
81+
ArrayRef<CharSourceRange> Ranges, ArrayRef<FixIt> FixIts,
82+
bool IsChildNote)
83+
: ID(ID), Loc(Loc), Kind(Kind), FormatString(FormatString),
84+
FormatArgs(FormatArgs),
85+
BufferIndirectlyCausingDiagnostic(BufferIndirectlyCausingDiagnostic),
86+
ChildDiagnosticInfo(ChildDiagnosticInfo), Ranges(Ranges),
87+
FixIts(FixIts), IsChildNote(IsChildNote) {}
6388
};
6489

6590
/// Abstract interface for classes that present diagnostics to the user.

trunk/include/swift/AST/DiagnosticEngine.h

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,9 @@ namespace swift {
337337
SmallVector<DiagnosticArgument, 3> Args;
338338
SmallVector<CharSourceRange, 2> Ranges;
339339
SmallVector<FixIt, 2> FixIts;
340+
std::vector<Diagnostic> ChildNotes;
340341
SourceLoc Loc;
342+
bool IsChildNote = false;
341343
const Decl *Decl = nullptr;
342344

343345
friend DiagnosticEngine;
@@ -362,10 +364,13 @@ namespace swift {
362364
ArrayRef<DiagnosticArgument> getArgs() const { return Args; }
363365
ArrayRef<CharSourceRange> getRanges() const { return Ranges; }
364366
ArrayRef<FixIt> getFixIts() const { return FixIts; }
367+
ArrayRef<Diagnostic> getChildNotes() const { return ChildNotes; }
368+
bool isChildNote() const { return IsChildNote; }
365369
SourceLoc getLoc() const { return Loc; }
366370
const class Decl *getDecl() const { return Decl; }
367371

368372
void setLoc(SourceLoc loc) { Loc = loc; }
373+
void setIsChildNote(bool isChildNote) { IsChildNote = isChildNote; }
369374
void setDecl(const class Decl *decl) { Decl = decl; }
370375

371376
/// Returns true if this object represents a particular diagnostic.
@@ -386,6 +391,8 @@ namespace swift {
386391
void addFixIt(FixIt &&F) {
387392
FixIts.push_back(std::move(F));
388393
}
394+
395+
void addChildNote(Diagnostic &&D);
389396
};
390397

391398
/// Describes an in-flight diagnostic, which is currently active
@@ -665,7 +672,8 @@ namespace swift {
665672

666673
friend class InFlightDiagnostic;
667674
friend class DiagnosticTransaction;
668-
675+
friend class CompoundDiagnosticTransaction;
676+
669677
public:
670678
explicit DiagnosticEngine(SourceManager &SourceMgr)
671679
: SourceMgr(SourceMgr), ActiveDiagnostic(),
@@ -878,6 +886,15 @@ namespace swift {
878886
return diagnose(decl, Diagnostic(id, std::move(args)...));
879887
}
880888

889+
/// Emit a parent diagnostic and attached notes.
890+
///
891+
/// \param parentDiag An InFlightDiagnostic representing the parent diag.
892+
///
893+
/// \param builder A closure which builds and emits notes to be attached to
894+
/// the parent diag.
895+
void diagnoseWithNotes(InFlightDiagnostic parentDiag,
896+
llvm::function_ref<void(void)> builder);
897+
881898
/// \returns true if diagnostic is marked with PointsToFirstBadToken
882899
/// option.
883900
bool isDiagnosticPointsToFirstBadToken(DiagID id) const;
@@ -905,6 +922,10 @@ namespace swift {
905922
/// Retrieve the active diagnostic.
906923
Diagnostic &getActiveDiagnostic() { return *ActiveDiagnostic; }
907924

925+
/// Generate DiagnosticInfo for a Diagnostic to be passed to consumers.
926+
Optional<DiagnosticInfo>
927+
diagnosticInfoForDiagnostic(const Diagnostic &diagnostic);
928+
908929
/// Send \c diag to all diagnostic consumers.
909930
void emitDiagnostic(const Diagnostic &diag);
910931

@@ -945,6 +966,7 @@ namespace swift {
945966
/// in LIFO order. An open transaction is implicitly committed upon
946967
/// destruction.
947968
class DiagnosticTransaction {
969+
protected:
948970
DiagnosticEngine &Engine;
949971

950972
/// How many tentative diagnostics there were when the transaction
@@ -968,7 +990,6 @@ namespace swift {
968990
Depth(Engine.TransactionCount),
969991
IsOpen(true)
970992
{
971-
assert(!Engine.ActiveDiagnostic);
972993
Engine.TransactionCount++;
973994
}
974995

@@ -1011,6 +1032,61 @@ namespace swift {
10111032
"transactions must be closed LIFO");
10121033
}
10131034
};
1035+
1036+
/// Represents a diagnostic transaction which constructs a compound diagnostic
1037+
/// from any diagnostics emitted inside. A compound diagnostic consists of a
1038+
/// parent error, warning, or remark followed by a variable number of child
1039+
/// notes. The semantics are otherwise the same as a regular
1040+
/// DiagnosticTransaction.
1041+
class CompoundDiagnosticTransaction : public DiagnosticTransaction {
1042+
public:
1043+
explicit CompoundDiagnosticTransaction(DiagnosticEngine &engine)
1044+
: DiagnosticTransaction(engine) {}
1045+
1046+
~CompoundDiagnosticTransaction() {
1047+
if (IsOpen) {
1048+
commit();
1049+
}
1050+
1051+
if (Depth == 0) {
1052+
Engine.TransactionStrings.clear();
1053+
Engine.TransactionAllocator.Reset();
1054+
}
1055+
}
1056+
1057+
void commit() {
1058+
assert(PrevDiagnostics < Engine.TentativeDiagnostics.size() &&
1059+
"CompoundDiagnosticTransaction must contain at least one diag");
1060+
1061+
// The first diagnostic is assumed to be the parent. If this is not an
1062+
// error or warning, we'll assert later when trying to add children.
1063+
Diagnostic &parent = Engine.TentativeDiagnostics[PrevDiagnostics];
1064+
1065+
// Associate the children with the parent.
1066+
for (auto diag =
1067+
Engine.TentativeDiagnostics.begin() + PrevDiagnostics + 1;
1068+
diag != Engine.TentativeDiagnostics.end(); ++diag) {
1069+
diag->setIsChildNote(true);
1070+
parent.addChildNote(std::move(*diag));
1071+
}
1072+
1073+
// Erase the children, they'll be emitted alongside their parent.
1074+
Engine.TentativeDiagnostics.erase(Engine.TentativeDiagnostics.begin() +
1075+
PrevDiagnostics + 1,
1076+
Engine.TentativeDiagnostics.end());
1077+
1078+
DiagnosticTransaction::commit();
1079+
}
1080+
};
1081+
1082+
inline void
1083+
DiagnosticEngine::diagnoseWithNotes(InFlightDiagnostic parentDiag,
1084+
llvm::function_ref<void(void)> builder) {
1085+
CompoundDiagnosticTransaction transaction(*this);
1086+
parentDiag.flush();
1087+
builder();
1088+
}
1089+
10141090
} // end namespace swift
10151091

10161092
#endif

0 commit comments

Comments
 (0)