diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/APINotes/APINotesYAMLCompiler.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Basic/Diagnostic.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Basic/IdentifierTable.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 13 |
12 files changed, 60 insertions, 5 deletions
diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp index 997929a..a412012 100644 --- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp +++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp @@ -89,6 +89,7 @@ template <> struct ScalarEnumerationTraits<NullabilityKind> { IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull); IO.enumCase(NK, "Optional", NullabilityKind::Nullable); IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified); + IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult); // TODO: Mapping this to it's own value would allow for better cross // checking. Also the default should be Unknown. IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 1c29d3a..c07cab9 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3512,6 +3512,7 @@ bool AttributedType::isQualifier() const { case attr::ObjCInertUnsafeUnretained: case attr::TypeNonNull: case attr::TypeNullable: + case attr::TypeNullableResult: case attr::TypeNullUnspecified: case attr::LifetimeBound: case attr::AddressSpace: @@ -4159,6 +4160,8 @@ AttributedType::getImmediateNullability() const { return NullabilityKind::Nullable; if (getAttrKind() == attr::TypeNullUnspecified) return NullabilityKind::Unspecified; + if (getAttrKind() == attr::TypeNullableResult) + return NullabilityKind::NullableResult; return None; } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index b42ffde..54c4512 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1579,6 +1579,8 @@ void TypePrinter::printAttributedBefore(const AttributedType *T, OS << " _Nullable"; else if (T->getAttrKind() == attr::TypeNullUnspecified) OS << " _Null_unspecified"; + else if (T->getAttrKind() == attr::TypeNullableResult) + OS << " _Nullable_result"; else llvm_unreachable("unhandled nullability"); spaceBeforePlaceHolder(OS); @@ -1649,6 +1651,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::LifetimeBound: case attr::TypeNonNull: case attr::TypeNullable: + case attr::TypeNullableResult: case attr::TypeNullUnspecified: case attr::ObjCGC: case attr::ObjCInertUnsafeUnretained: diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 30a4c51..d3b2122 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -55,6 +55,12 @@ const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, case NullabilityKind::Unspecified: string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'"; break; + + case NullabilityKind::NullableResult: + assert(!nullability.second && + "_Nullable_result isn't supported as context-sensitive keyword"); + string = "_Nullable_result"; + break; } DB.AddString(string); diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index 36b26d9..51c6e02 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -714,6 +714,11 @@ StringRef clang::getNullabilitySpelling(NullabilityKind kind, case NullabilityKind::Nullable: return isContextSensitive ? "nullable" : "_Nullable"; + case NullabilityKind::NullableResult: + assert(!isContextSensitive && + "_Nullable_result isn't supported as context-sensitive keyword"); + return "_Nullable_result"; + case NullabilityKind::Unspecified: return isContextSensitive ? "null_unspecified" : "_Null_unspecified"; } diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index c3c56dd..7ebf06a 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -833,6 +833,7 @@ void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) { switch (Tok.getKind()) { case tok::kw__Nonnull: case tok::kw__Nullable: + case tok::kw__Nullable_result: case tok::kw__Null_unspecified: { IdentifierInfo *AttrName = Tok.getIdentifierInfo(); SourceLocation AttrNameLoc = ConsumeToken(); @@ -3536,6 +3537,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // Nullability type specifiers. case tok::kw__Nonnull: case tok::kw__Nullable: + case tok::kw__Nullable_result: case tok::kw__Null_unspecified: ParseNullabilityTypeSpecifiers(DS.getAttributes()); continue; @@ -5022,6 +5024,7 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw__Nonnull: case tok::kw__Nullable: + case tok::kw__Nullable_result: case tok::kw__Null_unspecified: case tok::kw___kindof: @@ -5249,6 +5252,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { case tok::kw__Nonnull: case tok::kw__Nullable: + case tok::kw__Nullable_result: case tok::kw__Null_unspecified: case tok::kw___kindof: @@ -5524,6 +5528,7 @@ void Parser::ParseTypeQualifierListOpt( // Nullability type specifiers. case tok::kw__Nonnull: case tok::kw__Nullable: + case tok::kw__Nullable_result: case tok::kw__Null_unspecified: ParseNullabilityTypeSpecifiers(DS.getAttributes()); continue; diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index d0f1d2e..3bf2bc4 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -842,7 +842,8 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() { while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict, tok::kw__Nonnull, tok::kw__Nullable, - tok::kw__Null_unspecified, tok::kw__Atomic)) + tok::kw__Nullable_result, tok::kw__Null_unspecified, + tok::kw__Atomic)) ConsumeToken(); } else { return TPResult::True; @@ -1437,6 +1438,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, case tok::kw___unaligned: case tok::kw__Nonnull: case tok::kw__Nullable: + case tok::kw__Nullable_result: case tok::kw__Null_unspecified: case tok::kw___kindof: return TPResult::True; diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index b99dc33..456daab 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -503,7 +503,8 @@ void Sema::diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType, SourceLocation Loc) { Optional<NullabilityKind> ExprNullability = SrcType->getNullability(Context); - if (!ExprNullability || *ExprNullability != NullabilityKind::Nullable) + if (!ExprNullability || (*ExprNullability != NullabilityKind::Nullable && + *ExprNullability != NullabilityKind::NullableResult)) return; Optional<NullabilityKind> TypeNullability = DstType->getNullability(Context); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 10fd552..243f68d 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2700,6 +2700,10 @@ static std::string formatObjCParamQualifiers(unsigned ObjCQuals, case NullabilityKind::Unspecified: Result += "null_unspecified "; break; + + case NullabilityKind::NullableResult: + llvm_unreachable("Not supported as a context-sensitive keyword!"); + break; } } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3183b09..738fe87 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -8562,8 +8562,12 @@ static QualType computeConditionalNullability(QualType ResTy, bool IsBin, auto GetNullability = [&Ctx](QualType Ty) { Optional<NullabilityKind> Kind = Ty->getNullability(Ctx); - if (Kind) + if (Kind) { + // For our purposes, treat _Nullable_result as _Nullable. + if (*Kind == NullabilityKind::NullableResult) + return NullabilityKind::Nullable; return *Kind; + } return NullabilityKind::Unspecified; }; diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index ced0952..f5456ee 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -1563,12 +1563,20 @@ QualType Sema::getMessageSendResultType(const Expr *Receiver, // Map the nullability of the result into a table index. unsigned receiverNullabilityIdx = 0; - if (auto nullability = ReceiverType->getNullability(Context)) + if (Optional<NullabilityKind> nullability = + ReceiverType->getNullability(Context)) { + if (*nullability == NullabilityKind::NullableResult) + nullability = NullabilityKind::Nullable; receiverNullabilityIdx = 1 + static_cast<unsigned>(*nullability); + } unsigned resultNullabilityIdx = 0; - if (auto nullability = resultType->getNullability(Context)) + if (Optional<NullabilityKind> nullability = + resultType->getNullability(Context)) { + if (*nullability == NullabilityKind::NullableResult) + nullability = NullabilityKind::Nullable; resultNullabilityIdx = 1 + static_cast<unsigned>(*nullability); + } // The table of nullability mappings, indexed by the receiver's nullability // and then the result type's nullability. diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 0d80bce..df46aa3 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -147,6 +147,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr, #define NULLABILITY_TYPE_ATTRS_CASELIST \ case ParsedAttr::AT_TypeNonNull: \ case ParsedAttr::AT_TypeNullable: \ + case ParsedAttr::AT_TypeNullableResult: \ case ParsedAttr::AT_TypeNullUnspecified namespace { @@ -3893,6 +3894,11 @@ IdentifierInfo *Sema::getNullabilityKeyword(NullabilityKind nullability) { Ident__Nullable = PP.getIdentifierInfo("_Nullable"); return Ident__Nullable; + case NullabilityKind::NullableResult: + if (!Ident__Nullable_result) + Ident__Nullable_result = PP.getIdentifierInfo("_Nullable_result"); + return Ident__Nullable_result; + case NullabilityKind::Unspecified: if (!Ident__Null_unspecified) Ident__Null_unspecified = PP.getIdentifierInfo("_Null_unspecified"); @@ -3915,6 +3921,7 @@ static bool hasNullabilityAttr(const ParsedAttributesView &attrs) { for (const ParsedAttr &AL : attrs) { if (AL.getKind() == ParsedAttr::AT_TypeNonNull || AL.getKind() == ParsedAttr::AT_TypeNullable || + AL.getKind() == ParsedAttr::AT_TypeNullableResult || AL.getKind() == ParsedAttr::AT_TypeNullUnspecified) return true; } @@ -4333,6 +4340,9 @@ static Attr *createNullabilityAttr(ASTContext &Ctx, ParsedAttr &Attr, case NullabilityKind::Nullable: return createSimpleAttr<TypeNullableAttr>(Ctx, Attr); + case NullabilityKind::NullableResult: + return createSimpleAttr<TypeNullableResultAttr>(Ctx, Attr); + case NullabilityKind::Unspecified: return createSimpleAttr<TypeNullUnspecifiedAttr>(Ctx, Attr); } @@ -7008,6 +7018,9 @@ static NullabilityKind mapNullabilityAttrKind(ParsedAttr::Kind kind) { case ParsedAttr::AT_TypeNullable: return NullabilityKind::Nullable; + case ParsedAttr::AT_TypeNullableResult: + return NullabilityKind::NullableResult; + case ParsedAttr::AT_TypeNullUnspecified: return NullabilityKind::Unspecified; |