Author: Alex Lorenz
Date: 2021-03-09T13:36:57-08:00
New Revision: 2de0a18a8949f0235fb3a08dcc55ff3aa7d969e7

URL: 
https://github.com/llvm/llvm-project/commit/2de0a18a8949f0235fb3a08dcc55ff3aa7d969e7
DIFF: 
https://github.com/llvm/llvm-project/commit/2de0a18a8949f0235fb3a08dcc55ff3aa7d969e7.diff

LOG: [clang][ObjC] allow the use of NSAttributedString * return type with 
format_arg attribute

This is useful for APIs that want to produce an attributed NSString as a result 
of
some formatting API call.

Added: 
    

Modified: 
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/SemaObjC/format-arg-attribute.m

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 5b9acda6738e..c309f0436437 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -154,7 +154,8 @@ static bool isInstanceMethod(const Decl *D) {
   return false;
 }
 
-static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
+static inline bool isNSStringType(QualType T, ASTContext &Ctx,
+                                  bool AllowNSAttributedString = false) {
   const auto *PT = T->getAs<ObjCObjectPointerType>();
   if (!PT)
     return false;
@@ -165,6 +166,9 @@ static inline bool isNSStringType(QualType T, ASTContext 
&Ctx) {
 
   IdentifierInfo* ClsName = Cls->getIdentifier();
 
+  if (AllowNSAttributedString &&
+      ClsName == &Ctx.Idents.get("NSAttributedString"))
+    return true;
   // FIXME: Should we walk the chain of classes?
   return ClsName == &Ctx.Idents.get("NSString") ||
          ClsName == &Ctx.Idents.get("NSMutableString");
@@ -3286,7 +3290,7 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const 
ParsedAttr &AL) {
     return;
   }
   Ty = getFunctionOrMethodResultType(D);
-  if (!isNSStringType(Ty, S.Context) &&
+  if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true) &&
       !isCFStringType(Ty, S.Context) &&
       (!Ty->isPointerType() ||
        !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {

diff  --git a/clang/test/SemaObjC/format-arg-attribute.m 
b/clang/test/SemaObjC/format-arg-attribute.m
index 67c9c2e3d4c9..ac81bdc21dc1 100644
--- a/clang/test/SemaObjC/format-arg-attribute.m
+++ b/clang/test/SemaObjC/format-arg-attribute.m
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -verify -fsyntax-only %s
 
 @class NSString;
+@class NSAttributedString;
 
 extern NSString *fa2 (const NSString *) __attribute__((format_arg(1)));
 extern NSString *fa3 (NSString *) __attribute__((format_arg(1)));
@@ -25,3 +26,5 @@
 extern int fi3 (const NSString *) __attribute__((format_arg(1)));  // 
expected-error {{function does not return NSString}}
 extern NSString *fi4 (const NSString *) __attribute__((format_arg(1))); 
 extern NSString *fi5 (const NSString *) __attribute__((format_arg(1))); 
+
+extern NSAttributedString *fattrs (const NSString *) 
__attribute__((format_arg(1)));


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to