Skip to content

Commit 8afaf3a

Browse files
milsemanMForster
authored andcommitted
[Upstream] Add attributes for Swift
AST attributes: NSErrorDomain, SwiftBridge, SwiftBridgedTypedef, SwiftError, SwiftName, SwiftNewtype, SwiftObjCMembers, SwiftPrivate Module attribute: swift_infer_import_as_member
1 parent a5569f0 commit 8afaf3a

24 files changed

+1172
-26
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ def NonStaticNonConstCXXMethod
101101
[{!S->isStatic() && !S->isConst()}],
102102
"non-static non-const member functions">;
103103

104+
def ObjCClassMethod : SubsetSubject<ObjCMethod,
105+
[{!S->isInstanceMethod()}],
106+
"Objective-C class methods">;
107+
104108
def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
105109
[{S->isInstanceMethod()}],
106110
"Objective-C instance methods">;
@@ -1856,6 +1860,12 @@ def ObjCBridgeRelated : InheritableAttr {
18561860
let Documentation = [Undocumented];
18571861
}
18581862

1863+
def NSErrorDomain : Attr {
1864+
let Spellings = [GNU<"ns_error_domain">];
1865+
let Args = [IdentifierArgument<"ErrorDomain">];
1866+
let Documentation = [NSErrorDomainDocs];
1867+
}
1868+
18591869
def NSReturnsRetained : DeclOrTypeAttr {
18601870
let Spellings = [Clang<"ns_returns_retained">];
18611871
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
@@ -1954,6 +1964,12 @@ def ObjCSubclassingRestricted : InheritableAttr {
19541964
let SimpleHandler = 1;
19551965
}
19561966

1967+
def ObjCCompleteDefinition : InheritableAttr {
1968+
let Spellings = [GNU<"objc_complete_definition">];
1969+
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
1970+
let Documentation = [Undocumented];
1971+
}
1972+
19571973
def ObjCExplicitProtocolImpl : InheritableAttr {
19581974
let Spellings = [Clang<"objc_protocol_requires_explicit_implementation">];
19591975
let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
@@ -2087,6 +2103,60 @@ def Regparm : TypeAttr {
20872103
let ASTNode = 0;
20882104
}
20892105

2106+
def SwiftBridge : Attr {
2107+
let Spellings = [GNU<"swift_bridge">];
2108+
let Subjects = SubjectList<[Tag, TypedefName, ObjCInterface, ObjCProtocol],
2109+
ErrorDiag, "ExpectedType">;
2110+
let Args = [StringArgument<"SwiftType">];
2111+
let Documentation = [SwiftBridgeDocs];
2112+
}
2113+
2114+
def SwiftBridgedTypedef : Attr {
2115+
let Spellings = [GNU<"swift_bridged_typedef">];
2116+
let Subjects = SubjectList<[TypedefName], ErrorDiag, "typedefs">;
2117+
let Args = [];
2118+
let Documentation = [SwiftBridgedTypedefDocs];
2119+
}
2120+
2121+
def SwiftObjCMembers : Attr {
2122+
let Spellings = [GNU<"swift_objc_members">];
2123+
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
2124+
let Documentation = [SwiftObjCMembersDocs];
2125+
}
2126+
2127+
def SwiftError : InheritableAttr {
2128+
let Spellings = [GCC<"swift_error">];
2129+
let Args = [EnumArgument<"Convention", "ConventionKind",
2130+
["none", "nonnull_error", "null_result", "zero_result", "nonzero_result"],
2131+
["None", "NonNullError", "NullResult", "ZeroResult", "NonZeroResult"]>];
2132+
let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
2133+
let Documentation = [SwiftErrorDocs];
2134+
}
2135+
2136+
def SwiftName : InheritableAttr {
2137+
let Spellings = [GCC<"swift_name">];
2138+
let Args = [StringArgument<"Name">];
2139+
// Proper subject list disabled because of the custom error needed.
2140+
// Let's avoid merge conflicts for now.
2141+
// let Subjects = SubjectList<[EnumConstant, ObjCProtocol, ObjCClassMethod],
2142+
// ErrorDiag, "ExpectedSwiftNameSubjects">;
2143+
let Documentation = [Undocumented];
2144+
}
2145+
2146+
def SwiftNewtype : InheritableAttr {
2147+
let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">];
2148+
let Subjects = SubjectList<[TypedefName], ErrorDiag, "ExpectedType">;
2149+
let Args = [EnumArgument<"NewtypeKind", "NewtypeKind",
2150+
["struct", "enum"],
2151+
["NK_Struct", "NK_Enum"]>];
2152+
let Documentation = [SwiftNewtypeDocs];
2153+
}
2154+
2155+
def SwiftPrivate : InheritableAttr {
2156+
let Spellings = [GCC<"swift_private">];
2157+
let Documentation = [Undocumented];
2158+
}
2159+
20902160
def NoDeref : TypeAttr {
20912161
let Spellings = [Clang<"noderef">];
20922162
let Documentation = [NoDerefDocs];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3348,6 +3348,72 @@ where clause is one of the following:
33483348
}];
33493349
}
33503350

