diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 4 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 30 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/Inputs/literal-support.h | 8 | ||||
-rw-r--r-- | clang/test/CodeGenObjCXX/Inputs/literal-support.h | 8 | ||||
-rw-r--r-- | clang/test/SemaObjC/arc.m | 6 | ||||
-rw-r--r-- | clang/test/SemaObjC/objc-literal-comparison.m | 1 |
8 files changed, 51 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e4cdbd4880e..800e591b446 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2007,6 +2007,8 @@ def err_undeclared_nsarray : Error< def err_undeclared_nsdictionary : Error< "NSDictionary must be available to use Objective-C dictionary " "literals">; +def err_undeclared_alloc : Error< + "alloc must be available to use Objective-C literals">; def err_undeclared_boxing_method : Error< "declaration of %0 is missing in %1 class">; def err_objc_literal_method_sig : Error< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 3880cb57736..87453a25b4f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -685,8 +685,8 @@ public: /// \brief The declaration of the initWithObjects:forKeys:count: method. ObjCMethodDecl *InitDictionaryWithObjectsMethod; - /// \brief The declaration for + (id) alloc method. - ObjCMethodDecl *AllocObjectsMethod; + /// \brief The declaration for + (id) alloc method used in [NSDictionary alloc] + ObjCMethodDecl *DictAllocObjectsMethod; /// \brief id<NSCopying> type. QualType QIDNSCopying; diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 7fb5eba1c2d..4ed5aa8a287 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -98,7 +98,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, InitArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr), InitDictionaryWithObjectsMethod(nullptr), - AllocObjectsMethod(nullptr), + DictAllocObjectsMethod(nullptr), GlobalNewDeleteDeclared(false), TUKind(TUKind), NumSFINAEErrors(0), diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 4a844c59d29..b4d3d4de363 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -746,6 +746,7 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) { ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, ObjCDictionaryElement *Elements, unsigned NumElements) { + bool Arc = getLangOpts().ObjCAutoRefCount; // Look up the NSDictionary class, if we haven't done so already. if (!NSDictionaryDecl) { NamedDecl *IF = LookupSingleName(TUScope, @@ -765,9 +766,34 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, } } + QualType IdT = Context.getObjCIdType(); + if (Arc && !DictAllocObjectsMethod) { + // Find +[NSDictionary alloc] method. + IdentifierInfo *II = &Context.Idents.get("alloc"); + Selector AllocSel = Context.Selectors.getSelector(0, &II); + DictAllocObjectsMethod = NSDictionaryDecl->lookupClassMethod(AllocSel); + if (!DictAllocObjectsMethod && getLangOpts().DebuggerObjCLiteral) { + DictAllocObjectsMethod = ObjCMethodDecl::Create(Context, + SourceLocation(), SourceLocation(), AllocSel, + IdT, + nullptr /*TypeSourceInfo */, + Context.getTranslationUnitDecl(), + false /*Instance*/, false/*isVariadic*/, + /*isPropertyAccessor=*/false, + /*isImplicitlyDeclared=*/true, /*isDefined=*/false, + ObjCMethodDecl::Required, + false); + SmallVector<ParmVarDecl *, 1> Params; + DictAllocObjectsMethod->setMethodParams(Context, Params, None); + } + if (!DictAllocObjectsMethod) { + Diag(SR.getBegin(), diag::err_undeclared_alloc); + return ExprError(); + } + } + // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done // so already. - QualType IdT = Context.getObjCIdType(); if (!DictionaryWithObjectsMethod) { Selector Sel = NSAPIObj->getNSDictionarySelector( NSAPI::NSDict_dictionaryWithObjectsForKeysCount); @@ -925,7 +951,7 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, Context.getObjCInterfaceType(NSDictionaryDecl)); return MaybeBindToTemporary(ObjCDictionaryLiteral::Create( Context, makeArrayRef(Elements, NumElements), HasPackExpansions, Ty, - DictionaryWithObjectsMethod, nullptr, SR)); + DictionaryWithObjectsMethod, DictAllocObjectsMethod, SR)); } ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc, diff --git a/clang/test/CodeGenObjC/Inputs/literal-support.h b/clang/test/CodeGenObjC/Inputs/literal-support.h index 5680a20c9fb..fc80d88b13d 100644 --- a/clang/test/CodeGenObjC/Inputs/literal-support.h +++ b/clang/test/CodeGenObjC/Inputs/literal-support.h @@ -3,6 +3,10 @@ typedef unsigned char BOOL; +@interface NSObject ++ (id)alloc; +@end + @interface NSNumber @end @interface NSNumber (NSNumberCreation) @@ -21,14 +25,14 @@ typedef unsigned char BOOL; + (NSNumber *)numberWithBool:(BOOL)value; @end -@interface NSArray +@interface NSArray : NSObject @end @interface NSArray (NSArrayCreation) + (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; @end -@interface NSDictionary +@interface NSDictionary : NSObject + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; @end diff --git a/clang/test/CodeGenObjCXX/Inputs/literal-support.h b/clang/test/CodeGenObjCXX/Inputs/literal-support.h index 5680a20c9fb..fc80d88b13d 100644 --- a/clang/test/CodeGenObjCXX/Inputs/literal-support.h +++ b/clang/test/CodeGenObjCXX/Inputs/literal-support.h @@ -3,6 +3,10 @@ typedef unsigned char BOOL; +@interface NSObject ++ (id)alloc; +@end + @interface NSNumber @end @interface NSNumber (NSNumberCreation) @@ -21,14 +25,14 @@ typedef unsigned char BOOL; + (NSNumber *)numberWithBool:(BOOL)value; @end -@interface NSArray +@interface NSArray : NSObject @end @interface NSArray (NSArrayCreation) + (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; @end -@interface NSDictionary +@interface NSDictionary : NSObject + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; @end diff --git a/clang/test/SemaObjC/arc.m b/clang/test/SemaObjC/arc.m index ba7c09f4f9d..c162d7fdf71 100644 --- a/clang/test/SemaObjC/arc.m +++ b/clang/test/SemaObjC/arc.m @@ -5,7 +5,11 @@ typedef const void * CFTypeRef; CFTypeRef CFBridgingRetain(id X); id CFBridgingRelease(CFTypeRef); @protocol NSCopying @end -@interface NSDictionary +@interface NSObject ++ (id)alloc; +@end + +@interface NSDictionary : NSObject + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; - (void)setObject:(id)object forKeyedSubscript:(id)key; @end diff --git a/clang/test/SemaObjC/objc-literal-comparison.m b/clang/test/SemaObjC/objc-literal-comparison.m index 95ebfb397b0..68ac419ea29 100644 --- a/clang/test/SemaObjC/objc-literal-comparison.m +++ b/clang/test/SemaObjC/objc-literal-comparison.m @@ -16,6 +16,7 @@ typedef signed char BOOL; @interface NSObject : BaseObject - (BOOL)isEqual:(id)other; ++ (id)alloc; @end @interface NSNumber : NSObject |