Skip to content

Commit c5eae9d

Browse files
author
git apple-llvm automerger
committed
Merge commit 'dab98f483674' from apple/stable/20200714 into swift/main
2 parents 69fb3d5 + dab98f4 commit c5eae9d

35 files changed

+512
-32
lines changed

clang/include/clang-c/Index.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3861,7 +3861,15 @@ enum CXTypeNullabilityKind {
38613861
/**
38623862
* Nullability is not applicable to this type.
38633863
*/
3864-
CXTypeNullability_Invalid = 3
3864+
CXTypeNullability_Invalid = 3,
3865+
3866+
/**
3867+
* Generally behaves like Nullable, except when used in a block parameter that
3868+
* was imported into a swift async method. There, swift will assume that the
3869+
* parameter can get null even if no error occured. _Nullable parameters are
3870+
* assumed to only get null on error.
3871+
*/
3872+
CXTypeNullability_NullableResult = 4
38653873
};
38663874

38673875
/**

clang/include/clang/AST/Type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4874,6 +4874,9 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
48744874
case NullabilityKind::Nullable:
48754875
return attr::TypeNullable;
48764876

4877+
case NullabilityKind::NullableResult:
4878+
return attr::TypeNullableResult;
4879+
48774880
case NullabilityKind::Unspecified:
48784881
return attr::TypeNullUnspecified;
48794882
}

clang/include/clang/Basic/Attr.td

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,11 @@ def TypeNullable : TypeAttr {
17611761
let Documentation = [TypeNullableDocs];
17621762
}
17631763

1764+
def TypeNullableResult : TypeAttr {
1765+
let Spellings = [Keyword<"_Nullable_result">];
1766+
let Documentation = [TypeNullableResultDocs];
1767+
}
1768+
17641769
def TypeNullUnspecified : TypeAttr {
17651770
let Spellings = [Keyword<"_Null_unspecified">];
17661771
let Documentation = [TypeNullUnspecifiedDocs];
@@ -2106,6 +2111,19 @@ def Regparm : TypeAttr {
21062111
let ASTNode = 0;
21072112
}
21082113

2114+
def SwiftAsyncName : InheritableAttr {
2115+
let Spellings = [GNU<"swift_async_name">];
2116+
let Args = [StringArgument<"Name">];
2117+
let Subjects = SubjectList<[ObjCMethod, Function], ErrorDiag>;
2118+
let Documentation = [SwiftAsyncNameDocs];
2119+
}
2120+
2121+
def SwiftAttr : InheritableAttr {
2122+
let Spellings = [GNU<"swift_attr">];
2123+
let Args = [StringArgument<"Attribute">];
2124+
let Documentation = [SwiftAttrDocs];
2125+
}
2126+
21092127
def SwiftBridge : Attr {
21102128
let Spellings = [GNU<"swift_bridge">];
21112129
let Subjects = SubjectList<[Tag, TypedefName, ObjCInterface, ObjCProtocol],
@@ -2168,7 +2186,7 @@ def SwiftImportAsNonGeneric : InheritableAttr {
21682186
let Documentation = [Undocumented];
21692187
}
21702188

2171-
def SwiftImportPropertyAsAccessors : InheritableAttr {
2189+
def SwiftImportPropertyAsAccessors : InheritableAttr {
21722190
// This attribute has no spellings as it is only ever created implicitly
21732191
// from API notes.
21742192
let Spellings = [];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3440,6 +3440,29 @@ a caller of ``fetch_or_zero`` can provide null.
34403440
}];
34413441
}
34423442

3443+
def TypeNullableResultDocs : Documentation {
3444+
let Category = NullabilityDocs;
3445+
let Content = [{
3446+
The ``_Nullable_result`` nullability qualifier means that a value of the
3447+
``_Nullable_result`` pointer can be ``nil``, just like ``_Nullable``. Where this
3448+
attribute differs from ``_Nullable`` is when it's used on a parameter to a
3449+
completion handler in a Swift async method. For instance, here:
3450+
3451+
.. code-block:: objc
3452+
3453+
-(void)fetchSomeDataWithID:(int)identifier
3454+
completionHandler:(void (^)(Data *_Nullable_result result, NSError *error))completionHandler;
3455+
3456+
This method asynchronously calls ``completionHandler`` when the data is
3457+
available, or calls it with an error. ``_Nullable_result`` indicates to the
3458+
Swift importer that this is the uncommon case where ``result`` can get ``nil``
3459+
even if no error has occured, and will therefore import it as a Swift optional
3460+
type. Otherwise, if ``result`` was annotated with ``_Nullable``, the Swift
3461+
importer will assume that ``result`` will always be non-nil unless an error
3462+
occured.
3463+
}];
3464+
}
3465+
34433466
def TypeNullUnspecifiedDocs : Documentation {
34443467
let Category = NullabilityDocs;
34453468
let Content = [{
@@ -3546,6 +3569,40 @@ The ``ns_error_domain`` attribute indicates a global constant representing the e
35463569
}];
35473570
}
35483571

3572+
def SwiftAsyncNameDocs : Documentation {
3573+
let Category = SwiftDocs;
3574+
let Heading = "swift_async_name";
3575+
let Content = [{
3576+
The ``swift_async_name`` attribute provides the name of the ``async`` overload for
3577+
the given declaration in Swift. If this attribute is absent, the name is
3578+
transformed according to the algorithm built into the Swift compiler.
3579+
3580+
The argument is a string literal that contains the Swift name of the function or
3581+
method. The name may be a compound Swift name. The function or method with such
3582+
an attribute must have more than zero parameters, as its last parameter is
3583+
assumed to be a callback that's eliminated in the Swift ``async`` name.
3584+
3585+
.. code-block:: objc
3586+
3587+
@interface URL
3588+
+ (void) loadContentsFrom:(URL *)url callback:(void (^)(NSData *))data __attribute__((__swift_async_name__("URL.loadContentsFrom(_:)")))
3589+
@end
3590+
}];
3591+
}
3592+
3593+
def SwiftAttrDocs : Documentation {
3594+
let Category = SwiftDocs;
3595+
let Heading = "swift_attr";
3596+
let Content = [{
3597+
The ``swift_attr`` provides a Swift-specific annotation for the declaration
3598+
to which the attribute appertains to. It can be used on any declaration
3599+
in Clang. This kind of annotation is ignored by Clang as it doesn't have any
3600+
semantic meaning in languages supported by Clang. The Swift compiler can
3601+
interpret these annotations according to its own rules when importing C or
3602+
Objective-C declarations.
3603+
}];
3604+
}
3605+
35493606
def SwiftBridgeDocs : Documentation {
35503607
let Category = SwiftDocs;
35513608
let Content = [{

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,10 @@ def warn_objc_direct_property_ignored : Warning<
11091109
InGroup<IgnoredAttributes>;
11101110
def err_objc_direct_dynamic_property : Error<
11111111
"direct property cannot be @dynamic">;
1112+
def err_objc_direct_protocol_conformance : Error<
1113+
"%select{category %1|class extension}0 cannot conform to protocol %2 because "
1114+
"of direct members declared in interface %3">;
1115+
def note_direct_member_here : Note<"direct member declared here">;
11121116

11131117
def warn_conflicting_overriding_ret_types : Warning<
11141118
"conflicting return type in "
@@ -4062,9 +4066,15 @@ def warn_attr_swift_name_multiple_selfs : Warning<
40624066
def warn_attr_swift_name_static_subscript : Warning<
40634067
"%0 attribute for 'subscript' must take a 'self:' parameter">,
40644068
InGroup<SwiftNameAttribute>;
4065-
def warn_attr_swift_name_num_params : Warning<
4066-
"too %select{few|many}0 parameters in %1 attribute (expected %2; got %3)">,
4067-
InGroup<SwiftNameAttribute>;
4069+
def warn_attr_swift_name_num_params
4070+
: Warning<"too %select{few|many}0 parameters in the signature specified by "
4071+
"the %1 attribute (expected %2; got %3)">,
4072+
InGroup<SwiftNameAttribute>;
4073+
def warn_attr_swift_name_decl_missing_params
4074+
: Warning<"%0 attribute cannot be applied to a %select{function|method}1 "
4075+
"with no parameters">,
4076+
InGroup<SwiftNameAttribute>;
4077+
40684078
def err_attr_swift_error_no_error_parameter : Error<
40694079
"%0 attribute can only be applied to a %select{function|method}1 "
40704080
"with an error parameter">;

clang/include/clang/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ FEATURE(enumerator_attributes, true)
8787
FEATURE(generalized_swift_name, true)
8888
FEATURE(nullability, true)
8989
FEATURE(nullability_on_arrays, true)
90+
FEATURE(nullability_nullable_result, true)
9091
FEATURE(memory_sanitizer,
9192
LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory |
9293
SanitizerKind::KernelMemory))

clang/include/clang/Basic/Specifiers.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,12 @@ namespace clang {
326326
/// unspecified. This captures a (fairly rare) case where we
327327
/// can't conclude anything about the nullability of the type even
328328
/// though it has been considered.
329-
Unspecified
329+
Unspecified,
330+
// Generally behaves like Nullable, except when used in a block parameter
331+
// that was imported into a swift async method. There, swift will assume
332+
// that the parameter can get null even if no error occured. _Nullable
333+
// parameters are assumed to only get null on error.
334+
NullableResult,
330335
};
331336

332337
/// Return true if \p L has a weaker nullability annotation than \p R. The

clang/include/clang/Basic/TokenKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ ALIAS("__volatile__" , volatile , KEYALL)
652652
// Type nullability.
653653
KEYWORD(_Nonnull , KEYALL)
654654
KEYWORD(_Nullable , KEYALL)
655+
KEYWORD(_Nullable_result , KEYALL)
655656
KEYWORD(_Null_unspecified , KEYALL)
656657

657658
// Microsoft extensions which should be disabled in strict conformance mode

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1857,7 +1857,7 @@ class Sema final {
18571857
/// \returns true if the name is a valid swift name for \p D, false otherwise.
18581858
bool DiagnoseSwiftName(Decl *D, StringRef Name,
18591859
SourceLocation ArgLoc,
1860-
const IdentifierInfo *AttrName);
1860+
const IdentifierInfo *AttrName, bool IsAsync);
18611861

18621862
/// A derivative of BoundTypeDiagnoser for which the diagnostic's type
18631863
/// parameter is preceded by a 0/1 enum that is 1 if the type is sizeless.
@@ -12421,6 +12421,7 @@ class Sema final {
1242112421
/// Nullability type specifiers.
1242212422
IdentifierInfo *Ident__Nonnull = nullptr;
1242312423
IdentifierInfo *Ident__Nullable = nullptr;
12424+
IdentifierInfo *Ident__Nullable_result = nullptr;
1242412425
IdentifierInfo *Ident__Null_unspecified = nullptr;
1242512426

1242612427
IdentifierInfo *Ident_NSError = nullptr;

clang/lib/AST/Type.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3451,6 +3451,7 @@ bool AttributedType::isQualifier() const {
34513451
case attr::ObjCInertUnsafeUnretained:
34523452
case attr::TypeNonNull:
34533453
case attr::TypeNullable:
3454+
case attr::TypeNullableResult:
34543455
case attr::TypeNullUnspecified:
34553456
case attr::LifetimeBound:
34563457
case attr::AddressSpace:
@@ -4095,6 +4096,8 @@ AttributedType::getImmediateNullability() const {
40954096
return NullabilityKind::Nullable;
40964097
if (getAttrKind() == attr::TypeNullUnspecified)
40974098
return NullabilityKind::Unspecified;
4099+
if (getAttrKind() == attr::TypeNullableResult)
4100+
return NullabilityKind::NullableResult;
40984101
return None;
40994102
}
41004103

clang/lib/AST/TypePrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,8 @@ void TypePrinter::printAttributedBefore(const AttributedType *T,
15171517
OS << " _Nullable";
15181518
else if (T->getAttrKind() == attr::TypeNullUnspecified)
15191519
OS << " _Null_unspecified";
1520+
else if (T->getAttrKind() == attr::TypeNullableResult)
1521+
OS << " _Nullable_result";
15201522
else
15211523
llvm_unreachable("unhandled nullability");
15221524
spaceBeforePlaceHolder(OS);
@@ -1585,6 +1587,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
15851587
case attr::LifetimeBound:
15861588
case attr::TypeNonNull:
15871589
case attr::TypeNullable:
1590+
case attr::TypeNullableResult:
15881591
case attr::TypeNullUnspecified:
15891592
case attr::ObjCGC:
15901593
case attr::ObjCInertUnsafeUnretained:

clang/lib/Basic/Diagnostic.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
5555
case NullabilityKind::Unspecified:
5656
string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'";
5757
break;
58+
59+
case NullabilityKind::NullableResult:
60+
assert(!nullability.second &&
61+
"_Nullable_result isn't supported as context-sensitive keyword");
62+
string = "_Nullable_result";
63+
break;
5864
}
5965

6066
DB.AddString(string);

clang/lib/Basic/IdentifierTable.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,11 @@ StringRef clang::getNullabilitySpelling(NullabilityKind kind,
714714
case NullabilityKind::Nullable:
715715
return isContextSensitive ? "nullable" : "_Nullable";
716716

717+
case NullabilityKind::NullableResult:
718+
assert(!isContextSensitive &&
719+
"_Nullable_result isn't supported as context-sensitive keyword");
720+
return "_Nullable_result";
721+
717722
case NullabilityKind::Unspecified:
718723
return isContextSensitive ? "null_unspecified" : "_Null_unspecified";
719724
}

clang/lib/Parse/ParseDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,7 @@ void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {
861861
switch (Tok.getKind()) {
862862
case tok::kw__Nonnull:
863863
case tok::kw__Nullable:
864+
case tok::kw__Nullable_result:
864865
case tok::kw__Null_unspecified: {
865866
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
866867
SourceLocation AttrNameLoc = ConsumeToken();
@@ -3537,6 +3538,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
35373538
// Nullability type specifiers.
35383539
case tok::kw__Nonnull:
35393540
case tok::kw__Nullable:
3541+
case tok::kw__Nullable_result:
35403542
case tok::kw__Null_unspecified:
35413543
ParseNullabilityTypeSpecifiers(DS.getAttributes());
35423544
continue;
@@ -5016,6 +5018,7 @@ bool Parser::isTypeSpecifierQualifier() {
50165018

50175019
case tok::kw__Nonnull:
50185020
case tok::kw__Nullable:
5021+
case tok::kw__Nullable_result:
50195022
case tok::kw__Null_unspecified:
50205023

50215024
case tok::kw___kindof:
@@ -5244,6 +5247,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
52445247

52455248
case tok::kw__Nonnull:
52465249
case tok::kw__Nullable:
5250+
case tok::kw__Nullable_result:
52475251
case tok::kw__Null_unspecified:
52485252

52495253
case tok::kw___kindof:
@@ -5525,6 +5529,7 @@ void Parser::ParseTypeQualifierListOpt(
55255529
// Nullability type specifiers.
55265530
case tok::kw__Nonnull:
55275531
case tok::kw__Nullable:
5532+
case tok::kw__Nullable_result:
55285533
case tok::kw__Null_unspecified:
55295534
ParseNullabilityTypeSpecifiers(DS.getAttributes());
55305535
continue;

clang/lib/Parse/ParseTentative.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,8 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() {
842842

843843
while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
844844
tok::kw__Nonnull, tok::kw__Nullable,
845-
tok::kw__Null_unspecified, tok::kw__Atomic))
845+
tok::kw__Nullable_result, tok::kw__Null_unspecified,
846+
tok::kw__Atomic))
846847
ConsumeToken();
847848
} else {
848849
return TPResult::True;
@@ -1446,6 +1447,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
14461447
case tok::kw___unaligned:
14471448
case tok::kw__Nonnull:
14481449
case tok::kw__Nullable:
1450+
case tok::kw__Nullable_result:
14491451
case tok::kw__Null_unspecified:
14501452
case tok::kw___kindof:
14511453
return TPResult::True;

clang/lib/Sema/Sema.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,8 @@ void Sema::diagnoseNullableToNonnullConversion(QualType DstType,
499499
QualType SrcType,
500500
SourceLocation Loc) {
501501
Optional<NullabilityKind> ExprNullability = SrcType->getNullability(Context);
502-
if (!ExprNullability || *ExprNullability != NullabilityKind::Nullable)
502+
if (!ExprNullability || (*ExprNullability != NullabilityKind::Nullable &&
503+
*ExprNullability != NullabilityKind::NullableResult))
503504
return;
504505

505506
Optional<NullabilityKind> TypeNullability = DstType->getNullability(Context);

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ static void ProcessAPINotes(Sema &S, Decl *D,
316316
auto &APINoteName = S.getASTContext().Idents.get("SwiftName API Note");
317317

318318
if (!S.DiagnoseSwiftName(D, info.SwiftName, D->getLocation(),
319-
&APINoteName)) {
319+
&APINoteName, /*IsAsync=*/false)) {
320320
return nullptr;
321321
}
322322

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,6 +2657,10 @@ static std::string formatObjCParamQualifiers(unsigned ObjCQuals,
26572657
case NullabilityKind::Unspecified:
26582658
Result += "null_unspecified ";
26592659
break;
2660+
2661+
case NullabilityKind::NullableResult:
2662+
llvm_unreachable("Not supported as a context-sensitive keyword!");
2663+
break;
26602664
}
26612665
}
26622666
}

0 commit comments

Comments
 (0)