3351+
def SwiftDocs : DocumentationCategory<"Controlling Swift Import"> {
3352+
let Content = [{
3353+
Clang supports additional attributes for controlling how APIs are imported into Swift.
3354+
}];
3355+
}
3356+
3357+
def NSErrorDomainDocs : Documentation {
3358+
let Category = DocCatFunction;
3359+
let Content = [{
3360+
The ``ns_error_domain`` attribute indicates a global constant representing the error domain.
3361+
}];
3362+
}
3363+
3364+
def SwiftBridgeDocs : Documentation {
3365+
let Category = SwiftDocs;
3366+
let Content = [{
3367+
The ``swift_bridge`` attribute indicates that the type to which the attribute appertains is bridged to the named Swift type.
3368+
}];
3369+
}
3370+
3371+
def SwiftBridgedTypedefDocs : Documentation {
3372+
let Category = SwiftDocs;
3373+
let Content = [{
3374+
The ``swift_bridged_typedef`` attribute indicates that, when the typedef to which the attribute appertains is imported into Swift, it should refer to the bridged Swift type (e.g., Swift's ``String``) rather than the Objective-C type as written (e.g., ``NSString``).
3375+
}];
3376+
}
3377+
3378+
def SwiftObjCMembersDocs : Documentation {
3379+
let Category = SwiftDocs;
3380+
let Content = [{
3381+
The ``swift_objc_members`` attribute maps to the Swift ``@objcMembers`` attribute, which indicates that Swift members of this class, its subclasses, and all of the extensions thereof, will implicitly be exposed back to Objective-C.
3382+
}];
3383+
}
3384+
3385+
def SwiftErrorDocs : Documentation {
3386+
let Category = SwiftDocs;
3387+
let Heading = "swift_error";
3388+
let Content = [{
3389+
The ``swift_error`` attribute controls whether a particular function (or Objective-C method) is imported into Swift as a throwing function, and if so, the dynamic convention it uses.
3390+
3391+
All of these conventions except ``none`` require the function to have an error parameter. Currently, the error parameter is always the last parameter of type ``NSError**`` or ``CFErrorRef*``. Swift will remove the error parameter from the imported API, and dynamically will always pass a valid address initialized to a null pointer.
3392+
3393+
* ``swift_error(none)`` means that the function should not be imported as throwing. The error parameter and result type will be left alone.
3394+
3395+
* ``swift_error(null_result)`` means that calls to the function should be considered to have thrown if they return a null value. The return type must be a pointer type, and it will be imported into Swift with a non-optional type. This is the default error convention for Objective-C methods that return pointers.
3396+
3397+
* ``swift_error(zero_result)`` means that calls to the function should be considered to have thrown if they return a zero result. The return type must be an integral type. If the return type would have been imported as ``Bool``, it is instead imported as ``Void``. This is the default error convention for Objective-C methods that return a type that would be imported as ``Bool``.
3398+
3399+
* ``swift_error(nonzero_result)`` means that calls to the function should be considered to have thrown if they return a non-zero result. The return type must be an integral type. If the return type would have been imported as ``Bool``, it is instead imported as ``Void``.
3400+
3401+
* ``swift_error(nonnull_error)`` means that calls to the function should be considered to have thrown if they leave a non-null error in the error parameter. The return type is left unmodified.
3402+
3403+
}];
3404+
}
3405+
3406+
def SwiftNewtypeDocs : Documentation {
3407+
let Category = SwiftDocs;
3408+
let Heading = "swift_newtype";
3409+
let Content = [{
3410+
The ``swift_newtype`` attribute indicates that the typedef to which the attribute appertains is imported as a new Swift type of the typedef's name.
3411+
* ``swift_newtype(struct)`` means that a Swift struct will be created for this typedef.
3412+
* ``swift_newtype(enum)`` means that a Swift enum will be created for this typedef.
3413+
}];
3414+
}
3415+
3416+
33513417
def OMPDeclareTargetDocs : Documentation {
33523418
let Category = DocCatFunction;
33533419
let Heading = "#pragma omp declare target";

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ def StringCompare : DiagGroup<"string-compare">;
547547
def StringPlusInt : DiagGroup<"string-plus-int">;
548548
def StringPlusChar : DiagGroup<"string-plus-char">;
549549
def StrncatSize : DiagGroup<"strncat-size">;
550+
def SwiftNameAttribute : DiagGroup<"swift-name-attribute">;
550551
def IntInBoolContext : DiagGroup<"int-in-bool-context">;
551552
def TautologicalTypeLimitCompare : DiagGroup<"tautological-type-limit-compare">;
552553
def TautologicalUnsignedZeroCompare : DiagGroup<"tautological-unsigned-zero-compare">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,6 +3940,67 @@ def err_objc_bridged_related_known_method : Error<
39403940
def err_objc_attr_protocol_requires_definition : Error<
39413941
"attribute %0 can only be applied to @protocol definitions, not forward declarations">;
39423942

3943+
// Swift attributes
3944+
def warn_attr_swift_name_decl_kind : Warning<
3945+
"%0 attribute cannot be applied to this declaration">,
3946+
InGroup<SwiftNameAttribute>;
3947+
def warn_attr_swift_name_function : Warning<
3948+
"parameter of %0 attribute must be a Swift function name string">,
3949+
InGroup<SwiftNameAttribute>;
3950+
def warn_attr_swift_name_function_no_prototype : Warning<
3951+
"%0 attribute can only be applied to function declarations with prototypes">,
3952+
InGroup<SwiftNameAttribute>;
3953+
def warn_attr_swift_name_context_name_invalid_identifier : Warning<
3954+
"%0 attribute has invalid identifier for context name">,
3955+
InGroup<SwiftNameAttribute>;
3956+
def warn_attr_swift_name_basename_invalid_identifier : Warning<
3957+
"%0 attribute has invalid identifier for base name">,
3958+
InGroup<SwiftNameAttribute>;
3959+
def warn_attr_swift_name_parameter_invalid_identifier : Warning<
3960+
"%0 attribute has invalid identifier for parameter name">,
3961+
InGroup<SwiftNameAttribute>;
3962+
def warn_attr_swift_name_missing_parameters : Warning<
3963+
"%0 attribute is missing parameter label clause">,
3964+
InGroup<SwiftNameAttribute>;
3965+
def warn_attr_swift_name_subscript_not_accessor : Warning<
3966+
"%0 attribute for 'subscript' must be a getter or setter">,
3967+
InGroup<SwiftNameAttribute>;
3968+
def warn_attr_swift_name_subscript_no_parameter : Warning<
3969+
"%0 attribute for 'subscript' must take at least one parameter">,
3970+
InGroup<SwiftNameAttribute>;
3971+
def warn_attr_swift_name_subscript_getter_newValue : Warning<
3972+
"%0 attribute for 'subscript' getter cannot take a 'newValue:' parameter">,
3973+
InGroup<SwiftNameAttribute>;
3974+
def warn_attr_swift_name_subscript_setter_no_newValue : Warning<
3975+
"%0 attribute for 'subscript' setter must take a 'newValue:' parameter">,
3976+
InGroup<SwiftNameAttribute>;
3977+
def warn_attr_swift_name_subscript_setter_multiple_newValues : Warning<
3978+
"%0 attribute for 'subscript' setter cannot take multiple 'newValue:' parameters">,
3979+
InGroup<SwiftNameAttribute>;
3980+
def warn_attr_swift_name_getter_parameters : Warning<
3981+
"%0 attribute for getter must not take any parameters besides 'self:'">,
3982+
InGroup<SwiftNameAttribute>;
3983+
def warn_attr_swift_name_setter_parameters : Warning<
3984+
"%0 attribute for setter must take one parameter for new value">,
3985+
InGroup<SwiftNameAttribute>;
3986+
def warn_attr_swift_name_multiple_selfs : Warning<
3987+
"%0 attribute cannot specify more than one 'self:' parameter">,
3988+
InGroup<SwiftNameAttribute>;
3989+
def warn_attr_swift_name_static_subscript : Warning<
3990+
"%0 attribute for 'subscript' must take a 'self:' parameter">,
3991+
InGroup<SwiftNameAttribute>;
3992+
def warn_attr_swift_name_num_params : Warning<
3993+
"too %select{few|many}0 parameters in %1 attribute (expected %2; got %3)">,
3994+
InGroup<SwiftNameAttribute>;
3995+
def err_attr_swift_error_no_error_parameter : Error<
3996+
"%0 attribute can only be applied to a %select{function|method}1 "
3997+
"with an error parameter">;
3998+
def err_attr_swift_error_return_type : Error<
3999+
"%0 attribute with '%1' convention can only be applied to a "
4000+
"%select{function|method}2 returning %select{an integral type|a pointer}3">;
4001+
def warn_swift_newtype_attribute_non_typedef : Warning<
4002+
"'swift_newtype' attribute may be put on a typedef only; "
4003+
"attribute is ignored">, InGroup<DiagGroup<"swift-newtype-attribute">>;
39434004
def warn_ignored_objc_externally_retained : Warning<
39444005
"'objc_externally_retained' can only be applied to local variables "
39454006
"%select{of retainable type|with strong ownership}0">,
@@ -9437,6 +9498,14 @@ def err_nsconsumed_attribute_mismatch : Error<
94379498
def err_nsreturns_retained_attribute_mismatch : Error<
94389499
"overriding method has mismatched ns_returns_%select{not_retained|retained}0"
94399500
" attributes">;
9501+
def err_nserrordomain_not_tagdecl : Error<
9502+
"ns_error_domain attribute only valid on "
9503+
"%select{enums, structs, and unions|enums, structs, unions, and classes}0">;
9504+
def err_nserrordomain_invalid_decl : Error<
9505+
"domain argument %0 does not refer to global constant">;
9506+
def err_nserrordomain_requires_identifier : Error<
9507+
"domain argument must be an identifier">;
9508+
94409509
def warn_nsconsumed_attribute_mismatch : Warning<
94419510
err_nsconsumed_attribute_mismatch.Text>, InGroup<NSConsumedMismatch>;
94429511
def warn_nsreturns_retained_attribute_mismatch : Warning<

clang/include/clang/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ FEATURE(c_thread_safety_attributes, true)
8383
FEATURE(cxx_exceptions, LangOpts.CXXExceptions)
8484
FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData)
8585
FEATURE(enumerator_attributes, true)
86+
FEATURE(generalized_swift_name, true)
8687
FEATURE(nullability, true)
8788
FEATURE(nullability_on_arrays, true)
8889
FEATURE(memory_sanitizer,

clang/include/clang/Basic/Module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ class Module {
293293
/// to a regular (public) module map.
294294
unsigned ModuleMapIsPrivate : 1;
295295

296+
/// \brief Whether this is a module who has its swift_names inferred.
297+
unsigned IsSwiftInferImportAsMember : 1;
298+
296299
/// Whether Umbrella is a directory or header.
297300
unsigned HasUmbrellaDir : 1;
298301

clang/include/clang/Lex/ModuleMap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ class ModuleMap {
237237
/// Whether this is an exhaustive set of configuration macros.
238238
unsigned IsExhaustive : 1;
239239

240+
/// \brief Whether this is a module who has its swift_names inferred.
241+
unsigned IsSwiftInferImportAsMember : 1;
242+
240243
/// Whether files in this module can only include non-modular headers
241244
/// and headers from used modules.
242245
unsigned NoUndeclaredIncludes : 1;

clang/include/clang/Parse/Parser.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2787,6 +2787,14 @@ class Parser : public CodeCompletionHandler {
27872787
SourceLocation ScopeLoc,
27882788
ParsedAttr::Syntax Syntax);
27892789

2790+
void ParseSwiftNewtypeAttribute(IdentifierInfo &SwiftNewtype,
2791+
SourceLocation SwiftNewtypeLoc,
2792+
ParsedAttributes &attrs,
2793+
SourceLocation *endLoc,
2794+
IdentifierInfo *ScopeName,
2795+
SourceLocation ScopeLoc,
2796+
ParsedAttr::Syntax Syntax);
2797+
27902798
void
27912799
ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
27922800
SourceLocation AttrNameLoc, ParsedAttributes &Attrs,

clang/include/clang/Sema/Sema.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,24 @@ class Sema final {
18341834
}
18351835
};
18361836

1837+
/// Do a check to make sure \p Name looks like a legal swift_name
1838+
/// attribute for the decl \p D. Raise a diagnostic if the name is invalid
1839+
/// for the given declaration.
1840+
///
1841+
/// For a function, this will validate a compound Swift name,
1842+
/// e.g. <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>,
1843+
/// and the function will output the number of parameter names, and whether
1844+
/// this is a single-arg initializer.
1845+
///
1846+
/// For a type, enum constant, property, or variable declaration, this will
1847+
/// validate either a simple identifier, or a qualified
1848+
/// <code>context.identifier</code> name.
1849+
///
1850+
/// \returns true if the name is a valid swift name for \p D, false otherwise.
1851+
bool DiagnoseSwiftName(Decl *D, StringRef Name,
1852+
SourceLocation ArgLoc,
1853+
const IdentifierInfo *AttrName);
1854+
18371855
/// A derivative of BoundTypeDiagnoser for which the diagnostic's type
18381856
/// parameter is preceded by a 0/1 enum that is 1 if the type is sizeless.
18391857
/// For example, a diagnostic with no other parameters would generally have
@@ -3051,6 +3069,8 @@ class Sema final {
30513069
const SpeculativeLoadHardeningAttr &AL);
30523070
OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D,
30533071
const AttributeCommonInfo &CI);
3072+
SwiftNameAttr *mergeSwiftNameAttr(Decl *D, const AttributeCommonInfo &CI,
3073+
StringRef Name, bool Override);
30543074
InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL);
30553075
InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D,
30563076
const InternalLinkageAttr &AL);
@@ -12375,6 +12395,7 @@ class Sema final {
1237512395

1237612396
/// The struct behind the CFErrorRef pointer.
1237712397
RecordDecl *CFError = nullptr;
12398+
bool isCFError(RecordDecl *D);
1237812399

1237912400
/// Retrieve the identifier "NSError".
1238012401
IdentifierInfo *getNSErrorIdent();

clang/lib/Basic/Module.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,19 @@ using namespace clang;
3737
Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
3838
bool IsFramework, bool IsExplicit, unsigned VisibilityID)
3939
: Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
40+
Directory(), Umbrella(), ASTFile(nullptr),
4041
VisibilityID(VisibilityID), IsUnimportable(false),
4142
HasIncompatibleModuleFile(false), IsAvailable(true),
4243
IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
4344
IsSystem(false), IsExternC(false), IsInferred(false),
4445
InferSubmodules(false), InferExplicitSubmodules(false),
4546
InferExportWildcard(false), ConfigMacrosExhaustive(false),
4647
NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
48+
49+
// SWIFT-SPECIFIC FIELDS HERE. Handling them separately helps avoid merge
50+
// conflicts.
51+
IsSwiftInferImportAsMember(false),
52+
4753
HasUmbrellaDir(false), NameVisibility(Hidden) {
4854
if (Parent) {
4955
IsAvailable = Parent->isAvailable();
@@ -448,6 +454,8 @@ void Module::print(raw_ostream &OS, unsigned Indent) const {
448454
OS << " [system]";
449455
if (IsExternC)
450456
OS << " [extern_c]";
457+
if (IsSwiftInferImportAsMember)
458+
OS << " [swift_infer_import_as_member]";
451459
}
452460

453461
OS << " {\n";

0 commit comments

Comments
 (0)