diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index c97ae75329c..6084a1e4ef1 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -347,6 +347,9 @@ def StringCompare : DiagGroup<"string-compare">; def StringPlusInt : DiagGroup<"string-plus-int">; def StringPlusChar : DiagGroup<"string-plus-char">; def StrncatSize : DiagGroup<"strncat-size">; + +def SwiftNameAttribute : DiagGroup<"swift-name-attribute">; + def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">; def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">; def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">; diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index 312b71f4064..d13ae4c95a5 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -36,7 +36,7 @@ namespace clang { DIAG_START_AST = DIAG_START_PARSE + 500, DIAG_START_COMMENT = DIAG_START_AST + 110, DIAG_START_SEMA = DIAG_START_COMMENT + 100, - DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, + DIAG_START_ANALYSIS = DIAG_START_SEMA + 4000, DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 }; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 4278e45a2ab..33a473c3b85 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3009,15 +3009,57 @@ def err_objc_attr_protocol_requires_definition : Error< "attribute %0 can only be applied to @protocol definitions, not forward declarations">; // Swift attributes -def err_attr_swift_name_decl_kind : Error< - "%0 attribute cannot be applied to this declaration">; -def err_attr_swift_name_identifier : Error< - "parameter of %0 attribute must be an ASCII identifier string">; -def err_attr_swift_name_function : Error< - "parameter of %0 attribute must be a Swift function name string">; +def warn_attr_swift_name_decl_kind : Warning< + "%0 attribute cannot be applied to this declaration">, + InGroup; +def warn_attr_swift_name_function : Warning< + "parameter of %0 attribute must be a Swift function name string">, + InGroup; +def warn_attr_swift_name_function_no_prototype : Warning< + "%0 attribute can only be applied to function declarations with prototypes">, + InGroup; +def warn_attr_swift_name_context_name_invalid_identifier : Warning< + "%0 attribute has invalid identifier for context name">, + InGroup; +def warn_attr_swift_name_basename_invalid_identifier : Warning< + "%0 attribute has invalid identifier for base name">, + InGroup; +def warn_attr_swift_name_parameter_invalid_identifier : Warning< + "%0 attribute has invalid identifier for parameter name">, + InGroup; +def warn_attr_swift_name_missing_parameters : Warning< + "%0 attribute is missing parameter label clause">, + InGroup; +def warn_attr_swift_name_subscript_not_accessor : Warning< + "%0 attribute for 'subscript' must be a getter or setter">, + InGroup; +def warn_attr_swift_name_subscript_no_parameter : Warning< + "%0 attribute for 'subscript' must take at least one parameter">, + InGroup; +def warn_attr_swift_name_subscript_getter_newValue : Warning< + "%0 attribute for 'subscript' getter cannot take a 'newValue:' parameter">, + InGroup; +def warn_attr_swift_name_subscript_setter_no_newValue : Warning< + "%0 attribute for 'subscript' setter must take a 'newValue:' parameter">, + InGroup; +def warn_attr_swift_name_subscript_setter_multiple_newValues : Warning< + "%0 attribute for 'subscript' setter cannot take multiple 'newValue:' parameters">, + InGroup; +def warn_attr_swift_name_getter_parameters : Warning< + "%0 attribute for getter must not take any parameters besides 'self:'">, + InGroup; +def warn_attr_swift_name_setter_parameters : Warning< + "%0 attribute for setter must take one parameter for new value">, + InGroup; +def warn_attr_swift_name_multiple_selfs : Warning< + "%0 attribute cannot specify more than one 'self:' parameter">, + InGroup; +def warn_attr_swift_name_static_subscript : Warning< + "%0 attribute for 'subscript' must take a 'self:' parameter">, + InGroup; def warn_attr_swift_name_num_params : Warning< "too %select{few|many}0 parameters in %1 attribute (expected %2; got %3)">, - InGroup>; + InGroup; def err_attr_swift_error_no_error_parameter : Error< "%0 attribute can only be applied to a %select{function|method}1 " "with an error parameter">; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 005309a5197..5c868f0c848 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1368,6 +1368,24 @@ class Sema { } }; + /// Do a check to make sure \p Name looks like a legal swift_name + /// attribute for the decl \p D. Raise a diagnostic if the name is invalid + /// for the given declaration. + /// + /// For a function, this will validate a compound Swift name, + /// e.g. init(foo:bar:baz:) or controllerForName(_:), + /// and the function will output the number of parameter names, and whether + /// this is a single-arg initializer. + /// + /// For a type, enum constant, property, or variable declaration, this will + /// validate either a simple identifier, or a qualified + /// context.identifier name. + /// + /// \returns true if the name is a valid swift name for \p D, false otherwise. + bool DiagnoseSwiftName(Decl *D, StringRef Name, + SourceLocation ArgLoc, + IdentifierInfo *AttrName); + private: bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, TypeDiagnoser *Diagnoser); diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp index 5072824313e..4468d22f30a 100644 --- a/lib/Sema/SemaAPINotes.cpp +++ b/lib/Sema/SemaAPINotes.cpp @@ -111,7 +111,7 @@ static void ProcessAPINotes(Sema &S, Decl *D, if (Info.UnavailableInSwift) { D->addAttr(AvailabilityAttr::CreateImplicit( - S.Context, + S.Context, &S.Context.Idents.get("swift"), VersionTuple(), VersionTuple(), @@ -129,9 +129,14 @@ static void ProcessAPINotes(Sema &S, Decl *D, // swift_name if (!Info.SwiftName.empty() && !D->hasAttr()) { + auto &APINoteName = S.getASTContext().Idents.get("SwiftName API Note"); + + if (!S.DiagnoseSwiftName(D, Info.SwiftName, D->getLocation(), + &APINoteName)) { + return; + } D->addAttr(SwiftNameAttr::CreateImplicit(S.Context, - CopyString(S.Context, - Info.SwiftName))); + CopyString(S.Context, Info.SwiftName))); } } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 31a5694d816..ec2b8256b06 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -4585,13 +4585,11 @@ static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, Attr.getAttributeSpellingListIndex())); } -/// Do a very rough check to make sure \p Name looks like a Swift function name, -/// e.g. init(foo:bar:baz:) or controllerForName(_:), -/// and return the number of parameter names. -static bool validateSwiftFunctionName(StringRef Name, - unsigned &ParamCount, - bool &IsSingleParamInit) { - ParamCount = 0; +static Optional +validateSwiftFunctionName(StringRef Name, + unsigned &SwiftParamCount, + bool &IsSingleParamInit) { + SwiftParamCount = 0; // Check whether this will be mapped to a getter or setter of a // property. @@ -4606,7 +4604,7 @@ static bool validateSwiftFunctionName(StringRef Name, } if (Name.back() != ')') - return false; + return diag::warn_attr_swift_name_function; StringRef BaseName, Parameters; std::tie(BaseName, Parameters) = Name.split('('); @@ -4620,71 +4618,135 @@ static bool validateSwiftFunctionName(StringRef Name, BaseName = ContextName; ContextName = StringRef(); } else if (ContextName.empty() || !isValidIdentifier(ContextName)) { - return false; + return diag::warn_attr_swift_name_context_name_invalid_identifier; } else { IsMember = true; } if (!isValidIdentifier(BaseName) || BaseName == "_") - return false; + return diag::warn_attr_swift_name_basename_invalid_identifier; + bool IsSubscript = BaseName == "subscript"; + // A subscript accessor must be a getter or setter. + if (IsSubscript && !isGetter && !isSetter) + return diag::warn_attr_swift_name_subscript_not_accessor; + if (Parameters.empty()) - return false; + return diag::warn_attr_swift_name_missing_parameters; Parameters = Parameters.drop_back(); // ')' if (Parameters.empty()) { - // Setters must have at least one parameter. - if (isSetter) return false; - - return true; + // Setters and subscripts must have at least one parameter. + if (IsSubscript) + return diag::warn_attr_swift_name_subscript_no_parameter; + if (isSetter) + return diag::warn_attr_swift_name_setter_parameters; + + return None; } if (Parameters.back() != ':') - return false; + return diag::warn_attr_swift_name_function; Optional SelfLocation; + Optional NewValueLocation; + unsigned NewValueCount = 0; StringRef NextParam; do { std::tie(NextParam, Parameters) = Parameters.split(':'); if (!isValidIdentifier(NextParam)) - return false; + return diag::warn_attr_swift_name_parameter_invalid_identifier; // "self" indicates the "self" argument for a member. if (IsMember && NextParam == "self") { // More than one "self"? - if (SelfLocation) return false; + if (SelfLocation) return diag::warn_attr_swift_name_multiple_selfs; // The "self" location is the current parameter. - SelfLocation = ParamCount; + SelfLocation = SwiftParamCount; } - - ++ParamCount; + + // "newValue" indicates the "newValue" argument for a setter. + if (NextParam == "newValue") { + // There should only be one 'newValue', but it's only significant for + // subscript accessors, so don't error right away. + ++NewValueCount; + + NewValueLocation = SwiftParamCount; + } + ++SwiftParamCount; } while (!Parameters.empty()); + // Only instance subscripts are currently supported. + if (IsSubscript && !SelfLocation) + return diag::warn_attr_swift_name_static_subscript; + IsSingleParamInit = - (ParamCount == 1 && BaseName == "init" && NextParam != "_"); + (SwiftParamCount == 1 && BaseName == "init" && NextParam != "_"); // Check the number of parameters for a getter/setter. if (isGetter || isSetter) { // Setters have one parameter for the new value. - unsigned NumExpectedParams = isSetter ? 1 : 0; + unsigned NumExpectedParams; + unsigned ParamDiag; + + if (isSetter) { + NumExpectedParams = 1; + ParamDiag = diag::warn_attr_swift_name_setter_parameters; + } else { + NumExpectedParams = 0; + ParamDiag = diag::warn_attr_swift_name_getter_parameters; + } // Instance methods have one parameter for "self". if (SelfLocation) ++NumExpectedParams; - - if (ParamCount != NumExpectedParams) return true; + + // Subscripts may have additional parameters beyond the expected params for + // the index. + if (IsSubscript) { + if (SwiftParamCount < NumExpectedParams) + return ParamDiag; + // A subscript setter must explicitly label its newValue parameter to + // distinguish it from index parameters. + if (isSetter) { + if (!NewValueLocation) + return diag::warn_attr_swift_name_subscript_setter_no_newValue; + // There can only be one. + if (NewValueCount > 1) + return diag::warn_attr_swift_name_subscript_setter_multiple_newValues; + } else { + // Subscript getters should have no 'newValue:' parameter. + if (NewValueLocation) + return diag::warn_attr_swift_name_subscript_getter_newValue; + } + } else { + // Property accessors must have exactly the number of expected params. + if (SwiftParamCount != NumExpectedParams) + return ParamDiag; + } } - return true; + return None; } -static void handleSwiftName(Sema &S, Decl *D, const AttributeList &Attr) { - StringRef Name; - SourceLocation ArgLoc; - if (!S.checkStringLiteralArgumentAttr(Attr, 0, Name, &ArgLoc)) - return; - +/// Do a check to make sure \p Name looks like a legal swift_name +/// attribute for the decl \p D. Raise a diagnostic if the name is invalid +/// for the given declaration. +/// +/// For a function, this will validate a compound Swift name, +/// e.g. init(foo:bar:baz:) or controllerForName(_:), +/// and the function will output the number of parameter names, and whether this +/// is a single-arg initializer. +/// +/// For a type, enum constant, property, or variable declaration, this will +/// validate either a simple identifier, or a qualified +/// context.identifier name. +/// +/// \returns true if the name is a valid swift name for \p D, false otherwise. +bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name, + SourceLocation ArgLoc, + IdentifierInfo *AttrName) { if (isa(D) || isa(D)) { ArrayRef Params; unsigned ParamCount; @@ -4696,15 +4758,22 @@ static void handleSwiftName(Sema &S, Decl *D, const AttributeList &Attr) { const auto *Function = cast(D); ParamCount = Function->getNumParams(); Params = Function->parameters(); + + if (!Function->hasWrittenPrototype()) { + Diag(ArgLoc, diag::warn_attr_swift_name_function_no_prototype) + << AttrName; + return false; + } } - bool IsSingleParamInit; unsigned SwiftParamCount; - if (!validateSwiftFunctionName(Name, SwiftParamCount, IsSingleParamInit)) { - S.Diag(ArgLoc, diag::err_attr_swift_name_function) << Attr.getName(); - return; + bool IsSingleParamInit; + if (auto diagID = validateSwiftFunctionName(Name, SwiftParamCount, + IsSingleParamInit)) { + Diag(ArgLoc, *diagID) << AttrName; + return false; } - + bool ParamsOK; if (SwiftParamCount == ParamCount) { ParamsOK = true; @@ -4726,10 +4795,10 @@ static void handleSwiftName(Sema &S, Decl *D, const AttributeList &Attr) { } if (!ParamsOK) { - S.Diag(ArgLoc, diag::warn_attr_swift_name_num_params) - << (SwiftParamCount > ParamCount) << Attr.getName() + Diag(ArgLoc, diag::warn_attr_swift_name_num_params) + << (SwiftParamCount > ParamCount) << AttrName << ParamCount << SwiftParamCount; - return; + return false; } } else if (isa(D) || isa(D) || @@ -4742,24 +4811,35 @@ static void handleSwiftName(Sema &S, Decl *D, const AttributeList &Attr) { BaseName = ContextName; ContextName = StringRef(); } else if (!isValidIdentifier(ContextName)) { - S.Diag(ArgLoc, diag::err_attr_swift_name_identifier) << Attr.getName(); - return; + Diag(ArgLoc, diag::warn_attr_swift_name_context_name_invalid_identifier) + << AttrName; + return false; } if (!isValidIdentifier(BaseName)) { - S.Diag(ArgLoc, diag::err_attr_swift_name_identifier) << Attr.getName(); - return; + Diag(ArgLoc, diag::warn_attr_swift_name_basename_invalid_identifier) + << AttrName; + return false; } } else { - S.Diag(Attr.getLoc(), diag::err_attr_swift_name_decl_kind) - << Attr.getName(); - return; + Diag(ArgLoc, diag::warn_attr_swift_name_decl_kind) << AttrName; + return false; } + return true; +} - D->addAttr(::new (S.Context) - SwiftNameAttr(Attr.getRange(), S.Context, Name, - Attr.getAttributeSpellingListIndex())); +static void handleSwiftName(Sema &S, Decl *D, const AttributeList &Attr) { + StringRef Name; + SourceLocation ArgLoc; + if (!S.checkStringLiteralArgumentAttr(Attr, 0, Name, &ArgLoc)) + return; + + if (!S.DiagnoseSwiftName(D, Name, ArgLoc, Attr.getName())) + return; + + D->addAttr(::new (S.Context) SwiftNameAttr(Attr.getRange(), S.Context, Name, + Attr.getAttributeSpellingListIndex())); } static bool isErrorParameter(Sema &S, QualType paramType) { diff --git a/test/SemaObjC/attr-swift.m b/test/SemaObjC/attr-swift.m index effcfefff2f..bdcbbd0ace6 100644 --- a/test/SemaObjC/attr-swift.m +++ b/test/SemaObjC/attr-swift.m @@ -50,7 +50,7 @@ + (SNFoo *)fooWithValue:(int)value __attribute__((swift_name("foo(value:)"))); + (SNFoo *)fooWithValue:(int)value value:(int)value2 __attribute__((swift_name("foo(value:extra:)"))); + (SNFoo *)fooWithConvertingValue:(int)value value:(int)value2 __attribute__((swift_name("init(_:extra:)"))); -+ (SNFoo *)fooWithOtherValue:(int)value __attribute__((swift_name("init"))); // expected-error {{parameter of 'swift_name' attribute must be a Swift function name string}} ++ (SNFoo *)fooWithOtherValue:(int)value __attribute__((swift_name("init"))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}} + (SNFoo *)fooWithAnotherValue:(int)value __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}} + (SNFoo *)fooWithYetAnotherValue:(int)value __attribute__((swift_name("foo(value:extra:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 1; got 2)}} @@ -68,10 +68,10 @@ + (instancetype)specialBar __attribute__((swift_name("init(options:extra:)"))); + (instancetype)specialBaz __attribute__((swift_name("init(_:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 1)}} + (instancetype)specialGarply __attribute__((swift_name("foo(options:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 1)}} -+ (instancetype)trailingParen __attribute__((swift_name("foo("))); // expected-error {{parameter of 'swift_name' attribute must be a Swift function name string}} -+ (instancetype)trailingColon:(int)value __attribute__((swift_name("foo(value)"))); // expected-error {{parameter of 'swift_name' attribute must be a Swift function name string}} -+ (instancetype)initialIgnore:(int)value __attribute__((swift_name("_(value:)"))); // expected-error {{parameter of 'swift_name' attribute must be a Swift function name string}} -+ (instancetype)middleOmitted:(int)value __attribute__((swift_name("foo(:)"))); // expected-error {{parameter of 'swift_name' attribute must be a Swift function name string}} ++ (instancetype)trailingParen __attribute__((swift_name("foo("))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}} ++ (instancetype)trailingColon:(int)value __attribute__((swift_name("foo(value)"))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}} ++ (instancetype)initialIgnore:(int)value __attribute__((swift_name("_(value:)"))); // expected-warning {{'swift_name' attribute has invalid identifier for base name}} ++ (instancetype)middleOmitted:(int)value __attribute__((swift_name("foo(:)"))); // expected-warning {{'swift_name' attribute has invalid identifier for parameter name}} @property(strong) id someProp __attribute__((swift_name("prop"))); @end @@ -80,7 +80,7 @@ enum __attribute__((swift_name("MoreColors"))) MoreColors { Cyan, Magenta, Yellow __attribute__((swift_name("RoseGold"))), - Black __attribute__((swift_name("SpaceGrey()"))) // expected-error {{parameter of 'swift_name' attribute must be an ASCII identifier string}} + Black __attribute__((swift_name("SpaceGrey()"))) // expected-warning {{'swift_name' attribute has invalid identifier for base name}} }; struct __attribute__((swift_name("FooStruct"))) BarStruct { @@ -89,7 +89,7 @@ struct __attribute__((swift_name("FooStruct"))) BarStruct { int global_int __attribute__((swift_name("GlobalInt"))); -void foo1(int i) __attribute__((swift_name("foo"))); // expected-error{{parameter of 'swift_name' attribute must be a Swift function name string}} +void foo1(int i) __attribute__((swift_name("foo"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}} void foo2(int i) __attribute__((swift_name("foo()"))); // expected-warning{{too few parameters in 'swift_name' attribute (expected 1; got 0)}} void foo2(int i) __attribute__((swift_name("foo(a:b:)"))); // expected-warning{{too many parameters in 'swift_name' attribute (expected 1; got 2)}} void foo3(int i, int j) __attribute__((swift_name("fooWithX(_:y:)"))); // okay @@ -106,26 +106,55 @@ struct __attribute__((swift_name("FooStruct"))) BarStruct { // Getters and setters. float Point3DGetMagnitude(Point3D point) __attribute__((swift_name("getter:Point3D.magnitude(self:)"))); +float Point3DGetMagnitudeAndSomethingElse(Point3D point, float wat) __attribute__((swift_name("getter:Point3D.magnitude(self:wat:)"))); // expected-warning {{'swift_name' attribute for getter must not take any parameters besides 'self:'}} + float Point3DGetRadius(Point3D point) __attribute__((swift_name("getter:Point3D.radius(self:)"))); -void Point3DSetRadius(Point3D point, float radius) __attribute__((swift_name("setter:Point3D.radius(self:_:)"))); +void Point3DSetRadius(Point3D point, float radius) __attribute__((swift_name("setter:Point3D.radius(self:newValue:)"))); + +float Point3DPreGetRadius(Point3D point) __attribute__((swift_name("getter:Point3D.preRadius(self:)"))); +void Point3DPreSetRadius(float radius, Point3D point) __attribute__((swift_name("setter:Point3D.preRadius(newValue:self:)"))); + +void Point3DSetRadiusAndSomethingElse(Point3D point, float radius, float wat) __attribute__((swift_name("setter:Point3D.radius(self:newValue:wat:)"))); // expected-warning {{'swift_name' attribute for setter must take one parameter for new value}} + +float Point3DGetComponent(Point3D point, unsigned index) __attribute__((swift_name("getter:Point3D.subscript(self:_:)"))); +float Point3DSetComponent(Point3D point, unsigned index, float value) __attribute__((swift_name("setter:Point3D.subscript(self:_:newValue:)"))); + +float Point3DGetMatrixComponent(Point3D point, unsigned x, unsigned y) __attribute__((swift_name("getter:Point3D.subscript(self:x:y:)"))); +void Point3DSetMatrixComponent(Point3D point, unsigned x, float value, unsigned y) __attribute__((swift_name("setter:Point3D.subscript(self:x:newValue:y:)"))); + +float Point3DSetWithoutNewValue(Point3D point, unsigned x, unsigned y) __attribute__((swift_name("setter:Point3D.subscript(self:x:y:)"))); // expected-warning {{'swift_name' attribute for 'subscript' setter must take a 'newValue:' parameter}} + +float Point3DSubscriptButNotGetterSetter(Point3D point, unsigned x) __attribute__((swift_name("Point3D.subscript(self:_:)"))); // expected-warning {{'swift_name' attribute for 'subscript' must be a getter or setter}} + +void Point3DSubscriptSetterTwoNewValues(Point3D point, unsigned x, float a, float b) __attribute__((swift_name("setter:Point3D.subscript(self:_:newValue:newValue:)"))); // expected-warning {{'swift_name' attribute for 'subscript' setter cannot take multiple 'newValue:' parameters}} +float Point3DSubscriptGetterNewValue(Point3D point, unsigned x, float a, float b) __attribute__((swift_name("getter:Point3D.subscript(self:_:newValue:newValue:)"))); // expected-warning {{'swift_name' attribute for 'subscript' getter cannot take a 'newValue:' parameter}} + +void Point3DMethodWithNewValue(Point3D point, float newValue) __attribute__((swift_name("Point3D.method(self:newValue:)"))); +void Point3DMethodWithNewValues(Point3D point, float newValue, float newValueB) __attribute__((swift_name("Point3D.method(self:newValue:newValue:)"))); + +float Point3DStaticSubscript(unsigned x) __attribute__((swift_name("getter:Point3D.subscript(_:)"))); // expected-warning {{'swift_name' attribute for 'subscript' must take a 'self:' parameter}} +float Point3DStaticSubscriptNoArgs(void) __attribute__((swift_name("getter:Point3D.subscript()"))); // expected-warning {{'swift_name' attribute for 'subscript' must take at least one parameter}} + +float Point3DPreGetComponent(Point3D point, unsigned index) __attribute__((swift_name("getter:Point3D.subscript(self:_:)"))); Point3D getCurrentPoint3D(void) __attribute__((swift_name("getter:currentPoint3D()"))); -void setCurrentPoint3D(Point3D point) __attribute__((swift_name("setter:currentPoint3D(_:)"))); +void setCurrentPoint3D(Point3D point) __attribute__((swift_name("setter:currentPoint3D(newValue:)"))); Point3D getLastPoint3D(void) __attribute__((swift_name("getter:lastPoint3D()"))); -void setLastPoint3D(Point3D point) __attribute__((swift_name("setter:lastPoint3D(_:)"))); +void setLastPoint3D(Point3D point) __attribute__((swift_name("setter:lastPoint3D(newValue:)"))); -Point3D getZeroPoint() __attribute__((swift_name("getter:Point3D.zero()"))); -void setZeroPoint(Point3D point) __attribute__((swift_name("setter:Point3D.zero(_:)"))); +Point3D getZeroPoint(void) __attribute__((swift_name("getter:Point3D.zero()"))); +Point3D getZeroPointNoPrototype() __attribute__((swift_name("getter:Point3D.zeroNoPrototype()"))); // expected-warning{{'swift_name' attribute can only be applied to function declarations with prototypes}} +void setZeroPoint(Point3D point) __attribute__((swift_name("setter:Point3D.zero(newValue:)"))); -Point3D badGetter1(int x) __attribute__((swift_name("getter:bad1(_:))"))); // expected-error{{parameter of 'swift_name' attribute must be a Swift function name string}} -void badSetter1() __attribute__((swift_name("getter:bad1())"))); // expected-error{{parameter of 'swift_name' attribute must be a Swift function name string}} +Point3D badGetter1(int x) __attribute__((swift_name("getter:bad1(_:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}} +void badSetter1(void) __attribute__((swift_name("getter:bad1())"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}} -Point3D badGetter2(Point3D point) __attribute__((swift_name("getter:bad2(_:))"))); // expected-error{{parameter of 'swift_name' attribute must be a Swift function name string}} +Point3D badGetter2(Point3D point) __attribute__((swift_name("getter:bad2(_:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}} -void badSetter2(Point3D point) __attribute__((swift_name("setter:bad2(self:))"))); // expected-error{{parameter of 'swift_name' attribute must be a Swift function name string}} +void badSetter2(Point3D point) __attribute__((swift_name("setter:bad2(self:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}} // --- swift_error ---