From 3df3b62018c0015b0786b124827c276e8ee57117 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Wed, 11 Nov 2020 08:49:58 -0800 Subject: [PATCH] [clang] ns_error_domain attribute also supports CFString typed variables Differential Revision: https://reviews.llvm.org/D90891 --- clang/include/clang/Basic/AttrDocs.td | 7 ++++--- .../include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaDeclAttr.cpp | 3 ++- clang/test/Sema/ns_error_enum.m | 17 ++++++++++++++++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index a2f7b7a5bc1f8..085d2bac1dea8 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3594,9 +3594,10 @@ def NSErrorDomainDocs : Documentation { In Cocoa frameworks in Objective-C, one can group related error codes in enums and categorize these enums with error domains. -The ``ns_error_domain`` attribute indicates a global ``NSString`` constant -representing the error domain that an error code belongs to. For pointer -uniqueness and code size this is a constant symbol, not a literal. +The ``ns_error_domain`` attribute indicates a global ``NSString`` or +``CFString`` constant representing the error domain that an error code belongs +to. For pointer uniqueness and code size this is a constant symbol, not a +literal. The domain and error code need to be used together. The ``ns_error_domain`` attribute links error codes to their domain at the source level. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 63475811b117b..554d5943a63a9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9597,7 +9597,7 @@ def err_nsreturns_retained_attribute_mismatch : Error< def err_nserrordomain_invalid_decl : Error< "domain argument %select{|%1 }0does not refer to global constant">; def err_nserrordomain_wrong_type : Error< - "domain argument %0 does not point to an NSString constant">; + "domain argument %0 does not point to an NSString or CFString constant">; def warn_nsconsumed_attribute_mismatch : Warning< err_nsconsumed_attribute_mismatch.Text>, InGroup; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ec3ea9ebd85e0..a2df339151fb4 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5436,7 +5436,8 @@ static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &AL) { return; } - if (!isNSStringType(VD->getType(), S.Context)) { + if (!isNSStringType(VD->getType(), S.Context) && + !isCFStringType(VD->getType(), S.Context)) { S.Diag(Loc, diag::err_nserrordomain_wrong_type) << VD; return; } diff --git a/clang/test/Sema/ns_error_enum.m b/clang/test/Sema/ns_error_enum.m index c8323d903d150..895f9b8b3356a 100644 --- a/clang/test/Sema/ns_error_enum.m +++ b/clang/test/Sema/ns_error_enum.m @@ -36,9 +36,24 @@ typedef NS_ERROR_ENUM(unsigned char, MyTypedefErrorEnum, MyTypedefErrorDomain) { MyTypedefErrSecond, }; +typedef const struct __CFString * CFStringRef; + +extern CFStringRef const MyCFErrorDomain; +typedef NS_ERROR_ENUM(unsigned char, MyCFErrorEnum, MyCFErrorDomain) { + MyCFErrFirst, + MyCFErrSecond, +}; + +typedef CFStringRef CFErrorDomain; +extern CFErrorDomain const MyCFTypedefErrorDomain; +typedef NS_ERROR_ENUM(unsigned char, MyCFTypedefErrorEnum, MyCFTypedefErrorDomain) { + MyCFTypedefErrFirst, + MyCFTypedefErrSecond, +}; + extern char *const WrongErrorDomainType; enum __attribute__((ns_error_domain(WrongErrorDomainType))) MyWrongErrorDomainType { MyWrongErrorDomain }; -// expected-error@-1{{domain argument 'WrongErrorDomainType' does not point to an NSString constant}} +// expected-error@-1{{domain argument 'WrongErrorDomainType' does not point to an NSString or CFString constant}} struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructWithErrorDomain {}; // expected-error@-1{{'ns_error_domain' attribute only applies to enums}}