let Documentation = [SwiftErrorDocs];
}
+def SwiftName : InheritableAttr {
+ let Spellings = [GNU<"swift_name">];
+ let Args = [StringArgument<"Name">];
+ let Documentation = [SwiftNameDocs];
+}
+
def NoDeref : TypeAttr {
let Spellings = [Clang<"noderef">];
let Documentation = [NoDerefDocs];
}];
}
+def SwiftNameDocs : Documentation {
+ let Category = SwiftDocs;
+ let Heading = "swift_name";
+ let Content = [{
+The ``swift_name`` attribute provides the name of the declaration in Swift. If
+this attribute is absent, the name is transformed according to the algorithm
+built into the Swift compiler.
+
+The argument is a string literal that contains the Swift name of the function,
+variable, or type. When renaming a function, the name may be a compound Swift
+name. For a type, enum constant, property, or variable declaration, the name
+must be a simple or qualified identifier.
+
+ .. code-block:: c
+
+ @interface URL
+ - (void) initWithString:(NSString *)s __attribute__((__swift_name__("URL.init(_:)")))
+ @end
+
+ void __attribute__((__swift_name__("squareRoot()"))) sqrt(double v) {
+ }
+ }];
+}
+
def OMPDeclareSimdDocs : Documentation {
let Category = DocCatFunction;
let Heading = "#pragma omp declare simd";
def StringPlusInt : DiagGroup<"string-plus-int">;
def StringPlusChar : DiagGroup<"string-plus-char">;
def StrncatSize : DiagGroup<"strncat-size">;
+def SwiftNameAttribute : DiagGroup<"swift-name-attribute">;
def IntInBoolContext : DiagGroup<"int-in-bool-context">;
def TautologicalTypeLimitCompare : DiagGroup<"tautological-type-limit-compare">;
def TautologicalUnsignedZeroCompare : DiagGroup<"tautological-unsigned-zero-compare">;
def err_objc_attr_protocol_requires_definition : Error<
"attribute %0 can only be applied to @protocol definitions, not forward declarations">;
+// Swift attributes.
+def warn_attr_swift_name_function
+ : Warning<"%0 attribute argument must be a string literal specifying a Swift function name">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_invalid_identifier
+ : Warning<"%0 attribute has invalid identifier for the %select{base|context|parameter}1 name">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_decl_kind
+ : Warning<"%0 attribute cannot be applied to this declaration">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_invalid_parameter
+ : Warning<"%0 attribute for 'subscript' must %select{be a getter or setter|"
+ "have at least one parameter|"
+ "have a 'self:' parameter}1">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_missing_parameters
+ : Warning<"%0 attribute is missing parameter label clause">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_setter_parameters
+ : Warning<"%0 attribute for setter must have one parameter for new value">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_multiple_selfs
+ : Warning<"%0 attribute cannot specify more than one 'self:' parameter">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_getter_parameters
+ : Warning<"%0 attribute for getter must not have any parameters besides 'self:'">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_setter_no_newValue
+ : Warning<"%0 attribute for 'subscript' setter must have a 'newValue:' parameter">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_setter_multiple_newValues
+ : Warning<"%0 attribute for 'subscript' setter cannot have multiple 'newValue:' parameters">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_getter_newValue
+ : Warning<"%0 attribute for 'subscript' getter cannot have a 'newValue:' parameter">,
+ InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_num_params
+ : Warning<"too %select{few|many}0 parameters in %1 attribute (expected %2; got %3)">,
+ InGroup<SwiftNameAttribute>;
+
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">;
}
};
+ /// Do a check to make sure \p Name looks like a legal argument for the
+ /// swift_name attribute applied to decl \p D. Raise a diagnostic if the name
+ /// is invalid for the given declaration.
+ ///
+ /// \p AL is used to provide caret diagnostics in case of a malformed name.
+ ///
+ /// \returns true if the name is a valid swift name for \p D, false otherwise.
+ bool DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc,
+ const ParsedAttr &AL);
+
/// A derivative of BoundTypeDiagnoser for which the diagnostic's type
/// parameter is preceded by a 0/1 enum that is 1 if the type is sizeless.
/// For example, a diagnostic with no other parameters would generally have
SpeculativeLoadHardeningAttr *
mergeSpeculativeLoadHardeningAttr(Decl *D,
const SpeculativeLoadHardeningAttr &AL);
+ SwiftNameAttr *mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA,
+ StringRef Name, bool Override);
OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D,
const AttributeCommonInfo &CI);
InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL);
return false;
} else if (const auto *MA = dyn_cast<MinSizeAttr>(Attr))
NewAttr = S.mergeMinSizeAttr(D, *MA);
+ else if (const auto *SNA = dyn_cast<SwiftNameAttr>(Attr))
+ NewAttr = S.mergeSwiftNameAttr(D, *SNA, SNA->getName(),
+ AMK == Sema::AMK_Override);
else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr))
NewAttr = S.mergeOptimizeNoneAttr(D, *OA);
else if (const auto *InternalLinkageA = dyn_cast<InternalLinkageAttr>(Attr))
return ::new (Context) NoSpeculativeLoadHardeningAttr(Context, AL);
}
+SwiftNameAttr *Sema::mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA,
+ StringRef Name, bool Override) {
+ if (const auto *PrevSNA = D->getAttr<SwiftNameAttr>()) {
+ if (Override) {
+ // FIXME: warn about incompatible override
+ return nullptr;
+ }
+
+ if (PrevSNA->getName() != Name && !PrevSNA->isImplicit()) {
+ Diag(PrevSNA->getLocation(), diag::err_attributes_are_not_compatible)
+ << PrevSNA << &SNA;
+ Diag(SNA.getLoc(), diag::note_conflicting_attribute);
+ }
+
+ D->dropAttr<SwiftNameAttr>();
+ }
+ return ::new (Context) SwiftNameAttr(Context, SNA, Name);
+}
+
OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
const AttributeCommonInfo &CI) {
if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
D->addAttr(::new (S.Context) SwiftErrorAttr(S.Context, AL, Convention));
}
+// For a function, this will validate a compound Swift name, e.g.
+// <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>, 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
+// <code>context.identifier</code> name.
+static bool
+validateSwiftFunctionName(Sema &S, const ParsedAttr &AL, SourceLocation Loc,
+ StringRef Name, unsigned &SwiftParamCount,
+ bool &IsSingleParamInit) {
+ SwiftParamCount = 0;
+ IsSingleParamInit = false;
+
+ // Check whether this will be mapped to a getter or setter of a property.
+ bool IsGetter = false, IsSetter = false;
+ if (Name.startswith("getter:")) {
+ IsGetter = true;
+ Name = Name.substr(7);
+ } else if (Name.startswith("setter:")) {
+ IsSetter = true;
+ Name = Name.substr(7);
+ }
+
+ if (Name.back() != ')') {
+ S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;
+ return false;
+ }
+
+ bool IsMember = false;
+ StringRef ContextName, BaseName, Parameters;
+
+ std::tie(BaseName, Parameters) = Name.split('(');
+
+ // Split at the first '.', if it exists, which separates the context name
+ // from the base name.
+ std::tie(ContextName, BaseName) = BaseName.split('.');
+ if (BaseName.empty()) {
+ BaseName = ContextName;
+ ContextName = StringRef();
+ } else if (ContextName.empty() || !isValidIdentifier(ContextName)) {
+ S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
+ << AL << /*context*/ 1;
+ return false;
+ } else {
+ IsMember = true;
+ }
+
+ if (!isValidIdentifier(BaseName) || BaseName == "_") {
+ S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
+ << AL << /*basename*/ 0;
+ return false;
+ }
+
+ bool IsSubscript = BaseName == "subscript";
+ // A subscript accessor must be a getter or setter.
+ if (IsSubscript && !IsGetter && !IsSetter) {
+ S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
+ << AL << /* getter or setter */ 0;
+ return false;
+ }
+
+ if (Parameters.empty()) {
+ S.Diag(Loc, diag::warn_attr_swift_name_missing_parameters) << AL;
+ return false;
+ }
+
+ assert(Parameters.back() == ')' && "expected ')'");
+ Parameters = Parameters.drop_back(); // ')'
+
+ if (Parameters.empty()) {
+ // Setters and subscripts must have at least one parameter.
+ if (IsSubscript) {
+ S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
+ << AL << /* have at least one parameter */1;
+ return false;
+ }
+
+ if (IsSetter) {
+ S.Diag(Loc, diag::warn_attr_swift_name_setter_parameters) << AL;
+ return false;
+ }
+
+ return true;
+ }
+
+ if (Parameters.back() != ':') {
+ S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;
+ return false;
+ }
+
+ StringRef CurrentParam;
+ llvm::Optional<unsigned> SelfLocation;
+ unsigned NewValueCount = 0;
+ llvm::Optional<unsigned> NewValueLocation;
+ do {
+ std::tie(CurrentParam, Parameters) = Parameters.split(':');
+
+ if (!isValidIdentifier(CurrentParam)) {
+ S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
+ << AL << /*parameter*/2;
+ return false;
+ }
+
+ if (IsMember && CurrentParam == "self") {
+ // "self" indicates the "self" argument for a member.
+
+ // More than one "self"?
+ if (SelfLocation) {
+ S.Diag(Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;
+ return false;
+ }
+
+ // The "self" location is the current parameter.
+ SelfLocation = SwiftParamCount;
+ } else if (CurrentParam == "newValue") {
+ // "newValue" indicates the "newValue" argument for a setter.
+
+ // 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) {
+ S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
+ << AL << /*have a 'self:' parameter*/2;
+ return false;
+ }
+
+ IsSingleParamInit =
+ SwiftParamCount == 1 && BaseName == "init" && CurrentParam != "_";
+
+ // Check the number of parameters for a getter/setter.
+ if (IsGetter || IsSetter) {
+ // Setters have one parameter for the new value.
+ unsigned NumExpectedParams = IsGetter ? 0 : 1;
+ unsigned ParamDiag =
+ IsGetter ? diag::warn_attr_swift_name_getter_parameters
+ : diag::warn_attr_swift_name_setter_parameters;
+
+ // Instance methods have one parameter for "self".
+ if (SelfLocation)
+ ++NumExpectedParams;
+
+ // Subscripts may have additional parameters beyond the expected params for
+ // the index.
+ if (IsSubscript) {
+ if (SwiftParamCount < NumExpectedParams) {
+ S.Diag(Loc, ParamDiag) << AL;
+ return false;
+ }
+
+ // A subscript setter must explicitly label its newValue parameter to
+ // distinguish it from index parameters.
+ if (IsSetter) {
+ if (!NewValueLocation) {
+ S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)
+ << AL;
+ return false;
+ }
+ if (NewValueCount > 1) {
+ S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_multiple_newValues)
+ << AL;
+ return false;
+ }
+ } else {
+ // Subscript getters should have no 'newValue:' parameter.
+ if (NewValueLocation) {
+ S.Diag(Loc, diag::warn_attr_swift_name_subscript_getter_newValue)
+ << AL;
+ return false;
+ }
+ }
+ } else {
+ // Property accessors must have exactly the number of expected params.
+ if (SwiftParamCount != NumExpectedParams) {
+ S.Diag(Loc, ParamDiag) << AL;
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc,
+ const ParsedAttr &AL) {
+ if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
+ ArrayRef<ParmVarDecl*> Params;
+ unsigned ParamCount;
+
+ if (const auto *Method = dyn_cast<ObjCMethodDecl>(D)) {
+ ParamCount = Method->getSelector().getNumArgs();
+ Params = Method->parameters().slice(0, ParamCount);
+ } else {
+ const auto *F = cast<FunctionDecl>(D);
+
+ ParamCount = F->getNumParams();
+ Params = F->parameters();
+
+ if (!F->hasWrittenPrototype()) {
+ Diag(Loc, diag::warn_attribute_wrong_decl_type) << AL
+ << /* non-K&R-style functions */12;
+ return false;
+ }
+ }
+
+ unsigned SwiftParamCount;
+ bool IsSingleParamInit;
+ if (!validateSwiftFunctionName(*this, AL, Loc, Name,
+ SwiftParamCount, IsSingleParamInit))
+ return false;
+
+ bool ParamCountValid;
+ if (SwiftParamCount == ParamCount) {
+ ParamCountValid = true;
+ } else if (SwiftParamCount > ParamCount) {
+ ParamCountValid = IsSingleParamInit && ParamCount == 0;
+ } else {
+ // We have fewer Swift parameters than Objective-C parameters, but that
+ // might be because we've transformed some of them. Check for potential
+ // "out" parameters and err on the side of not warning.
+ unsigned MaybeOutParamCount =
+ std::count_if(Params.begin(), Params.end(),
+ [](const ParmVarDecl *Param) -> bool {
+ QualType ParamTy = Param->getType();
+ if (ParamTy->isReferenceType() || ParamTy->isPointerType())
+ return !ParamTy->getPointeeType().isConstQualified();
+ return false;
+ });
+
+ ParamCountValid = SwiftParamCount + MaybeOutParamCount >= ParamCount;
+ }
+
+ if (!ParamCountValid) {
+ Diag(Loc, diag::warn_attr_swift_name_num_params)
+ << (SwiftParamCount > ParamCount) << AL << ParamCount
+ << SwiftParamCount;
+ return false;
+ }
+ } else if (isa<EnumConstantDecl>(D) || isa<ObjCProtocolDecl>(D) ||
+ isa<ObjCInterfaceDecl>(D) || isa<ObjCPropertyDecl>(D) ||
+ isa<VarDecl>(D) || isa<TypedefNameDecl>(D) || isa<TagDecl>(D) ||
+ isa<IndirectFieldDecl>(D) || isa<FieldDecl>(D)) {
+ StringRef ContextName, BaseName;
+
+ std::tie(ContextName, BaseName) = Name.split('.');
+ if (BaseName.empty()) {
+ BaseName = ContextName;
+ ContextName = StringRef();
+ } else if (!isValidIdentifier(ContextName)) {
+ Diag(Loc, diag::warn_attr_swift_name_invalid_identifier) << AL
+ << /*context*/1;
+ return false;
+ }
+
+ if (!isValidIdentifier(BaseName)) {
+ Diag(Loc, diag::warn_attr_swift_name_invalid_identifier) << AL
+ << /*basename*/0;
+ return false;
+ }
+ } else {
+ Diag(Loc, diag::warn_attr_swift_name_decl_kind) << AL;
+ return false;
+ }
+ return true;
+}
+
+static void handleSwiftName(Sema &S, Decl *D, const ParsedAttr &AL) {
+ StringRef Name;
+ SourceLocation Loc;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))
+ return;
+
+ if (!S.DiagnoseSwiftName(D, Name, Loc, AL))
+ return;
+
+ D->addAttr(::new (S.Context) SwiftNameAttr(S.Context, AL, Name));
+}
+
//===----------------------------------------------------------------------===//
// Microsoft specific attribute handlers.
//===----------------------------------------------------------------------===//
case ParsedAttr::AT_SwiftError:
handleSwiftError(S, D, AL);
break;
+ case ParsedAttr::AT_SwiftName:
+ handleSwiftName(S, D, AL);
+ break;
case ParsedAttr::AT_SwiftObjCMembers:
handleSimpleAttribute<SwiftObjCMembersAttr>(S, D, AL);
break;
--- /dev/null
+// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc %s
+
+#define SWIFT_NAME(name) __attribute__((__swift_name__(name)))
+
+typedef struct {
+ float x, y, z;
+} Point3D;
+
+__attribute__((__swift_name__("PType")))
+@protocol P
+@end
+
+__attribute__((__swift_name__("IClass")))
+@interface I<P>
+- (instancetype)init SWIFT_NAME("init()");
+- (instancetype)initWithValue:(int)value SWIFT_NAME("iWithValue(_:)");
+
++ (void)refresh SWIFT_NAME("refresh()");
+
+- (instancetype)i SWIFT_NAME("i()");
+
+- (I *)iWithValue:(int)value SWIFT_NAME("i(value:)");
+- (I *)iWithValue:(int)value value:(int)value2 SWIFT_NAME("i(value:extra:)");
+- (I *)iWithValueConvertingValue:(int)value value:(int)value2 SWIFT_NAME("i(_:extra:)");
+
++ (I *)iWithOtheValue:(int)value SWIFT_NAME("init");
+// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
+
++ (I *)iWithAnotherValue:(int)value SWIFT_NAME("i()");
+// expected-warning@-1 {{too few parameters in '__swift_name__' attribute (expected 1; got 0)}}
+
++ (I *)iWithYetAnotherValue:(int)value SWIFT_NAME("i(value:extra:)");
+// expected-warning@-1 {{too many parameters in '__swift_name__' attribute (expected 1; got 2}}
+
++ (I *)iAndReturnErrorCode:(int *)errorCode SWIFT_NAME("i()"); // no-warning
++ (I *)iWithValue:(int)value andReturnErrorCode:(int *)errorCode SWIFT_NAME("i(value:)"); // no-warning
+
++ (I *)iFromErrorCode:(const int *)errorCode SWIFT_NAME("i()");
+// expected-warning@-1 {{too few parameters in '__swift_name__' attribute (expected 1; got 0)}}
+
++ (I *)iWithPointerA:(int *)value andReturnErrorCode:(int *)errorCode SWIFT_NAME("i()"); // no-warning
++ (I *)iWithPointerB:(int *)value andReturnErrorCode:(int *)errorCode SWIFT_NAME("i(pointer:)"); // no-warning
++ (I *)iWithPointerC:(int *)value andReturnErrorCode:(int *)errorCode SWIFT_NAME("i(pointer:errorCode:)"); // no-warning
+
++ (I *)iWithOtherI:(I *)other SWIFT_NAME("i()");
+// expected-warning@-1 {{too few parameters in '__swift_name__' attribute (expected 1; got 0)}}
+
++ (instancetype)specialI SWIFT_NAME("init(options:)");
++ (instancetype)specialJ SWIFT_NAME("init(options:extra:)");
+// expected-warning@-1 {{too many parameters in '__swift_name__' attribute (expected 0; got 2)}}
++ (instancetype)specialK SWIFT_NAME("init(_:)");
+// expected-warning@-1 {{too many parameters in '__swift_name__' attribute (expected 0; got 1)}}
++ (instancetype)specialL SWIFT_NAME("i(options:)");
+// expected-warning@-1 {{too many parameters in '__swift_name__' attribute (expected 0; got 1)}}
+
++ (instancetype)trailingParen SWIFT_NAME("foo(");
+// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
++ (instancetype)trailingColon SWIFT_NAME("foo:");
+// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
++ (instancetype)initialIgnore:(int)value SWIFT_NAME("_(value:)");
+// expected-warning@-1 {{'__swift_name__' attribute has invalid identifier for the base name}}
++ (instancetype)middleOmitted:(int)value SWIFT_NAME("i(:)");
+// expected-warning@-1 {{'__swift_name__' attribute has invalid identifier for the parameter name}}
+
+@property(strong) id someProp SWIFT_NAME("prop");
+@end
+
+enum SWIFT_NAME("E") E {
+ value1,
+ value2,
+ value3 SWIFT_NAME("three"),
+ value4 SWIFT_NAME("four()"), // expected-warning {{'__swift_name__' attribute has invalid identifier for the base name}}
+};
+
+struct SWIFT_NAME("TStruct") SStruct {
+ int i, j, k SWIFT_NAME("kay");
+};
+
+int i SWIFT_NAME("g_i");
+
+void f0(int i) SWIFT_NAME("f_0");
+// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
+
+void f1(int i) SWIFT_NAME("f_1()");
+// expected-warning@-1 {{too few parameters in '__swift_name__' attribute (expected 1; got 0)}}
+
+void f2(int i) SWIFT_NAME("f_2(a:b:)");
+// expected-warning@-1 {{too many parameters in '__swift_name__' attribute (expected 1; got 2)}}
+
+void f3(int x, int y) SWIFT_NAME("fWithX(_:y:)");
+void f4(int x, int *error) SWIFT_NAME("fWithX(_:)");
+
+typedef int int_t SWIFT_NAME("IntType");
+
+struct Point3D createPoint3D(float x, float y, float z) SWIFT_NAME("Point3D.init(x:y:z:)");
+struct Point3D rotatePoint3D(Point3D point, float radians) SWIFT_NAME("Point3D.rotate(self:radians:)");
+struct Point3D badRotatePoint3D(Point3D point, float radians) SWIFT_NAME("Point3D.rotate(radians:)");
+// expected-warning@-1 {{too few parameters in '__swift_name__' attribute (expected 2; got 1)}}
+
+extern struct Point3D identityPoint SWIFT_NAME("Point3D.identity");
+
+float Point3DGetMagnitude(Point3D point) SWIFT_NAME("getter:Point3D.magnitude(self:)");
+float Point3DGetMagnitudeAndSomethingElse(Point3D point, float f) SWIFT_NAME("getter:Point3D.magnitude(self:f:)");
+// expected-warning@-1 {{'__swift_name__' attribute for getter must not have any parameters besides 'self:'}}
+
+float Point3DGetRadius(Point3D point) SWIFT_NAME("getter:Point3D.radius(self:)");
+void Point3DSetRadius(Point3D point, float radius) SWIFT_NAME("setter:Point3D.radius(self:newValue:)");
+
+float Point3DPreGetRadius(Point3D point) SWIFT_NAME("getter:Point3D.preRadius(self:)");
+void Point3DPreSetRadius(float radius, Point3D point) SWIFT_NAME("setter:Point3D.preRadius(newValue:self:)");
+
+void Point3DSetRadiusAndSomethingElse(Point3D point, float radius, float f) SWIFT_NAME("setter:Point3D.radius(self:newValue:f:)");
+// expected-warning@-1 {{'__swift_name__' attribute for setter must have one parameter for new value}}
+
+float Point3DGetComponent(Point3D point, unsigned index) SWIFT_NAME("getter:Point3D.subscript(self:_:)");
+float Point3DSetComponent(Point3D point, unsigned index, float value) SWIFT_NAME("setter:Point3D.subscript(self:_:newValue:)");
+
+float Point3DGetMatrixComponent(Point3D point, unsigned x, unsigned y) SWIFT_NAME("getter:Point3D.subscript(self:x:y:)");
+void Point3DSetMatrixComponent(Point3D point, unsigned x, float value, unsigned y) SWIFT_NAME("setter:Point3D.subscript(self:x:newValue:y:)");
+
+float Point3DSetWithoutNewValue(Point3D point, unsigned x, unsigned y) SWIFT_NAME("setter:Point3D.subscript(self:x:y:)");
+// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' setter must have a 'newValue:' parameter}}
+
+float Point3DSubscriptButNotGetterSetter(Point3D point, unsigned x) SWIFT_NAME("Point3D.subscript(self:_:)");
+// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' must be a getter or setter}}
+
+void Point3DSubscriptSetterTwoNewValues(Point3D point, unsigned x, float a, float b) SWIFT_NAME("setter:Point3D.subscript(self:_:newValue:newValue:)");
+// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' setter cannot have multiple 'newValue:' parameters}}
+
+float Point3DSubscriptGetterNewValue(Point3D point, unsigned x, float a, float b) SWIFT_NAME("getter:Point3D.subscript(self:_:newValue:newValue:)");
+// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' getter cannot have a 'newValue:' parameter}}
+
+void Point3DMethodWithNewValue(Point3D point, float newValue) SWIFT_NAME("Point3D.method(self:newValue:)");
+void Point3DMethodWithNewValues(Point3D point, float newValue, float newValueB) SWIFT_NAME("Point3D.method(self:newValue:newValue:)");
+
+float Point3DStaticSubscript(unsigned x) SWIFT_NAME("getter:Point3D.subscript(_:)");
+// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' must have a 'self:' parameter}}
+
+float Point3DStaticSubscriptNoArgs(void) SWIFT_NAME("getter:Point3D.subscript()");
+// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' must have at least one parameter}}
+
+float Point3DPreGetComponent(Point3D point, unsigned index) SWIFT_NAME("getter:Point3D.subscript(self:_:)");
+
+Point3D getCurrentPoint3D(void) SWIFT_NAME("getter:currentPoint3D()");
+
+void setCurrentPoint3D(Point3D point) SWIFT_NAME("setter:currentPoint3D(newValue:)");
+
+Point3D getLastPoint3D(void) SWIFT_NAME("getter:lastPoint3D()");
+
+void setLastPoint3D(Point3D point) SWIFT_NAME("setter:lastPoint3D(newValue:)");
+
+Point3D getZeroPoint(void) SWIFT_NAME("getter:Point3D.zero()");
+void setZeroPoint(Point3D point) SWIFT_NAME("setter:Point3D.zero(newValue:)");
+Point3D getZeroPointNoPrototype() SWIFT_NAME("getter:Point3D.zeroNoPrototype()");
+// expected-warning@-1 {{'__swift_name__' attribute only applies to non-K&R-style functions}}
+
+Point3D badGetter1(int x) SWIFT_NAME("getter:bad1(_:)");
+// expected-warning@-1 {{'__swift_name__' attribute for getter must not have any parameters besides 'self:'}}
+
+void badSetter1(void) SWIFT_NAME("getter:bad1())");
+// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
+
+Point3D badGetter2(Point3D point) SWIFT_NAME("getter:bad2(_:))");
+// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
+
+void badSetter2(Point3D point) SWIFT_NAME("setter:bad2(self:))");
+// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
+
+void g(int i) SWIFT_NAME("function(int:)");
+// expected-note@-1 {{conflicting attribute is here}}
+
+// expected-error@+1 {{'swift_name' and 'swift_name' attributes are not compatible}}
+void g(int i) SWIFT_NAME("function(_:)") {
+}